android/guava/src/com/google/common/reflect/TypeResolver.java
public TypeResolver where(Type formal, Type actual) {
    Map<TypeVariableKey, Type> mappings = Maps.newHashMap();
    populateTypeMappings(mappings, checkNotNull(formal), checkNotNull(actual));
    return where(mappings);
  }
public TypeResolver where(Type formal, Type actual) {
    Map<TypeVariableKey, Type> mappings = Maps.newHashMap();
    populateTypeMappings(mappings, checkNotNull(formal), checkNotNull(actual));
    return where(mappings);
  }
Returns a new {@code TypeResolver} with type variables in {@code formal} mapping to types in
{@code actual}.

<p>For example, if {@code formal} is a {@code TypeVariable T}, and {@code actual} is {@code
String.class}, then {@code new TypeResolver().where(formal, actual)} will {@linkplain
#resolveType resolve} {@code ParameterizedType List<T>} to {@code List<String>}, and resolve
{@code Map<T, Something>} to {@code Map<String, Something>} etc. Similarly, {@code formal} and
{@code actual} can be {@code Map<K, V>} and {@code Map<String, Integer>} respectively, or they
can be {@code E[]} and {@code String[]} respectively, or even any arbitrary combination
thereof.

@param formal The type whose type variables or itself is mapped to other type(s). It's almost
always a bug if {@code formal} isn't a type variable and contains no type variable. Make
sure you are passing the two parameters in the right order.
@param actual The type that the formal type variable(s) are mapped to. It can be or contain yet
other type variables, in which case these type variables will be further resolved if
corresponding mappings exist in the current {@code TypeResolver} instance.