anchor.diff:  
   == Advanced Topics
   
  +=== Working with Generic Types
  +
  +Jdbi provides utility classes to make it easier to work with Java generic types.
  +
  +==== GenericType
  +
  +link:{jdbidocs}/core/generic/GenericType.html[GenericType^] represents a generic
  +type signature that can be passed around in a type-safe way.
  +
  +Create a generic type reference by instantiating an anonymous inner class:
  +
  +[source,java]
  +----
  +new GenericType<Optional<String>>() {}
  +----
  +
  +This type reference can be passed to any Jdbi method that accepts a
  +`GenericType<T>`, e.g.:
  +
  +[source,java]
  +----
  +List<Optional<String>> middleNames = handle
  +    .select("select middle_name from contacts")
  +    .mapTo(new GenericType<Optional<String>>() {})
  +    .list();
  +----
  +
  +The `GenericType.getType()` returns the raw
  +link:{jdkdocs}/java/lang/reflect/Type.html[java.lang.reflect.Type^] object used
  +to represent generics in Java.
  +
  +==== GenericTypes
  +
  +link:{jdbidocs}/core/generic/GenericTypes.html[GenericTypes^] provides methods
  +for working with Java generic types signatures.
  +
  +All methods in `GenericTypes` operate in terms of `java.lang.reflect.Type`.
  +
  +The `getErasedType(Type)` method accepts a `Type` and returns the raw `Class`
  +for that type, with any generic parameters erased:
  +
  +[source,java]
  +----
  +Type listOfInteger = new GenericType<List<Integer>>() {}.getType();
  +GenericTypes.getErasedType(listOfInteger); // => List.class
  +
  +GenericTypes.getErasedType(String.class); // => String.class
  +----
  +
  +The `resolveType(Type, Type)` method takes a generic type, and a context type in
  +which to resolve it.
  +
  +For example, given the type variable `T` from `Optional<T>`:
  +
  +[source,java]
  +----
  +Type t = Optional.class.getTypeParameters()[0];
  +----
  +
  +And given the context type `Optional<String>`:
  +
  +[source,java]
  +----
  +Type optionalOfString = new GenericType<Optional<String>>() {}.getType();
  +----
  +
  +The `resolveType()` method answers the question: "what is type T, in the context
  +of type Optional<String>?"
  +
  +[source,java]
  +----
  +GenericTypes.resolveType(t, optionalOfString);
  +// => String.class
  +----
  +
  +This scenario of resolving the first type parameter of some generic supertype is
  +so common that we made a separate method for it:
  +
  +[source,java]
  +----
  +GenericTypes.findGenericParameter(optionalOfString, Optional.class);
  +// => Optional.of(String.class)
  +
  +Type listOfInteger = new GenericType<List<Integer>>() {}.getType();
  +GenericTypes.findGenericParameter(listOfInteger, Collection.class);
  +// => Optional.of(Integer.class)
  +----
  +
  +Note that this method will return `Optional.empty()` if the type parameter
  +cannot be resolved, or the types have nothing to do with each other:
  +
  +[source,java]
  +----
  +GenericTypes.findGenericParameter(optionalOfString, List.class);
  +// => Optional.empty();
  +----
  +
   === NamedArgumentFinder
   
   The link:{jdbidocs}/core/argument/NamedArgumentFinder[NamedArgumentFinder^]
  
positive.code: 
      Type t = GenericTypes.resolveType(Optional.class.getTypeParameters()[0], type);
  
      ColumnMapper<?> embeddedMapper = config.get(ColumnMappers.class)
          .findFor(t)
          .orElseThrow(() -> new NoSuchMapperException(
              "No column mapper registered for parameter " + t + " of type " + type));
  
      ColumnMapper<?> optionalMapper = (rs, col, ctx) ->
          Optional.ofNullable(embeddedMapper.map(rs, col, ctx));
  
      return Optional.of(optionalMapper);
    }
  
negative.code: }
  ----
  
  [TIP]
  The `GenericTypes` utility class is discussed in <<Working with Generic Types>>.
  
  Next, extract the `T` generic parameter from the mapped type:
  
  [source,java]
  ----
  Type t = GenericTypes.resolveType(Optional.class.getTypeParameters()[0], type);
  ----
  
  The expression `Optional.class.getTypeParameters()[0]` gives the type variable
  `T`.
  
  We use `resolveType()` to resolve the type of `T` in the context of the mapped
  type.
  
  Now that we have the type of `T`, we can look up a column mapper for that type
  from the `ColumnMappers` config class, through the config registry:
  
  [source,java]
  ----
  ColumnMapper<?> tMapper = config.get(ColumnMappers.class)
      .findFor(embeddedType)
      .orElseThrow(() -> new NoSuchMapperException(
          "No column mapper registered for parameter " + embeddedType + " of type " + type));
  