17dd252788645e940eada959bdde927426e2531c9Paul Duffin/*
27dd252788645e940eada959bdde927426e2531c9Paul Duffin * Copyright (C) 2006 The Guava Authors
37dd252788645e940eada959bdde927426e2531c9Paul Duffin *
47dd252788645e940eada959bdde927426e2531c9Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License");
57dd252788645e940eada959bdde927426e2531c9Paul Duffin * you may not use this file except in compliance with the License.
67dd252788645e940eada959bdde927426e2531c9Paul Duffin * You may obtain a copy of the License at
77dd252788645e940eada959bdde927426e2531c9Paul Duffin *
87dd252788645e940eada959bdde927426e2531c9Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0
97dd252788645e940eada959bdde927426e2531c9Paul Duffin *
107dd252788645e940eada959bdde927426e2531c9Paul Duffin * Unless required by applicable law or agreed to in writing, software
117dd252788645e940eada959bdde927426e2531c9Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS,
127dd252788645e940eada959bdde927426e2531c9Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137dd252788645e940eada959bdde927426e2531c9Paul Duffin * See the License for the specific language governing permissions and
147dd252788645e940eada959bdde927426e2531c9Paul Duffin * limitations under the License.
157dd252788645e940eada959bdde927426e2531c9Paul Duffin */
167dd252788645e940eada959bdde927426e2531c9Paul Duffin
177dd252788645e940eada959bdde927426e2531c9Paul Duffinpackage com.google.common.reflect;
187dd252788645e940eada959bdde927426e2531c9Paul Duffin
197dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.base.Preconditions.checkArgument;
207dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.base.Preconditions.checkNotNull;
217dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.base.Preconditions.checkState;
227dd252788645e940eada959bdde927426e2531c9Paul Duffin
237dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.Beta;
247dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.annotations.VisibleForTesting;
250888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.base.Joiner;
267dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Predicate;
277dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.FluentIterable;
287dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.ForwardingSet;
297dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.ImmutableList;
307dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.ImmutableMap;
317dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.ImmutableSet;
327dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.Maps;
337dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.Ordering;
340888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.primitives.Primitives;
357dd252788645e940eada959bdde927426e2531c9Paul Duffin
367dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.io.Serializable;
377dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.Constructor;
387dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.GenericArrayType;
397dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.Method;
407dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.ParameterizedType;
417dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.Type;
427dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.TypeVariable;
437dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.lang.reflect.WildcardType;
440888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Arrays;
457dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Comparator;
467dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Map;
477dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Set;
487dd252788645e940eada959bdde927426e2531c9Paul Duffin
497dd252788645e940eada959bdde927426e2531c9Paul Duffinimport javax.annotation.Nullable;
507dd252788645e940eada959bdde927426e2531c9Paul Duffin
517dd252788645e940eada959bdde927426e2531c9Paul Duffin/**
527dd252788645e940eada959bdde927426e2531c9Paul Duffin * A {@link Type} with generics.
537dd252788645e940eada959bdde927426e2531c9Paul Duffin *
547dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>Operations that are otherwise only available in {@link Class} are implemented to support
557dd252788645e940eada959bdde927426e2531c9Paul Duffin * {@code Type}, for example {@link #isAssignableFrom}, {@link #isArray} and {@link
567dd252788645e940eada959bdde927426e2531c9Paul Duffin * #getComponentType}. It also provides additional utilities such as {@link #getTypes} and {@link
577dd252788645e940eada959bdde927426e2531c9Paul Duffin * #resolveType} etc.
587dd252788645e940eada959bdde927426e2531c9Paul Duffin *
597dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>There are three ways to get a {@code TypeToken} instance: <ul>
607dd252788645e940eada959bdde927426e2531c9Paul Duffin * <li>Wrap a {@code Type} obtained via reflection. For example: {@code
617dd252788645e940eada959bdde927426e2531c9Paul Duffin * TypeToken.of(method.getGenericReturnType())}.
627dd252788645e940eada959bdde927426e2531c9Paul Duffin * <li>Capture a generic type with a (usually anonymous) subclass. For example: <pre>   {@code
630888a09821a98ac0680fad765217302858e70fa4Paul Duffin *   new TypeToken<List<String>>() {}}</pre>
640888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>Note that it's critical that the actual type argument is carried by a subclass.
657dd252788645e940eada959bdde927426e2531c9Paul Duffin * The following code is wrong because it only captures the {@code <T>} type variable
667dd252788645e940eada959bdde927426e2531c9Paul Duffin * of the {@code listType()} method signature; while {@code <String>} is lost in erasure:
677dd252788645e940eada959bdde927426e2531c9Paul Duffin * <pre>   {@code
687dd252788645e940eada959bdde927426e2531c9Paul Duffin *   class Util {
697dd252788645e940eada959bdde927426e2531c9Paul Duffin *     static <T> TypeToken<List<T>> listType() {
707dd252788645e940eada959bdde927426e2531c9Paul Duffin *       return new TypeToken<List<T>>() {};
717dd252788645e940eada959bdde927426e2531c9Paul Duffin *     }
727dd252788645e940eada959bdde927426e2531c9Paul Duffin *   }
737dd252788645e940eada959bdde927426e2531c9Paul Duffin *
740888a09821a98ac0680fad765217302858e70fa4Paul Duffin *   TypeToken<List<String>> stringListType = Util.<String>listType();}</pre>
757dd252788645e940eada959bdde927426e2531c9Paul Duffin * <li>Capture a generic type with a (usually anonymous) subclass and resolve it against
767dd252788645e940eada959bdde927426e2531c9Paul Duffin * a context class that knows what the type parameters are. For example: <pre>   {@code
777dd252788645e940eada959bdde927426e2531c9Paul Duffin *   abstract class IKnowMyType<T> {
787dd252788645e940eada959bdde927426e2531c9Paul Duffin *     TypeToken<T> type = new TypeToken<T>(getClass()) {};
797dd252788645e940eada959bdde927426e2531c9Paul Duffin *   }
800888a09821a98ac0680fad765217302858e70fa4Paul Duffin *   new IKnowMyType<String>() {}.type => String}</pre>
817dd252788645e940eada959bdde927426e2531c9Paul Duffin * </ul>
827dd252788645e940eada959bdde927426e2531c9Paul Duffin *
837dd252788645e940eada959bdde927426e2531c9Paul Duffin * <p>{@code TypeToken} is serializable when no type variable is contained in the type.
847dd252788645e940eada959bdde927426e2531c9Paul Duffin *
850888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>Note to Guice users: {@code} TypeToken is similar to Guice's {@code TypeLiteral} class
860888a09821a98ac0680fad765217302858e70fa4Paul Duffin * except that it is serializable and offers numerous additional utility methods.
877dd252788645e940eada959bdde927426e2531c9Paul Duffin *
887dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author Bob Lee
897dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author Sven Mawson
907dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author Ben Yu
917dd252788645e940eada959bdde927426e2531c9Paul Duffin * @since 12.0
927dd252788645e940eada959bdde927426e2531c9Paul Duffin */
937dd252788645e940eada959bdde927426e2531c9Paul Duffin@Beta
940888a09821a98ac0680fad765217302858e70fa4Paul Duffin@SuppressWarnings("serial") // SimpleTypeToken is the serialized form.
957dd252788645e940eada959bdde927426e2531c9Paul Duffinpublic abstract class TypeToken<T> extends TypeCapture<T> implements Serializable {
967dd252788645e940eada959bdde927426e2531c9Paul Duffin
977dd252788645e940eada959bdde927426e2531c9Paul Duffin  private final Type runtimeType;
987dd252788645e940eada959bdde927426e2531c9Paul Duffin
997dd252788645e940eada959bdde927426e2531c9Paul Duffin  /** Resolver for resolving types with {@link #runtimeType} as context. */
1007dd252788645e940eada959bdde927426e2531c9Paul Duffin  private transient TypeResolver typeResolver;
1017dd252788645e940eada959bdde927426e2531c9Paul Duffin
1027dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
1037dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Constructs a new type token of {@code T}.
1047dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
1057dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <p>Clients create an empty anonymous subclass. Doing so embeds the type
1067dd252788645e940eada959bdde927426e2531c9Paul Duffin   * parameter in the anonymous class's type hierarchy so we can reconstitute
1077dd252788645e940eada959bdde927426e2531c9Paul Duffin   * it at runtime despite erasure.
1087dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
1097dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <p>For example: <pre>   {@code
1100888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *   TypeToken<List<String>> t = new TypeToken<List<String>>() {};}</pre>
1117dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
1127dd252788645e940eada959bdde927426e2531c9Paul Duffin  protected TypeToken() {
1137dd252788645e940eada959bdde927426e2531c9Paul Duffin    this.runtimeType = capture();
1147dd252788645e940eada959bdde927426e2531c9Paul Duffin    checkState(!(runtimeType instanceof TypeVariable),
1150888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "Cannot construct a TypeToken for a type variable.\n" +
1160888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "You probably meant to call new TypeToken<%s>(getClass()) " +
1170888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "that can resolve the type variable for you.\n" +
1180888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "If you do need to create a TypeToken of a type variable, " +
1190888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "please use TypeToken.of() instead.", runtimeType);
1207dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1217dd252788645e940eada959bdde927426e2531c9Paul Duffin
1227dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
1237dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Constructs a new type token of {@code T} while resolving free type variables in the context of
1247dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code declaringClass}.
1257dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
1267dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <p>Clients create an empty anonymous subclass. Doing so embeds the type
1277dd252788645e940eada959bdde927426e2531c9Paul Duffin   * parameter in the anonymous class's type hierarchy so we can reconstitute
1287dd252788645e940eada959bdde927426e2531c9Paul Duffin   * it at runtime despite erasure.
1297dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
1307dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <p>For example: <pre>   {@code
1317dd252788645e940eada959bdde927426e2531c9Paul Duffin   *   abstract class IKnowMyType<T> {
1327dd252788645e940eada959bdde927426e2531c9Paul Duffin   *     TypeToken<T> getMyType() {
1337dd252788645e940eada959bdde927426e2531c9Paul Duffin   *       return new TypeToken<T>(getClass()) {};
1347dd252788645e940eada959bdde927426e2531c9Paul Duffin   *     }
1357dd252788645e940eada959bdde927426e2531c9Paul Duffin   *   }
1367dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
1370888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *   new IKnowMyType<String>() {}.getMyType() => String}</pre>
1387dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
1397dd252788645e940eada959bdde927426e2531c9Paul Duffin  protected TypeToken(Class<?> declaringClass) {
1407dd252788645e940eada959bdde927426e2531c9Paul Duffin    Type captured = super.capture();
1417dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (captured instanceof Class) {
1427dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.runtimeType = captured;
1437dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else {
1447dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.runtimeType = of(declaringClass).resolveType(captured).runtimeType;
1457dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1467dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1477dd252788645e940eada959bdde927426e2531c9Paul Duffin
1487dd252788645e940eada959bdde927426e2531c9Paul Duffin  private TypeToken(Type type) {
1497dd252788645e940eada959bdde927426e2531c9Paul Duffin    this.runtimeType = checkNotNull(type);
1507dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1517dd252788645e940eada959bdde927426e2531c9Paul Duffin
1527dd252788645e940eada959bdde927426e2531c9Paul Duffin  /** Returns an instance of type token that wraps {@code type}. */
1537dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static <T> TypeToken<T> of(Class<T> type) {
1547dd252788645e940eada959bdde927426e2531c9Paul Duffin    return new SimpleTypeToken<T>(type);
1557dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1567dd252788645e940eada959bdde927426e2531c9Paul Duffin
1577dd252788645e940eada959bdde927426e2531c9Paul Duffin  /** Returns an instance of type token that wraps {@code type}. */
1587dd252788645e940eada959bdde927426e2531c9Paul Duffin  public static TypeToken<?> of(Type type) {
1597dd252788645e940eada959bdde927426e2531c9Paul Duffin    return new SimpleTypeToken<Object>(type);
1607dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1617dd252788645e940eada959bdde927426e2531c9Paul Duffin
1627dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
1637dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns the raw type of {@code T}. Formally speaking, if {@code T} is returned by
1647dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@link java.lang.reflect.Method#getGenericReturnType}, the raw type is what's returned by
1657dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@link java.lang.reflect.Method#getReturnType} of the same method object. Specifically:
1667dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <ul>
1677dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <li>If {@code T} is a {@code Class} itself, {@code T} itself is returned.
1687dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <li>If {@code T} is a {@link ParameterizedType}, the raw type of the parameterized type is
1697dd252788645e940eada959bdde927426e2531c9Paul Duffin   *     returned.
1707dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <li>If {@code T} is a {@link GenericArrayType}, the returned type is the corresponding array
1717dd252788645e940eada959bdde927426e2531c9Paul Duffin   *     class. For example: {@code List<Integer>[] => List[]}.
1727dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <li>If {@code T} is a type variable or a wildcard type, the raw type of the first upper bound
1737dd252788645e940eada959bdde927426e2531c9Paul Duffin   *     is returned. For example: {@code <X extends Foo> => Foo}.
1747dd252788645e940eada959bdde927426e2531c9Paul Duffin   * </ul>
1757dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
1767dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final Class<? super T> getRawType() {
1777dd252788645e940eada959bdde927426e2531c9Paul Duffin    Class<?> rawType = getRawType(runtimeType);
1780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @SuppressWarnings("unchecked") // raw type is |T|
1797dd252788645e940eada959bdde927426e2531c9Paul Duffin    Class<? super T> result = (Class<? super T>) rawType;
1807dd252788645e940eada959bdde927426e2531c9Paul Duffin    return result;
1817dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1827dd252788645e940eada959bdde927426e2531c9Paul Duffin
1837dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
1847dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns the raw type of the class or parameterized type; if {@code T} is type variable or
1857dd252788645e940eada959bdde927426e2531c9Paul Duffin   * wildcard type, the raw types of all its upper bounds are returned.
1867dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
1877dd252788645e940eada959bdde927426e2531c9Paul Duffin  private ImmutableSet<Class<? super T>> getImmediateRawTypes() {
1887dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Cast from ImmutableSet<Class<?>> to ImmutableSet<Class<? super T>>
1890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @SuppressWarnings({"unchecked", "rawtypes"})
1907dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableSet<Class<? super T>> result = (ImmutableSet) getRawTypes(runtimeType);
1917dd252788645e940eada959bdde927426e2531c9Paul Duffin    return result;
1927dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1937dd252788645e940eada959bdde927426e2531c9Paul Duffin
1947dd252788645e940eada959bdde927426e2531c9Paul Duffin  /** Returns the represented type. */
1957dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final Type getType() {
1967dd252788645e940eada959bdde927426e2531c9Paul Duffin    return runtimeType;
1977dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1987dd252788645e940eada959bdde927426e2531c9Paul Duffin
1997dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
2000888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * <p>Returns a new {@code TypeToken} where type variables represented by {@code typeParam}
2017dd252788645e940eada959bdde927426e2531c9Paul Duffin   * are substituted by {@code typeArg}. For example, it can be used to construct
2027dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code Map<K, V>} for any {@code K} and {@code V} type: <pre>   {@code
2037dd252788645e940eada959bdde927426e2531c9Paul Duffin   *   static <K, V> TypeToken<Map<K, V>> mapOf(
2047dd252788645e940eada959bdde927426e2531c9Paul Duffin   *       TypeToken<K> keyType, TypeToken<V> valueType) {
2057dd252788645e940eada959bdde927426e2531c9Paul Duffin   *     return new TypeToken<Map<K, V>>() {}
2067dd252788645e940eada959bdde927426e2531c9Paul Duffin   *         .where(new TypeParameter<K>() {}, keyType)
2077dd252788645e940eada959bdde927426e2531c9Paul Duffin   *         .where(new TypeParameter<V>() {}, valueType);
2080888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *   }}</pre>
2097dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
2107dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @param <X> The parameter type
2117dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @param typeParam the parameter type variable
2127dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @param typeArg the actual type to substitute
2137dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
2147dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final <X> TypeToken<T> where(TypeParameter<X> typeParam, TypeToken<X> typeArg) {
2150888a09821a98ac0680fad765217302858e70fa4Paul Duffin    TypeResolver resolver = new TypeResolver()
2160888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .where(ImmutableMap.of(
2170888a09821a98ac0680fad765217302858e70fa4Paul Duffin            new TypeResolver.TypeVariableKey(typeParam.typeVariable),
2180888a09821a98ac0680fad765217302858e70fa4Paul Duffin            typeArg.runtimeType));
2197dd252788645e940eada959bdde927426e2531c9Paul Duffin    // If there's any type error, we'd report now rather than later.
2207dd252788645e940eada959bdde927426e2531c9Paul Duffin    return new SimpleTypeToken<T>(resolver.resolveType(runtimeType));
2217dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2227dd252788645e940eada959bdde927426e2531c9Paul Duffin
2237dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
2240888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * <p>Returns a new {@code TypeToken} where type variables represented by {@code typeParam}
2257dd252788645e940eada959bdde927426e2531c9Paul Duffin   * are substituted by {@code typeArg}. For example, it can be used to construct
2267dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code Map<K, V>} for any {@code K} and {@code V} type: <pre>   {@code
2277dd252788645e940eada959bdde927426e2531c9Paul Duffin   *   static <K, V> TypeToken<Map<K, V>> mapOf(
2287dd252788645e940eada959bdde927426e2531c9Paul Duffin   *       Class<K> keyType, Class<V> valueType) {
2297dd252788645e940eada959bdde927426e2531c9Paul Duffin   *     return new TypeToken<Map<K, V>>() {}
2307dd252788645e940eada959bdde927426e2531c9Paul Duffin   *         .where(new TypeParameter<K>() {}, keyType)
2317dd252788645e940eada959bdde927426e2531c9Paul Duffin   *         .where(new TypeParameter<V>() {}, valueType);
2320888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *   }}</pre>
2337dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
2347dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @param <X> The parameter type
2357dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @param typeParam the parameter type variable
2367dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @param typeArg the actual type to substitute
2377dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
2387dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final <X> TypeToken<T> where(TypeParameter<X> typeParam, Class<X> typeArg) {
2397dd252788645e940eada959bdde927426e2531c9Paul Duffin    return where(typeParam, of(typeArg));
2407dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2417dd252788645e940eada959bdde927426e2531c9Paul Duffin
2427dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
2430888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * <p>Resolves the given {@code type} against the type context represented by this type.
2447dd252788645e940eada959bdde927426e2531c9Paul Duffin   * For example: <pre>   {@code
2457dd252788645e940eada959bdde927426e2531c9Paul Duffin   *   new TypeToken<List<String>>() {}.resolveType(
2467dd252788645e940eada959bdde927426e2531c9Paul Duffin   *       List.class.getMethod("get", int.class).getGenericReturnType())
2470888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *   => String.class}</pre>
2487dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
2497dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final TypeToken<?> resolveType(Type type) {
2507dd252788645e940eada959bdde927426e2531c9Paul Duffin    checkNotNull(type);
2517dd252788645e940eada959bdde927426e2531c9Paul Duffin    TypeResolver resolver = typeResolver;
2527dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (resolver == null) {
2537dd252788645e940eada959bdde927426e2531c9Paul Duffin      resolver = (typeResolver = TypeResolver.accordingTo(runtimeType));
2547dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2557dd252788645e940eada959bdde927426e2531c9Paul Duffin    return of(resolver.resolveType(type));
2567dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2577dd252788645e940eada959bdde927426e2531c9Paul Duffin
2587dd252788645e940eada959bdde927426e2531c9Paul Duffin  private Type[] resolveInPlace(Type[] types) {
2597dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (int i = 0; i < types.length; i++) {
2607dd252788645e940eada959bdde927426e2531c9Paul Duffin      types[i] = resolveType(types[i]).getType();
2617dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2627dd252788645e940eada959bdde927426e2531c9Paul Duffin    return types;
2637dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2647dd252788645e940eada959bdde927426e2531c9Paul Duffin
2657dd252788645e940eada959bdde927426e2531c9Paul Duffin  private TypeToken<?> resolveSupertype(Type type) {
2667dd252788645e940eada959bdde927426e2531c9Paul Duffin    TypeToken<?> supertype = resolveType(type);
2677dd252788645e940eada959bdde927426e2531c9Paul Duffin    // super types' type mapping is a subset of type mapping of this type.
2687dd252788645e940eada959bdde927426e2531c9Paul Duffin    supertype.typeResolver = typeResolver;
2697dd252788645e940eada959bdde927426e2531c9Paul Duffin    return supertype;
2707dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
2717dd252788645e940eada959bdde927426e2531c9Paul Duffin
2727dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
2737dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns the generic superclass of this type or {@code null} if the type represents
2747dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@link Object} or an interface. This method is similar but different from {@link
2757dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Class#getGenericSuperclass}. For example, {@code
2767dd252788645e940eada959bdde927426e2531c9Paul Duffin   * new TypeToken<StringArrayList>() {}.getGenericSuperclass()} will return {@code
2777dd252788645e940eada959bdde927426e2531c9Paul Duffin   * new TypeToken<ArrayList<String>>() {}}; while {@code
2787dd252788645e940eada959bdde927426e2531c9Paul Duffin   * StringArrayList.class.getGenericSuperclass()} will return {@code ArrayList<E>}, where {@code E}
2797dd252788645e940eada959bdde927426e2531c9Paul Duffin   * is the type variable declared by class {@code ArrayList}.
2807dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
2817dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <p>If this type is a type variable or wildcard, its first upper bound is examined and returned
2827dd252788645e940eada959bdde927426e2531c9Paul Duffin   * if the bound is a class or extends from a class. This means that the returned type could be a
2837dd252788645e940eada959bdde927426e2531c9Paul Duffin   * type variable too.
2847dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
2857dd252788645e940eada959bdde927426e2531c9Paul Duffin  @Nullable
2867dd252788645e940eada959bdde927426e2531c9Paul Duffin  final TypeToken<? super T> getGenericSuperclass() {
2877dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (runtimeType instanceof TypeVariable) {
2887dd252788645e940eada959bdde927426e2531c9Paul Duffin      // First bound is always the super class, if one exists.
2897dd252788645e940eada959bdde927426e2531c9Paul Duffin      return boundAsSuperclass(((TypeVariable<?>) runtimeType).getBounds()[0]);
2907dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2917dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (runtimeType instanceof WildcardType) {
2927dd252788645e940eada959bdde927426e2531c9Paul Duffin      // wildcard has one and only one upper bound.
2937dd252788645e940eada959bdde927426e2531c9Paul Duffin      return boundAsSuperclass(((WildcardType) runtimeType).getUpperBounds()[0]);
2947dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2957dd252788645e940eada959bdde927426e2531c9Paul Duffin    Type superclass = getRawType().getGenericSuperclass();
2967dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (superclass == null) {
2977dd252788645e940eada959bdde927426e2531c9Paul Duffin      return null;
2987dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @SuppressWarnings("unchecked") // super class of T
3007dd252788645e940eada959bdde927426e2531c9Paul Duffin    TypeToken<? super T> superToken = (TypeToken<? super T>) resolveSupertype(superclass);
3017dd252788645e940eada959bdde927426e2531c9Paul Duffin    return superToken;
3027dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3037dd252788645e940eada959bdde927426e2531c9Paul Duffin
3040888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Nullable private TypeToken<? super T> boundAsSuperclass(Type bound) {
3057dd252788645e940eada959bdde927426e2531c9Paul Duffin    TypeToken<?> token = of(bound);
3067dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (token.getRawType().isInterface()) {
3077dd252788645e940eada959bdde927426e2531c9Paul Duffin      return null;
3087dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3090888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @SuppressWarnings("unchecked") // only upper bound of T is passed in.
3107dd252788645e940eada959bdde927426e2531c9Paul Duffin    TypeToken<? super T> superclass = (TypeToken<? super T>) token;
3117dd252788645e940eada959bdde927426e2531c9Paul Duffin    return superclass;
3127dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3137dd252788645e940eada959bdde927426e2531c9Paul Duffin
3147dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
3157dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns the generic interfaces that this type directly {@code implements}. This method is
3167dd252788645e940eada959bdde927426e2531c9Paul Duffin   * similar but different from {@link Class#getGenericInterfaces()}. For example, {@code
3177dd252788645e940eada959bdde927426e2531c9Paul Duffin   * new TypeToken<List<String>>() {}.getGenericInterfaces()} will return a list that contains
3187dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code new TypeToken<Iterable<String>>() {}}; while {@code List.class.getGenericInterfaces()}
3197dd252788645e940eada959bdde927426e2531c9Paul Duffin   * will return an array that contains {@code Iterable<T>}, where the {@code T} is the type
3207dd252788645e940eada959bdde927426e2531c9Paul Duffin   * variable declared by interface {@code Iterable}.
3217dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
3227dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <p>If this type is a type variable or wildcard, its upper bounds are examined and those that
3237dd252788645e940eada959bdde927426e2531c9Paul Duffin   * are either an interface or upper-bounded only by interfaces are returned. This means that the
3247dd252788645e940eada959bdde927426e2531c9Paul Duffin   * returned types could include type variables too.
3257dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
3267dd252788645e940eada959bdde927426e2531c9Paul Duffin  final ImmutableList<TypeToken<? super T>> getGenericInterfaces() {
3277dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (runtimeType instanceof TypeVariable) {
3287dd252788645e940eada959bdde927426e2531c9Paul Duffin      return boundsAsInterfaces(((TypeVariable<?>) runtimeType).getBounds());
3297dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3307dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (runtimeType instanceof WildcardType) {
3317dd252788645e940eada959bdde927426e2531c9Paul Duffin      return boundsAsInterfaces(((WildcardType) runtimeType).getUpperBounds());
3327dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3337dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableList.Builder<TypeToken<? super T>> builder = ImmutableList.builder();
3347dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (Type interfaceType : getRawType().getGenericInterfaces()) {
3350888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @SuppressWarnings("unchecked") // interface of T
3360888a09821a98ac0680fad765217302858e70fa4Paul Duffin      TypeToken<? super T> resolvedInterface = (TypeToken<? super T>)
3370888a09821a98ac0680fad765217302858e70fa4Paul Duffin          resolveSupertype(interfaceType);
3387dd252788645e940eada959bdde927426e2531c9Paul Duffin      builder.add(resolvedInterface);
3397dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3407dd252788645e940eada959bdde927426e2531c9Paul Duffin    return builder.build();
3417dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3427dd252788645e940eada959bdde927426e2531c9Paul Duffin
3437dd252788645e940eada959bdde927426e2531c9Paul Duffin  private ImmutableList<TypeToken<? super T>> boundsAsInterfaces(Type[] bounds) {
3447dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableList.Builder<TypeToken<? super T>> builder = ImmutableList.builder();
3457dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (Type bound : bounds) {
3460888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @SuppressWarnings("unchecked") // upper bound of T
3477dd252788645e940eada959bdde927426e2531c9Paul Duffin      TypeToken<? super T> boundType = (TypeToken<? super T>) of(bound);
3487dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (boundType.getRawType().isInterface()) {
3497dd252788645e940eada959bdde927426e2531c9Paul Duffin        builder.add(boundType);
3507dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
3517dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3527dd252788645e940eada959bdde927426e2531c9Paul Duffin    return builder.build();
3537dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3547dd252788645e940eada959bdde927426e2531c9Paul Duffin
3557dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
3567dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns the set of interfaces and classes that this type is or is a subtype of. The returned
3577dd252788645e940eada959bdde927426e2531c9Paul Duffin   * types are parameterized with proper type arguments.
3587dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
3597dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <p>Subtypes are always listed before supertypes. But the reverse is not true. A type isn't
3607dd252788645e940eada959bdde927426e2531c9Paul Duffin   * necessarily a subtype of all the types following. Order between types without subtype
3617dd252788645e940eada959bdde927426e2531c9Paul Duffin   * relationship is arbitrary and not guaranteed.
3627dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
3637dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <p>If this type is a type variable or wildcard, upper bounds that are themselves type variables
3647dd252788645e940eada959bdde927426e2531c9Paul Duffin   * aren't included (their super interfaces and superclasses are).
3657dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
3667dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final TypeSet getTypes() {
3677dd252788645e940eada959bdde927426e2531c9Paul Duffin    return new TypeSet();
3687dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3697dd252788645e940eada959bdde927426e2531c9Paul Duffin
3707dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
3717dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns the generic form of {@code superclass}. For example, if this is
3727dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code ArrayList<String>}, {@code Iterable<String>} is returned given the
3737dd252788645e940eada959bdde927426e2531c9Paul Duffin   * input {@code Iterable.class}.
3747dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
3757dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final TypeToken<? super T> getSupertype(Class<? super T> superclass) {
3760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkArgument(superclass.isAssignableFrom(getRawType()),
3770888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "%s is not a super class of %s", superclass, this);
3787dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (runtimeType instanceof TypeVariable) {
3797dd252788645e940eada959bdde927426e2531c9Paul Duffin      return getSupertypeFromUpperBounds(superclass, ((TypeVariable<?>) runtimeType).getBounds());
3807dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3817dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (runtimeType instanceof WildcardType) {
3827dd252788645e940eada959bdde927426e2531c9Paul Duffin      return getSupertypeFromUpperBounds(superclass, ((WildcardType) runtimeType).getUpperBounds());
3837dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3847dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (superclass.isArray()) {
3857dd252788645e940eada959bdde927426e2531c9Paul Duffin      return getArraySupertype(superclass);
3867dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
3870888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @SuppressWarnings("unchecked") // resolved supertype
3880888a09821a98ac0680fad765217302858e70fa4Paul Duffin    TypeToken<? super T> supertype = (TypeToken<? super T>)
3890888a09821a98ac0680fad765217302858e70fa4Paul Duffin        resolveSupertype(toGenericType(superclass).runtimeType);
3907dd252788645e940eada959bdde927426e2531c9Paul Duffin    return supertype;
3917dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
3927dd252788645e940eada959bdde927426e2531c9Paul Duffin
3937dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
3947dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns subtype of {@code this} with {@code subclass} as the raw class.
3957dd252788645e940eada959bdde927426e2531c9Paul Duffin   * For example, if this is {@code Iterable<String>} and {@code subclass} is {@code List},
3967dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code List<String>} is returned.
3977dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
3987dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final TypeToken<? extends T> getSubtype(Class<?> subclass) {
3997dd252788645e940eada959bdde927426e2531c9Paul Duffin    checkArgument(!(runtimeType instanceof TypeVariable),
4007dd252788645e940eada959bdde927426e2531c9Paul Duffin        "Cannot get subtype of type variable <%s>", this);
4017dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (runtimeType instanceof WildcardType) {
4027dd252788645e940eada959bdde927426e2531c9Paul Duffin      return getSubtypeFromLowerBounds(subclass, ((WildcardType) runtimeType).getLowerBounds());
4037dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkArgument(getRawType().isAssignableFrom(subclass),
4050888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "%s isn't a subclass of %s", subclass, this);
4067dd252788645e940eada959bdde927426e2531c9Paul Duffin    // unwrap array type if necessary
4077dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (isArray()) {
4087dd252788645e940eada959bdde927426e2531c9Paul Duffin      return getArraySubtype(subclass);
4097dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @SuppressWarnings("unchecked") // guarded by the isAssignableFrom() statement above
4110888a09821a98ac0680fad765217302858e70fa4Paul Duffin    TypeToken<? extends T> subtype = (TypeToken<? extends T>)
4120888a09821a98ac0680fad765217302858e70fa4Paul Duffin        of(resolveTypeArgsForSubclass(subclass));
4137dd252788645e940eada959bdde927426e2531c9Paul Duffin    return subtype;
4147dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4157dd252788645e940eada959bdde927426e2531c9Paul Duffin
4167dd252788645e940eada959bdde927426e2531c9Paul Duffin  /** Returns true if this type is assignable from the given {@code type}. */
4177dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final boolean isAssignableFrom(TypeToken<?> type) {
4187dd252788645e940eada959bdde927426e2531c9Paul Duffin    return isAssignableFrom(type.runtimeType);
4197dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4207dd252788645e940eada959bdde927426e2531c9Paul Duffin
4217dd252788645e940eada959bdde927426e2531c9Paul Duffin  /** Check if this type is assignable from the given {@code type}. */
4227dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final boolean isAssignableFrom(Type type) {
4237dd252788645e940eada959bdde927426e2531c9Paul Duffin    return isAssignable(checkNotNull(type), runtimeType);
4247dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4257dd252788645e940eada959bdde927426e2531c9Paul Duffin
4267dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
4277dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns true if this type is known to be an array type, such as {@code int[]}, {@code T[]},
4287dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code <? extends Map<String, Integer>[]>} etc.
4297dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
4307dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final boolean isArray() {
4317dd252788645e940eada959bdde927426e2531c9Paul Duffin    return getComponentType() != null;
4327dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4337dd252788645e940eada959bdde927426e2531c9Paul Duffin
4347dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
4350888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Returns true if this type is one of the nine primitive types (including {@code void}).
4360888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
4370888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @since 15.0
4380888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
4390888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public final boolean isPrimitive() {
4400888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return (runtimeType instanceof Class) && ((Class<?>) runtimeType).isPrimitive();
4410888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4420888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4430888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
4440888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Returns the corresponding wrapper type if this is a primitive type; otherwise returns
4450888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * {@code this} itself. Idempotent.
4460888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
4470888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @since 15.0
4480888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
4490888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public final TypeToken<T> wrap() {
4500888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (isPrimitive()) {
4510888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @SuppressWarnings("unchecked") // this is a primitive class
4520888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Class<T> type = (Class<T>) runtimeType;
4530888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return TypeToken.of(Primitives.wrap(type));
4540888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4550888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return this;
4560888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4570888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4580888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private boolean isWrapper() {
4590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return Primitives.allWrapperTypes().contains(runtimeType);
4600888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4610888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4620888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
4630888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Returns the corresponding primitive type if this is a wrapper type; otherwise returns
4640888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * {@code this} itself. Idempotent.
4650888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
4660888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @since 15.0
4670888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
4680888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public final TypeToken<T> unwrap() {
4690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (isWrapper()) {
4700888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @SuppressWarnings("unchecked") // this is a wrapper class
4710888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Class<T> type = (Class<T>) runtimeType;
4720888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return TypeToken.of(Primitives.unwrap(type));
4730888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
4740888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return this;
4750888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
4760888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4770888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
4787dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns the array component type if this type represents an array ({@code int[]}, {@code T[]},
4797dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code <? extends Map<String, Integer>[]>} etc.), or else {@code null} is returned.
4807dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
4810888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Nullable public final TypeToken<?> getComponentType() {
4827dd252788645e940eada959bdde927426e2531c9Paul Duffin    Type componentType = Types.getComponentType(runtimeType);
4837dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (componentType == null) {
4847dd252788645e940eada959bdde927426e2531c9Paul Duffin      return null;
4857dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
4867dd252788645e940eada959bdde927426e2531c9Paul Duffin    return of(componentType);
4877dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
4887dd252788645e940eada959bdde927426e2531c9Paul Duffin
4897dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
4907dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns the {@link Invokable} for {@code method}, which must be a member of {@code T}.
4917dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
4927dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @since 14.0
4937dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
4947dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final Invokable<T, Object> method(Method method) {
4950888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkArgument(of(method.getDeclaringClass()).isAssignableFrom(this),
4960888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "%s not declared by %s", method, this);
4977dd252788645e940eada959bdde927426e2531c9Paul Duffin    return new Invokable.MethodInvokable<T>(method) {
4980888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override Type getGenericReturnType() {
4997dd252788645e940eada959bdde927426e2531c9Paul Duffin        return resolveType(super.getGenericReturnType()).getType();
5007dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5010888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override Type[] getGenericParameterTypes() {
5027dd252788645e940eada959bdde927426e2531c9Paul Duffin        return resolveInPlace(super.getGenericParameterTypes());
5037dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5040888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override Type[] getGenericExceptionTypes() {
5057dd252788645e940eada959bdde927426e2531c9Paul Duffin        return resolveInPlace(super.getGenericExceptionTypes());
5067dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5077dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override public TypeToken<T> getOwnerType() {
5087dd252788645e940eada959bdde927426e2531c9Paul Duffin        return TypeToken.this;
5097dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5100888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override public String toString() {
5110888a09821a98ac0680fad765217302858e70fa4Paul Duffin        return getOwnerType() + "." + super.toString();
5120888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
5137dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
5147dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
5157dd252788645e940eada959bdde927426e2531c9Paul Duffin
5167dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
5177dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns the {@link Invokable} for {@code constructor}, which must be a member of {@code T}.
5187dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
5197dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @since 14.0
5207dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
5217dd252788645e940eada959bdde927426e2531c9Paul Duffin  public final Invokable<T, T> constructor(Constructor<?> constructor) {
5220888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkArgument(constructor.getDeclaringClass() == getRawType(),
5230888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "%s not declared by %s", constructor, getRawType());
5247dd252788645e940eada959bdde927426e2531c9Paul Duffin    return new Invokable.ConstructorInvokable<T>(constructor) {
5250888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override Type getGenericReturnType() {
5267dd252788645e940eada959bdde927426e2531c9Paul Duffin        return resolveType(super.getGenericReturnType()).getType();
5277dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5280888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override Type[] getGenericParameterTypes() {
5297dd252788645e940eada959bdde927426e2531c9Paul Duffin        return resolveInPlace(super.getGenericParameterTypes());
5307dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5310888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override Type[] getGenericExceptionTypes() {
5327dd252788645e940eada959bdde927426e2531c9Paul Duffin        return resolveInPlace(super.getGenericExceptionTypes());
5337dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5347dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override public TypeToken<T> getOwnerType() {
5357dd252788645e940eada959bdde927426e2531c9Paul Duffin        return TypeToken.this;
5367dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5370888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override public String toString() {
5380888a09821a98ac0680fad765217302858e70fa4Paul Duffin        return getOwnerType() + "(" + Joiner.on(", ").join(getGenericParameterTypes()) + ")";
5390888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
5407dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
5417dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
5427dd252788645e940eada959bdde927426e2531c9Paul Duffin
5437dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
5447dd252788645e940eada959bdde927426e2531c9Paul Duffin   * The set of interfaces and classes that {@code T} is or is a subtype of. {@link Object} is not
5457dd252788645e940eada959bdde927426e2531c9Paul Duffin   * included in the set if this type is an interface.
5467dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
5477dd252788645e940eada959bdde927426e2531c9Paul Duffin  public class TypeSet extends ForwardingSet<TypeToken<? super T>> implements Serializable {
5487dd252788645e940eada959bdde927426e2531c9Paul Duffin
5497dd252788645e940eada959bdde927426e2531c9Paul Duffin    private transient ImmutableSet<TypeToken<? super T>> types;
5507dd252788645e940eada959bdde927426e2531c9Paul Duffin
5517dd252788645e940eada959bdde927426e2531c9Paul Duffin    TypeSet() {}
5527dd252788645e940eada959bdde927426e2531c9Paul Duffin
5537dd252788645e940eada959bdde927426e2531c9Paul Duffin    /** Returns the types that are interfaces implemented by this type. */
5547dd252788645e940eada959bdde927426e2531c9Paul Duffin    public TypeSet interfaces() {
5557dd252788645e940eada959bdde927426e2531c9Paul Duffin      return new InterfaceSet(this);
5567dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5577dd252788645e940eada959bdde927426e2531c9Paul Duffin
5587dd252788645e940eada959bdde927426e2531c9Paul Duffin    /** Returns the types that are classes. */
5597dd252788645e940eada959bdde927426e2531c9Paul Duffin    public TypeSet classes() {
5607dd252788645e940eada959bdde927426e2531c9Paul Duffin      return new ClassSet();
5617dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5627dd252788645e940eada959bdde927426e2531c9Paul Duffin
5630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override protected Set<TypeToken<? super T>> delegate() {
5647dd252788645e940eada959bdde927426e2531c9Paul Duffin      ImmutableSet<TypeToken<? super T>> filteredTypes = types;
5657dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (filteredTypes == null) {
5667dd252788645e940eada959bdde927426e2531c9Paul Duffin        // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
5670888a09821a98ac0680fad765217302858e70fa4Paul Duffin        @SuppressWarnings({"unchecked", "rawtypes"})
5680888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ImmutableList<TypeToken<? super T>> collectedTypes = (ImmutableList)
5690888a09821a98ac0680fad765217302858e70fa4Paul Duffin            TypeCollector.FOR_GENERIC_TYPE.collectTypes(TypeToken.this);
5707dd252788645e940eada959bdde927426e2531c9Paul Duffin        return (types = FluentIterable.from(collectedTypes)
5710888a09821a98ac0680fad765217302858e70fa4Paul Duffin                .filter(TypeFilter.IGNORE_TYPE_VARIABLE_OR_WILDCARD)
5720888a09821a98ac0680fad765217302858e70fa4Paul Duffin                .toSet());
5737dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else {
5747dd252788645e940eada959bdde927426e2531c9Paul Duffin        return filteredTypes;
5757dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
5767dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5777dd252788645e940eada959bdde927426e2531c9Paul Duffin
5787dd252788645e940eada959bdde927426e2531c9Paul Duffin    /** Returns the raw types of the types in this set, in the same order. */
5797dd252788645e940eada959bdde927426e2531c9Paul Duffin    public Set<Class<? super T>> rawTypes() {
5807dd252788645e940eada959bdde927426e2531c9Paul Duffin      // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
5810888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @SuppressWarnings({"unchecked", "rawtypes"})
5820888a09821a98ac0680fad765217302858e70fa4Paul Duffin      ImmutableList<Class<? super T>> collectedTypes = (ImmutableList)
5830888a09821a98ac0680fad765217302858e70fa4Paul Duffin          TypeCollector.FOR_RAW_TYPE.collectTypes(getImmediateRawTypes());
5847dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ImmutableSet.copyOf(collectedTypes);
5857dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5867dd252788645e940eada959bdde927426e2531c9Paul Duffin
5877dd252788645e940eada959bdde927426e2531c9Paul Duffin    private static final long serialVersionUID = 0;
5887dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
5897dd252788645e940eada959bdde927426e2531c9Paul Duffin
5907dd252788645e940eada959bdde927426e2531c9Paul Duffin  private final class InterfaceSet extends TypeSet {
5917dd252788645e940eada959bdde927426e2531c9Paul Duffin
5927dd252788645e940eada959bdde927426e2531c9Paul Duffin    private transient final TypeSet allTypes;
5937dd252788645e940eada959bdde927426e2531c9Paul Duffin    private transient ImmutableSet<TypeToken<? super T>> interfaces;
5947dd252788645e940eada959bdde927426e2531c9Paul Duffin
5957dd252788645e940eada959bdde927426e2531c9Paul Duffin    InterfaceSet(TypeSet allTypes) {
5967dd252788645e940eada959bdde927426e2531c9Paul Duffin      this.allTypes = allTypes;
5977dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
5987dd252788645e940eada959bdde927426e2531c9Paul Duffin
5990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override protected Set<TypeToken<? super T>> delegate() {
6007dd252788645e940eada959bdde927426e2531c9Paul Duffin      ImmutableSet<TypeToken<? super T>> result = interfaces;
6017dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (result == null) {
6020888a09821a98ac0680fad765217302858e70fa4Paul Duffin        return (interfaces = FluentIterable.from(allTypes)
6030888a09821a98ac0680fad765217302858e70fa4Paul Duffin            .filter(TypeFilter.INTERFACE_ONLY)
6047dd252788645e940eada959bdde927426e2531c9Paul Duffin            .toSet());
6057dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else {
6067dd252788645e940eada959bdde927426e2531c9Paul Duffin        return result;
6077dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
6087dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6097dd252788645e940eada959bdde927426e2531c9Paul Duffin
6100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public TypeSet interfaces() {
6117dd252788645e940eada959bdde927426e2531c9Paul Duffin      return this;
6127dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6137dd252788645e940eada959bdde927426e2531c9Paul Duffin
6140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public Set<Class<? super T>> rawTypes() {
6157dd252788645e940eada959bdde927426e2531c9Paul Duffin      // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
6160888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @SuppressWarnings({"unchecked", "rawtypes"})
6170888a09821a98ac0680fad765217302858e70fa4Paul Duffin      ImmutableList<Class<? super T>> collectedTypes = (ImmutableList)
6180888a09821a98ac0680fad765217302858e70fa4Paul Duffin          TypeCollector.FOR_RAW_TYPE.collectTypes(getImmediateRawTypes());
6190888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return FluentIterable.from(collectedTypes)
6200888a09821a98ac0680fad765217302858e70fa4Paul Duffin          .filter(new Predicate<Class<?>>() {
6210888a09821a98ac0680fad765217302858e70fa4Paul Duffin            @Override public boolean apply(Class<?> type) {
6220888a09821a98ac0680fad765217302858e70fa4Paul Duffin              return type.isInterface();
6230888a09821a98ac0680fad765217302858e70fa4Paul Duffin            }
6240888a09821a98ac0680fad765217302858e70fa4Paul Duffin          })
6250888a09821a98ac0680fad765217302858e70fa4Paul Duffin          .toSet();
6267dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6277dd252788645e940eada959bdde927426e2531c9Paul Duffin
6280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public TypeSet classes() {
6297dd252788645e940eada959bdde927426e2531c9Paul Duffin      throw new UnsupportedOperationException("interfaces().classes() not supported.");
6307dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6317dd252788645e940eada959bdde927426e2531c9Paul Duffin
6327dd252788645e940eada959bdde927426e2531c9Paul Duffin    private Object readResolve() {
6337dd252788645e940eada959bdde927426e2531c9Paul Duffin      return getTypes().interfaces();
6347dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6357dd252788645e940eada959bdde927426e2531c9Paul Duffin
6367dd252788645e940eada959bdde927426e2531c9Paul Duffin    private static final long serialVersionUID = 0;
6377dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6387dd252788645e940eada959bdde927426e2531c9Paul Duffin
6397dd252788645e940eada959bdde927426e2531c9Paul Duffin  private final class ClassSet extends TypeSet {
6407dd252788645e940eada959bdde927426e2531c9Paul Duffin
6417dd252788645e940eada959bdde927426e2531c9Paul Duffin    private transient ImmutableSet<TypeToken<? super T>> classes;
6427dd252788645e940eada959bdde927426e2531c9Paul Duffin
6430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override protected Set<TypeToken<? super T>> delegate() {
6447dd252788645e940eada959bdde927426e2531c9Paul Duffin      ImmutableSet<TypeToken<? super T>> result = classes;
6457dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (result == null) {
6460888a09821a98ac0680fad765217302858e70fa4Paul Duffin        @SuppressWarnings({"unchecked", "rawtypes"})
6470888a09821a98ac0680fad765217302858e70fa4Paul Duffin        ImmutableList<TypeToken<? super T>> collectedTypes = (ImmutableList)
6480888a09821a98ac0680fad765217302858e70fa4Paul Duffin            TypeCollector.FOR_GENERIC_TYPE.classesOnly().collectTypes(TypeToken.this);
6497dd252788645e940eada959bdde927426e2531c9Paul Duffin        return (classes = FluentIterable.from(collectedTypes)
6500888a09821a98ac0680fad765217302858e70fa4Paul Duffin            .filter(TypeFilter.IGNORE_TYPE_VARIABLE_OR_WILDCARD)
6510888a09821a98ac0680fad765217302858e70fa4Paul Duffin            .toSet());
6527dd252788645e940eada959bdde927426e2531c9Paul Duffin      } else {
6537dd252788645e940eada959bdde927426e2531c9Paul Duffin        return result;
6547dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
6557dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6567dd252788645e940eada959bdde927426e2531c9Paul Duffin
6570888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public TypeSet classes() {
6587dd252788645e940eada959bdde927426e2531c9Paul Duffin      return this;
6597dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6607dd252788645e940eada959bdde927426e2531c9Paul Duffin
6610888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public Set<Class<? super T>> rawTypes() {
6627dd252788645e940eada959bdde927426e2531c9Paul Duffin      // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
6630888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @SuppressWarnings({"unchecked", "rawtypes"})
6640888a09821a98ac0680fad765217302858e70fa4Paul Duffin      ImmutableList<Class<? super T>> collectedTypes = (ImmutableList)
6650888a09821a98ac0680fad765217302858e70fa4Paul Duffin          TypeCollector.FOR_RAW_TYPE.classesOnly().collectTypes(getImmediateRawTypes());
6667dd252788645e940eada959bdde927426e2531c9Paul Duffin      return ImmutableSet.copyOf(collectedTypes);
6677dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6687dd252788645e940eada959bdde927426e2531c9Paul Duffin
6690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override public TypeSet interfaces() {
6707dd252788645e940eada959bdde927426e2531c9Paul Duffin      throw new UnsupportedOperationException("classes().interfaces() not supported.");
6717dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6727dd252788645e940eada959bdde927426e2531c9Paul Duffin
6737dd252788645e940eada959bdde927426e2531c9Paul Duffin    private Object readResolve() {
6747dd252788645e940eada959bdde927426e2531c9Paul Duffin      return getTypes().classes();
6757dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6767dd252788645e940eada959bdde927426e2531c9Paul Duffin
6777dd252788645e940eada959bdde927426e2531c9Paul Duffin    private static final long serialVersionUID = 0;
6787dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6797dd252788645e940eada959bdde927426e2531c9Paul Duffin
6807dd252788645e940eada959bdde927426e2531c9Paul Duffin  private enum TypeFilter implements Predicate<TypeToken<?>> {
6817dd252788645e940eada959bdde927426e2531c9Paul Duffin
6827dd252788645e940eada959bdde927426e2531c9Paul Duffin    IGNORE_TYPE_VARIABLE_OR_WILDCARD {
6830888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override public boolean apply(TypeToken<?> type) {
6840888a09821a98ac0680fad765217302858e70fa4Paul Duffin        return !(type.runtimeType instanceof TypeVariable
6850888a09821a98ac0680fad765217302858e70fa4Paul Duffin            || type.runtimeType instanceof WildcardType);
6867dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
6877dd252788645e940eada959bdde927426e2531c9Paul Duffin    },
6887dd252788645e940eada959bdde927426e2531c9Paul Duffin    INTERFACE_ONLY {
6890888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override public boolean apply(TypeToken<?> type) {
6907dd252788645e940eada959bdde927426e2531c9Paul Duffin        return type.getRawType().isInterface();
6917dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
6927dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
6937dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
6947dd252788645e940eada959bdde927426e2531c9Paul Duffin
6957dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
6967dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns true if {@code o} is another {@code TypeToken} that represents the same {@link Type}.
6977dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
6980888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override public boolean equals(@Nullable Object o) {
6997dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (o instanceof TypeToken) {
7007dd252788645e940eada959bdde927426e2531c9Paul Duffin      TypeToken<?> that = (TypeToken<?>) o;
7017dd252788645e940eada959bdde927426e2531c9Paul Duffin      return runtimeType.equals(that.runtimeType);
7027dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
7037dd252788645e940eada959bdde927426e2531c9Paul Duffin    return false;
7047dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7057dd252788645e940eada959bdde927426e2531c9Paul Duffin
7060888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override public int hashCode() {
7077dd252788645e940eada959bdde927426e2531c9Paul Duffin    return runtimeType.hashCode();
7087dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7097dd252788645e940eada959bdde927426e2531c9Paul Duffin
7100888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override public String toString() {
7117dd252788645e940eada959bdde927426e2531c9Paul Duffin    return Types.toString(runtimeType);
7127dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7137dd252788645e940eada959bdde927426e2531c9Paul Duffin
7147dd252788645e940eada959bdde927426e2531c9Paul Duffin  /** Implemented to support serialization of subclasses. */
7157dd252788645e940eada959bdde927426e2531c9Paul Duffin  protected Object writeReplace() {
7167dd252788645e940eada959bdde927426e2531c9Paul Duffin    // TypeResolver just transforms the type to our own impls that are Serializable
7177dd252788645e940eada959bdde927426e2531c9Paul Duffin    // except TypeVariable.
7187dd252788645e940eada959bdde927426e2531c9Paul Duffin    return of(new TypeResolver().resolveType(runtimeType));
7197dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7207dd252788645e940eada959bdde927426e2531c9Paul Duffin
7217dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
7227dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Ensures that this type token doesn't contain type variables, which can cause unchecked type
7237dd252788645e940eada959bdde927426e2531c9Paul Duffin   * errors for callers like {@link TypeToInstanceMap}.
7247dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
7257dd252788645e940eada959bdde927426e2531c9Paul Duffin  final TypeToken<T> rejectTypeVariables() {
7260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    new TypeVisitor() {
7270888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override void visitTypeVariable(TypeVariable<?> type) {
7280888a09821a98ac0680fad765217302858e70fa4Paul Duffin        throw new IllegalArgumentException(
7290888a09821a98ac0680fad765217302858e70fa4Paul Duffin            runtimeType + "contains a type variable and is not safe for the operation");
7300888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
7310888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override void visitWildcardType(WildcardType type) {
7320888a09821a98ac0680fad765217302858e70fa4Paul Duffin        visit(type.getLowerBounds());
7330888a09821a98ac0680fad765217302858e70fa4Paul Duffin        visit(type.getUpperBounds());
7340888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
7350888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override void visitParameterizedType(ParameterizedType type) {
7360888a09821a98ac0680fad765217302858e70fa4Paul Duffin        visit(type.getActualTypeArguments());
7370888a09821a98ac0680fad765217302858e70fa4Paul Duffin        visit(type.getOwnerType());
7380888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
7390888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override void visitGenericArrayType(GenericArrayType type) {
7400888a09821a98ac0680fad765217302858e70fa4Paul Duffin        visit(type.getGenericComponentType());
7410888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
7420888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }.visit(runtimeType);
7437dd252788645e940eada959bdde927426e2531c9Paul Duffin    return this;
7447dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7457dd252788645e940eada959bdde927426e2531c9Paul Duffin
7467dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static boolean isAssignable(Type from, Type to) {
7477dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (to.equals(from)) {
7487dd252788645e940eada959bdde927426e2531c9Paul Duffin      return true;
7497dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
7507dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (to instanceof WildcardType) {
7517dd252788645e940eada959bdde927426e2531c9Paul Duffin      return isAssignableToWildcardType(from, (WildcardType) to);
7527dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
7537dd252788645e940eada959bdde927426e2531c9Paul Duffin    // if "from" is type variable, it's assignable if any of its "extends"
7547dd252788645e940eada959bdde927426e2531c9Paul Duffin    // bounds is assignable to "to".
7557dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (from instanceof TypeVariable) {
7567dd252788645e940eada959bdde927426e2531c9Paul Duffin      return isAssignableFromAny(((TypeVariable<?>) from).getBounds(), to);
7577dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
7587dd252788645e940eada959bdde927426e2531c9Paul Duffin    // if "from" is wildcard, it'a assignable to "to" if any of its "extends"
7597dd252788645e940eada959bdde927426e2531c9Paul Duffin    // bounds is assignable to "to".
7607dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (from instanceof WildcardType) {
7617dd252788645e940eada959bdde927426e2531c9Paul Duffin      return isAssignableFromAny(((WildcardType) from).getUpperBounds(), to);
7627dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
7637dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (from instanceof GenericArrayType) {
7647dd252788645e940eada959bdde927426e2531c9Paul Duffin      return isAssignableFromGenericArrayType((GenericArrayType) from, to);
7657dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
7667dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Proceed to regular Type assignability check
7677dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (to instanceof Class) {
7687dd252788645e940eada959bdde927426e2531c9Paul Duffin      return isAssignableToClass(from, (Class<?>) to);
7697dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else if (to instanceof ParameterizedType) {
7707dd252788645e940eada959bdde927426e2531c9Paul Duffin      return isAssignableToParameterizedType(from, (ParameterizedType) to);
7717dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else if (to instanceof GenericArrayType) {
7727dd252788645e940eada959bdde927426e2531c9Paul Duffin      return isAssignableToGenericArrayType(from, (GenericArrayType) to);
7737dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else { // to instanceof TypeVariable
7747dd252788645e940eada959bdde927426e2531c9Paul Duffin      return false;
7757dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
7767dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7777dd252788645e940eada959bdde927426e2531c9Paul Duffin
7787dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static boolean isAssignableFromAny(Type[] fromTypes, Type to) {
7797dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (Type from : fromTypes) {
7807dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (isAssignable(from, to)) {
7817dd252788645e940eada959bdde927426e2531c9Paul Duffin        return true;
7827dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
7837dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
7847dd252788645e940eada959bdde927426e2531c9Paul Duffin    return false;
7857dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7867dd252788645e940eada959bdde927426e2531c9Paul Duffin
7877dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static boolean isAssignableToClass(Type from, Class<?> to) {
7887dd252788645e940eada959bdde927426e2531c9Paul Duffin    return to.isAssignableFrom(getRawType(from));
7897dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
7907dd252788645e940eada959bdde927426e2531c9Paul Duffin
7910888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static boolean isAssignableToWildcardType(
7920888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Type from, WildcardType to) {
7937dd252788645e940eada959bdde927426e2531c9Paul Duffin    // if "to" is <? extends Foo>, "from" can be:
7947dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Foo, SubFoo, <? extends Foo>, <? extends SubFoo>, <T extends Foo> or
7957dd252788645e940eada959bdde927426e2531c9Paul Duffin    // <T extends SubFoo>.
7967dd252788645e940eada959bdde927426e2531c9Paul Duffin    // if "to" is <? super Foo>, "from" can be:
7977dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Foo, SuperFoo, <? super Foo> or <? super SuperFoo>.
7987dd252788645e940eada959bdde927426e2531c9Paul Duffin    return isAssignable(from, supertypeBound(to)) && isAssignableBySubtypeBound(from, to);
7997dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
8007dd252788645e940eada959bdde927426e2531c9Paul Duffin
8017dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static boolean isAssignableBySubtypeBound(Type from, WildcardType to) {
8027dd252788645e940eada959bdde927426e2531c9Paul Duffin    Type toSubtypeBound = subtypeBound(to);
8037dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (toSubtypeBound == null) {
8047dd252788645e940eada959bdde927426e2531c9Paul Duffin      return true;
8057dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8067dd252788645e940eada959bdde927426e2531c9Paul Duffin    Type fromSubtypeBound = subtypeBound(from);
8077dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (fromSubtypeBound == null) {
8087dd252788645e940eada959bdde927426e2531c9Paul Duffin      return false;
8097dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8107dd252788645e940eada959bdde927426e2531c9Paul Duffin    return isAssignable(toSubtypeBound, fromSubtypeBound);
8117dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
8127dd252788645e940eada959bdde927426e2531c9Paul Duffin
8137dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static boolean isAssignableToParameterizedType(Type from, ParameterizedType to) {
8147dd252788645e940eada959bdde927426e2531c9Paul Duffin    Class<?> matchedClass = getRawType(to);
8157dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (!matchedClass.isAssignableFrom(getRawType(from))) {
8167dd252788645e940eada959bdde927426e2531c9Paul Duffin      return false;
8177dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8187dd252788645e940eada959bdde927426e2531c9Paul Duffin    Type[] typeParams = matchedClass.getTypeParameters();
8197dd252788645e940eada959bdde927426e2531c9Paul Duffin    Type[] toTypeArgs = to.getActualTypeArguments();
8207dd252788645e940eada959bdde927426e2531c9Paul Duffin    TypeToken<?> fromTypeToken = of(from);
8217dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (int i = 0; i < typeParams.length; i++) {
8227dd252788645e940eada959bdde927426e2531c9Paul Duffin      // If "to" is "List<? extends CharSequence>"
8237dd252788645e940eada959bdde927426e2531c9Paul Duffin      // and "from" is StringArrayList,
8247dd252788645e940eada959bdde927426e2531c9Paul Duffin      // First step is to figure out StringArrayList "is-a" List<E> and <E> is
8257dd252788645e940eada959bdde927426e2531c9Paul Duffin      // String.
8267dd252788645e940eada959bdde927426e2531c9Paul Duffin      // typeParams[0] is E and fromTypeToken.get(typeParams[0]) will resolve to
8277dd252788645e940eada959bdde927426e2531c9Paul Duffin      // String.
8287dd252788645e940eada959bdde927426e2531c9Paul Duffin      // String is then matched against <? extends CharSequence>.
8297dd252788645e940eada959bdde927426e2531c9Paul Duffin      Type fromTypeArg = fromTypeToken.resolveType(typeParams[i]).runtimeType;
8307dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (!matchTypeArgument(fromTypeArg, toTypeArgs[i])) {
8317dd252788645e940eada959bdde927426e2531c9Paul Duffin        return false;
8327dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
8337dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8347dd252788645e940eada959bdde927426e2531c9Paul Duffin    return true;
8357dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
8367dd252788645e940eada959bdde927426e2531c9Paul Duffin
8377dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static boolean isAssignableToGenericArrayType(Type from, GenericArrayType to) {
8387dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (from instanceof Class) {
8397dd252788645e940eada959bdde927426e2531c9Paul Duffin      Class<?> fromClass = (Class<?>) from;
8407dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (!fromClass.isArray()) {
8417dd252788645e940eada959bdde927426e2531c9Paul Duffin        return false;
8427dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
8437dd252788645e940eada959bdde927426e2531c9Paul Duffin      return isAssignable(fromClass.getComponentType(), to.getGenericComponentType());
8447dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else if (from instanceof GenericArrayType) {
8457dd252788645e940eada959bdde927426e2531c9Paul Duffin      GenericArrayType fromArrayType = (GenericArrayType) from;
8467dd252788645e940eada959bdde927426e2531c9Paul Duffin      return isAssignable(fromArrayType.getGenericComponentType(), to.getGenericComponentType());
8477dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else {
8487dd252788645e940eada959bdde927426e2531c9Paul Duffin      return false;
8497dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8507dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
8517dd252788645e940eada959bdde927426e2531c9Paul Duffin
8527dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static boolean isAssignableFromGenericArrayType(GenericArrayType from, Type to) {
8537dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (to instanceof Class) {
8547dd252788645e940eada959bdde927426e2531c9Paul Duffin      Class<?> toClass = (Class<?>) to;
8557dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (!toClass.isArray()) {
8567dd252788645e940eada959bdde927426e2531c9Paul Duffin        return toClass == Object.class; // any T[] is assignable to Object
8577dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
8587dd252788645e940eada959bdde927426e2531c9Paul Duffin      return isAssignable(from.getGenericComponentType(), toClass.getComponentType());
8597dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else if (to instanceof GenericArrayType) {
8607dd252788645e940eada959bdde927426e2531c9Paul Duffin      GenericArrayType toArrayType = (GenericArrayType) to;
8617dd252788645e940eada959bdde927426e2531c9Paul Duffin      return isAssignable(from.getGenericComponentType(), toArrayType.getGenericComponentType());
8627dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else {
8637dd252788645e940eada959bdde927426e2531c9Paul Duffin      return false;
8647dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8657dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
8667dd252788645e940eada959bdde927426e2531c9Paul Duffin
8677dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static boolean matchTypeArgument(Type from, Type to) {
8687dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (from.equals(to)) {
8697dd252788645e940eada959bdde927426e2531c9Paul Duffin      return true;
8707dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8717dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (to instanceof WildcardType) {
8727dd252788645e940eada959bdde927426e2531c9Paul Duffin      return isAssignableToWildcardType(from, (WildcardType) to);
8737dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8747dd252788645e940eada959bdde927426e2531c9Paul Duffin    return false;
8757dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
8767dd252788645e940eada959bdde927426e2531c9Paul Duffin
8777dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static Type supertypeBound(Type type) {
8787dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (type instanceof WildcardType) {
8797dd252788645e940eada959bdde927426e2531c9Paul Duffin      return supertypeBound((WildcardType) type);
8807dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8817dd252788645e940eada959bdde927426e2531c9Paul Duffin    return type;
8827dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
8837dd252788645e940eada959bdde927426e2531c9Paul Duffin
8847dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static Type supertypeBound(WildcardType type) {
8857dd252788645e940eada959bdde927426e2531c9Paul Duffin    Type[] upperBounds = type.getUpperBounds();
8867dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (upperBounds.length == 1) {
8877dd252788645e940eada959bdde927426e2531c9Paul Duffin      return supertypeBound(upperBounds[0]);
8887dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else if (upperBounds.length == 0) {
8897dd252788645e940eada959bdde927426e2531c9Paul Duffin      return Object.class;
8907dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else {
8910888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new AssertionError(
8920888a09821a98ac0680fad765217302858e70fa4Paul Duffin          "There should be at most one upper bound for wildcard type: " + type);
8937dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
8947dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
8957dd252788645e940eada959bdde927426e2531c9Paul Duffin
8960888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Nullable private static Type subtypeBound(Type type) {
8977dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (type instanceof WildcardType) {
8987dd252788645e940eada959bdde927426e2531c9Paul Duffin      return subtypeBound((WildcardType) type);
8997dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else {
9007dd252788645e940eada959bdde927426e2531c9Paul Duffin      return type;
9017dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
9027dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9037dd252788645e940eada959bdde927426e2531c9Paul Duffin
9040888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Nullable private static Type subtypeBound(WildcardType type) {
9057dd252788645e940eada959bdde927426e2531c9Paul Duffin    Type[] lowerBounds = type.getLowerBounds();
9067dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (lowerBounds.length == 1) {
9077dd252788645e940eada959bdde927426e2531c9Paul Duffin      return subtypeBound(lowerBounds[0]);
9087dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else if (lowerBounds.length == 0) {
9097dd252788645e940eada959bdde927426e2531c9Paul Duffin      return null;
9107dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else {
9110888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throw new AssertionError(
9120888a09821a98ac0680fad765217302858e70fa4Paul Duffin          "Wildcard should have at most one lower bound: " + type);
9137dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
9147dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9157dd252788645e940eada959bdde927426e2531c9Paul Duffin
9160888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @VisibleForTesting static Class<?> getRawType(Type type) {
9177dd252788645e940eada959bdde927426e2531c9Paul Duffin    // For wildcard or type variable, the first bound determines the runtime type.
9187dd252788645e940eada959bdde927426e2531c9Paul Duffin    return getRawTypes(type).iterator().next();
9197dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9207dd252788645e940eada959bdde927426e2531c9Paul Duffin
9210888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @VisibleForTesting static ImmutableSet<Class<?>> getRawTypes(Type type) {
9220888a09821a98ac0680fad765217302858e70fa4Paul Duffin    checkNotNull(type);
9230888a09821a98ac0680fad765217302858e70fa4Paul Duffin    final ImmutableSet.Builder<Class<?>> builder = ImmutableSet.builder();
9240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    new TypeVisitor() {
9250888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override void visitTypeVariable(TypeVariable<?> t) {
9260888a09821a98ac0680fad765217302858e70fa4Paul Duffin        visit(t.getBounds());
9270888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
9280888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override void visitWildcardType(WildcardType t) {
9290888a09821a98ac0680fad765217302858e70fa4Paul Duffin        visit(t.getUpperBounds());
9300888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
9310888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override void visitParameterizedType(ParameterizedType t) {
9320888a09821a98ac0680fad765217302858e70fa4Paul Duffin        builder.add((Class<?>) t.getRawType());
9330888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
9340888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override void visitClass(Class<?> t) {
9350888a09821a98ac0680fad765217302858e70fa4Paul Duffin        builder.add(t);
9360888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
9370888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override void visitGenericArrayType(GenericArrayType t) {
9380888a09821a98ac0680fad765217302858e70fa4Paul Duffin        builder.add(Types.getArrayClass(getRawType(t.getGenericComponentType())));
9390888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
9407dd252788645e940eada959bdde927426e2531c9Paul Duffin
9410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }.visit(type);
9427dd252788645e940eada959bdde927426e2531c9Paul Duffin    return builder.build();
9437dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9447dd252788645e940eada959bdde927426e2531c9Paul Duffin
9457dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
9467dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Returns the type token representing the generic type declaration of {@code cls}. For example:
9477dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@code TypeToken.getGenericType(Iterable.class)} returns {@code Iterable<T>}.
9487dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
9497dd252788645e940eada959bdde927426e2531c9Paul Duffin   * <p>If {@code cls} isn't parameterized and isn't a generic array, the type token of the class is
9507dd252788645e940eada959bdde927426e2531c9Paul Duffin   * returned.
9517dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
9520888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @VisibleForTesting static <T> TypeToken<? extends T> toGenericType(Class<T> cls) {
9537dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (cls.isArray()) {
9547dd252788645e940eada959bdde927426e2531c9Paul Duffin      Type arrayOfGenericType = Types.newArrayType(
9550888a09821a98ac0680fad765217302858e70fa4Paul Duffin          // If we are passed with int[].class, don't turn it to GenericArrayType
9567dd252788645e940eada959bdde927426e2531c9Paul Duffin          toGenericType(cls.getComponentType()).runtimeType);
9570888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @SuppressWarnings("unchecked") // array is covariant
9587dd252788645e940eada959bdde927426e2531c9Paul Duffin      TypeToken<? extends T> result = (TypeToken<? extends T>) of(arrayOfGenericType);
9597dd252788645e940eada959bdde927426e2531c9Paul Duffin      return result;
9607dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
9617dd252788645e940eada959bdde927426e2531c9Paul Duffin    TypeVariable<Class<T>>[] typeParams = cls.getTypeParameters();
9627dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (typeParams.length > 0) {
9630888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @SuppressWarnings("unchecked") // Like, it's Iterable<T> for Iterable.class
9640888a09821a98ac0680fad765217302858e70fa4Paul Duffin      TypeToken<? extends T> type = (TypeToken<? extends T>)
9650888a09821a98ac0680fad765217302858e70fa4Paul Duffin          of(Types.newParameterizedType(cls, typeParams));
9667dd252788645e940eada959bdde927426e2531c9Paul Duffin      return type;
9677dd252788645e940eada959bdde927426e2531c9Paul Duffin    } else {
9687dd252788645e940eada959bdde927426e2531c9Paul Duffin      return of(cls);
9697dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
9707dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9717dd252788645e940eada959bdde927426e2531c9Paul Duffin
9720888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private TypeToken<? super T> getSupertypeFromUpperBounds(
9730888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Class<? super T> supertype, Type[] upperBounds) {
9747dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (Type upperBound : upperBounds) {
9750888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @SuppressWarnings("unchecked") // T's upperbound is <? super T>.
9767dd252788645e940eada959bdde927426e2531c9Paul Duffin      TypeToken<? super T> bound = (TypeToken<? super T>) of(upperBound);
9777dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (of(supertype).isAssignableFrom(bound)) {
9780888a09821a98ac0680fad765217302858e70fa4Paul Duffin        @SuppressWarnings({"rawtypes", "unchecked"}) // guarded by the isAssignableFrom check.
9797dd252788645e940eada959bdde927426e2531c9Paul Duffin        TypeToken<? super T> result = bound.getSupertype((Class) supertype);
9807dd252788645e940eada959bdde927426e2531c9Paul Duffin        return result;
9817dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
9827dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
9837dd252788645e940eada959bdde927426e2531c9Paul Duffin    throw new IllegalArgumentException(supertype + " isn't a super type of " + this);
9847dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9857dd252788645e940eada959bdde927426e2531c9Paul Duffin
9867dd252788645e940eada959bdde927426e2531c9Paul Duffin  private TypeToken<? extends T> getSubtypeFromLowerBounds(Class<?> subclass, Type[] lowerBounds) {
9877dd252788645e940eada959bdde927426e2531c9Paul Duffin    for (Type lowerBound : lowerBounds) {
9880888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @SuppressWarnings("unchecked") // T's lower bound is <? extends T>
9897dd252788645e940eada959bdde927426e2531c9Paul Duffin      TypeToken<? extends T> bound = (TypeToken<? extends T>) of(lowerBound);
9907dd252788645e940eada959bdde927426e2531c9Paul Duffin      // Java supports only one lowerbound anyway.
9917dd252788645e940eada959bdde927426e2531c9Paul Duffin      return bound.getSubtype(subclass);
9927dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
9937dd252788645e940eada959bdde927426e2531c9Paul Duffin    throw new IllegalArgumentException(subclass + " isn't a subclass of " + this);
9947dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
9957dd252788645e940eada959bdde927426e2531c9Paul Duffin
9967dd252788645e940eada959bdde927426e2531c9Paul Duffin  private TypeToken<? super T> getArraySupertype(Class<? super T> supertype) {
9977dd252788645e940eada959bdde927426e2531c9Paul Duffin    // with component type, we have lost generic type information
9987dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Use raw type so that compiler allows us to call getSupertype()
9997dd252788645e940eada959bdde927426e2531c9Paul Duffin    @SuppressWarnings("rawtypes")
10000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    TypeToken componentType = checkNotNull(getComponentType(),
10010888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "%s isn't a super type of %s", supertype, this);
10027dd252788645e940eada959bdde927426e2531c9Paul Duffin    // array is covariant. component type is super type, so is the array type.
10030888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @SuppressWarnings("unchecked") // going from raw type back to generics
10047dd252788645e940eada959bdde927426e2531c9Paul Duffin    TypeToken<?> componentSupertype = componentType.getSupertype(supertype.getComponentType());
10050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @SuppressWarnings("unchecked") // component type is super type, so is array type.
10067dd252788645e940eada959bdde927426e2531c9Paul Duffin    TypeToken<? super T> result = (TypeToken<? super T>)
10070888a09821a98ac0680fad765217302858e70fa4Paul Duffin        // If we are passed with int[].class, don't turn it to GenericArrayType
10080888a09821a98ac0680fad765217302858e70fa4Paul Duffin        of(newArrayClassOrGenericArrayType(componentSupertype.runtimeType));
10097dd252788645e940eada959bdde927426e2531c9Paul Duffin    return result;
10107dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
10117dd252788645e940eada959bdde927426e2531c9Paul Duffin
10127dd252788645e940eada959bdde927426e2531c9Paul Duffin  private TypeToken<? extends T> getArraySubtype(Class<?> subclass) {
10137dd252788645e940eada959bdde927426e2531c9Paul Duffin    // array is covariant. component type is subtype, so is the array type.
10140888a09821a98ac0680fad765217302858e70fa4Paul Duffin    TypeToken<?> componentSubtype = getComponentType()
10150888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .getSubtype(subclass.getComponentType());
10160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @SuppressWarnings("unchecked") // component type is subtype, so is array type.
10177dd252788645e940eada959bdde927426e2531c9Paul Duffin    TypeToken<? extends T> result = (TypeToken<? extends T>)
10180888a09821a98ac0680fad765217302858e70fa4Paul Duffin        // If we are passed with int[].class, don't turn it to GenericArrayType
10190888a09821a98ac0680fad765217302858e70fa4Paul Duffin        of(newArrayClassOrGenericArrayType(componentSubtype.runtimeType));
10207dd252788645e940eada959bdde927426e2531c9Paul Duffin    return result;
10217dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
10227dd252788645e940eada959bdde927426e2531c9Paul Duffin
10237dd252788645e940eada959bdde927426e2531c9Paul Duffin  private Type resolveTypeArgsForSubclass(Class<?> subclass) {
10247dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (runtimeType instanceof Class) {
10257dd252788645e940eada959bdde927426e2531c9Paul Duffin      // no resolution needed
10267dd252788645e940eada959bdde927426e2531c9Paul Duffin      return subclass;
10277dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
10287dd252788645e940eada959bdde927426e2531c9Paul Duffin    // class Base<A, B> {}
10297dd252788645e940eada959bdde927426e2531c9Paul Duffin    // class Sub<X, Y> extends Base<X, Y> {}
10307dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Base<String, Integer>.subtype(Sub.class):
10317dd252788645e940eada959bdde927426e2531c9Paul Duffin
10327dd252788645e940eada959bdde927426e2531c9Paul Duffin    // Sub<X, Y>.getSupertype(Base.class) => Base<X, Y>
10337dd252788645e940eada959bdde927426e2531c9Paul Duffin    // => X=String, Y=Integer
10347dd252788645e940eada959bdde927426e2531c9Paul Duffin    // => Sub<X, Y>=Sub<String, Integer>
10357dd252788645e940eada959bdde927426e2531c9Paul Duffin    TypeToken<?> genericSubtype = toGenericType(subclass);
10360888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @SuppressWarnings({"rawtypes", "unchecked"}) // subclass isn't <? extends T>
10370888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Type supertypeWithArgsFromSubtype = genericSubtype
10380888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .getSupertype((Class) getRawType())
10390888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .runtimeType;
10400888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return new TypeResolver().where(supertypeWithArgsFromSubtype, runtimeType)
10410888a09821a98ac0680fad765217302858e70fa4Paul Duffin        .resolveType(genericSubtype.runtimeType);
10427dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
10437dd252788645e940eada959bdde927426e2531c9Paul Duffin
10447dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
10457dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Creates an array class if {@code componentType} is a class, or else, a
10467dd252788645e940eada959bdde927426e2531c9Paul Duffin   * {@link GenericArrayType}. This is what Java7 does for generic array type
10477dd252788645e940eada959bdde927426e2531c9Paul Duffin   * parameters.
10487dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
10497dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static Type newArrayClassOrGenericArrayType(Type componentType) {
10507dd252788645e940eada959bdde927426e2531c9Paul Duffin    return Types.JavaVersion.JAVA7.newArrayType(componentType);
10517dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
10527dd252788645e940eada959bdde927426e2531c9Paul Duffin
10537dd252788645e940eada959bdde927426e2531c9Paul Duffin  private static final class SimpleTypeToken<T> extends TypeToken<T> {
10547dd252788645e940eada959bdde927426e2531c9Paul Duffin
10557dd252788645e940eada959bdde927426e2531c9Paul Duffin    SimpleTypeToken(Type type) {
10567dd252788645e940eada959bdde927426e2531c9Paul Duffin      super(type);
10577dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
10587dd252788645e940eada959bdde927426e2531c9Paul Duffin
10597dd252788645e940eada959bdde927426e2531c9Paul Duffin    private static final long serialVersionUID = 0;
10607dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
10617dd252788645e940eada959bdde927426e2531c9Paul Duffin
10627dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
10637dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Collects parent types from a sub type.
10647dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
10657dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @param <K> The type "kind". Either a TypeToken, or Class.
10667dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
10677dd252788645e940eada959bdde927426e2531c9Paul Duffin  private abstract static class TypeCollector<K> {
10687dd252788645e940eada959bdde927426e2531c9Paul Duffin
10690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    static final TypeCollector<TypeToken<?>> FOR_GENERIC_TYPE =
10700888a09821a98ac0680fad765217302858e70fa4Paul Duffin        new TypeCollector<TypeToken<?>>() {
10710888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override Class<?> getRawType(TypeToken<?> type) {
10720888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return type.getRawType();
10730888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
10747dd252788645e940eada959bdde927426e2531c9Paul Duffin
10750888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override Iterable<? extends TypeToken<?>> getInterfaces(TypeToken<?> type) {
10760888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return type.getGenericInterfaces();
10770888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
10787dd252788645e940eada959bdde927426e2531c9Paul Duffin
10790888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Nullable
10800888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override TypeToken<?> getSuperclass(TypeToken<?> type) {
10810888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return type.getGenericSuperclass();
10820888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
10830888a09821a98ac0680fad765217302858e70fa4Paul Duffin        };
10847dd252788645e940eada959bdde927426e2531c9Paul Duffin
10850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    static final TypeCollector<Class<?>> FOR_RAW_TYPE =
10860888a09821a98ac0680fad765217302858e70fa4Paul Duffin        new TypeCollector<Class<?>>() {
10870888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override Class<?> getRawType(Class<?> type) {
10880888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return type;
10890888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
10907dd252788645e940eada959bdde927426e2531c9Paul Duffin
10910888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override Iterable<? extends Class<?>> getInterfaces(Class<?> type) {
10923ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin            return Arrays.asList(type.getInterfaces());
10930888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
10947dd252788645e940eada959bdde927426e2531c9Paul Duffin
10950888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Nullable
10960888a09821a98ac0680fad765217302858e70fa4Paul Duffin          @Override Class<?> getSuperclass(Class<?> type) {
10970888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return type.getSuperclass();
10980888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
10990888a09821a98ac0680fad765217302858e70fa4Paul Duffin        };
11007dd252788645e940eada959bdde927426e2531c9Paul Duffin
11017dd252788645e940eada959bdde927426e2531c9Paul Duffin    /** For just classes, we don't have to traverse interfaces. */
11027dd252788645e940eada959bdde927426e2531c9Paul Duffin    final TypeCollector<K> classesOnly() {
11037dd252788645e940eada959bdde927426e2531c9Paul Duffin      return new ForwardingTypeCollector<K>(this) {
11040888a09821a98ac0680fad765217302858e70fa4Paul Duffin        @Override Iterable<? extends K> getInterfaces(K type) {
11057dd252788645e940eada959bdde927426e2531c9Paul Duffin          return ImmutableSet.of();
11067dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
11070888a09821a98ac0680fad765217302858e70fa4Paul Duffin        @Override ImmutableList<K> collectTypes(Iterable<? extends K> types) {
11087dd252788645e940eada959bdde927426e2531c9Paul Duffin          ImmutableList.Builder<K> builder = ImmutableList.builder();
11097dd252788645e940eada959bdde927426e2531c9Paul Duffin          for (K type : types) {
11107dd252788645e940eada959bdde927426e2531c9Paul Duffin            if (!getRawType(type).isInterface()) {
11117dd252788645e940eada959bdde927426e2531c9Paul Duffin              builder.add(type);
11127dd252788645e940eada959bdde927426e2531c9Paul Duffin            }
11137dd252788645e940eada959bdde927426e2531c9Paul Duffin          }
11147dd252788645e940eada959bdde927426e2531c9Paul Duffin          return super.collectTypes(builder.build());
11157dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
11167dd252788645e940eada959bdde927426e2531c9Paul Duffin      };
11177dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
11187dd252788645e940eada959bdde927426e2531c9Paul Duffin
11197dd252788645e940eada959bdde927426e2531c9Paul Duffin    final ImmutableList<K> collectTypes(K type) {
11207dd252788645e940eada959bdde927426e2531c9Paul Duffin      return collectTypes(ImmutableList.of(type));
11217dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
11227dd252788645e940eada959bdde927426e2531c9Paul Duffin
11237dd252788645e940eada959bdde927426e2531c9Paul Duffin    ImmutableList<K> collectTypes(Iterable<? extends K> types) {
11247dd252788645e940eada959bdde927426e2531c9Paul Duffin      // type -> order number. 1 for Object, 2 for anything directly below, so on so forth.
11257dd252788645e940eada959bdde927426e2531c9Paul Duffin      Map<K, Integer> map = Maps.newHashMap();
11267dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (K type : types) {
11277dd252788645e940eada959bdde927426e2531c9Paul Duffin        collectTypes(type, map);
11287dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
11297dd252788645e940eada959bdde927426e2531c9Paul Duffin      return sortKeysByValue(map, Ordering.natural().reverse());
11307dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
11317dd252788645e940eada959bdde927426e2531c9Paul Duffin
11327dd252788645e940eada959bdde927426e2531c9Paul Duffin    /** Collects all types to map, and returns the total depth from T up to Object. */
11337dd252788645e940eada959bdde927426e2531c9Paul Duffin    private int collectTypes(K type, Map<? super K, Integer> map) {
11347dd252788645e940eada959bdde927426e2531c9Paul Duffin      Integer existing = map.get(this);
11357dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (existing != null) {
11367dd252788645e940eada959bdde927426e2531c9Paul Duffin        // short circuit: if set contains type it already contains its supertypes
11377dd252788645e940eada959bdde927426e2531c9Paul Duffin        return existing;
11387dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
11390888a09821a98ac0680fad765217302858e70fa4Paul Duffin      int aboveMe = getRawType(type).isInterface()
11400888a09821a98ac0680fad765217302858e70fa4Paul Duffin          ? 1 // interfaces should be listed before Object
11417dd252788645e940eada959bdde927426e2531c9Paul Duffin          : 0;
11427dd252788645e940eada959bdde927426e2531c9Paul Duffin      for (K interfaceType : getInterfaces(type)) {
11437dd252788645e940eada959bdde927426e2531c9Paul Duffin        aboveMe = Math.max(aboveMe, collectTypes(interfaceType, map));
11447dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
11457dd252788645e940eada959bdde927426e2531c9Paul Duffin      K superclass = getSuperclass(type);
11467dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (superclass != null) {
11477dd252788645e940eada959bdde927426e2531c9Paul Duffin        aboveMe = Math.max(aboveMe, collectTypes(superclass, map));
11487dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
11497dd252788645e940eada959bdde927426e2531c9Paul Duffin      /*
11507dd252788645e940eada959bdde927426e2531c9Paul Duffin       * TODO(benyu): should we include Object for interface?
11517dd252788645e940eada959bdde927426e2531c9Paul Duffin       * Also, CharSequence[] and Object[] for String[]?
11527dd252788645e940eada959bdde927426e2531c9Paul Duffin       *
11537dd252788645e940eada959bdde927426e2531c9Paul Duffin       */
11547dd252788645e940eada959bdde927426e2531c9Paul Duffin      map.put(type, aboveMe + 1);
11557dd252788645e940eada959bdde927426e2531c9Paul Duffin      return aboveMe + 1;
11567dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
11577dd252788645e940eada959bdde927426e2531c9Paul Duffin
11580888a09821a98ac0680fad765217302858e70fa4Paul Duffin    private static <K, V> ImmutableList<K> sortKeysByValue(
11590888a09821a98ac0680fad765217302858e70fa4Paul Duffin        final Map<K, V> map, final Comparator<? super V> valueComparator) {
11607dd252788645e940eada959bdde927426e2531c9Paul Duffin      Ordering<K> keyOrdering = new Ordering<K>() {
11610888a09821a98ac0680fad765217302858e70fa4Paul Duffin        @Override public int compare(K left, K right) {
11627dd252788645e940eada959bdde927426e2531c9Paul Duffin          return valueComparator.compare(map.get(left), map.get(right));
11637dd252788645e940eada959bdde927426e2531c9Paul Duffin        }
11647dd252788645e940eada959bdde927426e2531c9Paul Duffin      };
11657dd252788645e940eada959bdde927426e2531c9Paul Duffin      return keyOrdering.immutableSortedCopy(map.keySet());
11667dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
11677dd252788645e940eada959bdde927426e2531c9Paul Duffin
11687dd252788645e940eada959bdde927426e2531c9Paul Duffin    abstract Class<?> getRawType(K type);
11697dd252788645e940eada959bdde927426e2531c9Paul Duffin    abstract Iterable<? extends K> getInterfaces(K type);
11700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Nullable abstract K getSuperclass(K type);
11717dd252788645e940eada959bdde927426e2531c9Paul Duffin
11727dd252788645e940eada959bdde927426e2531c9Paul Duffin    private static class ForwardingTypeCollector<K> extends TypeCollector<K> {
11737dd252788645e940eada959bdde927426e2531c9Paul Duffin
11747dd252788645e940eada959bdde927426e2531c9Paul Duffin      private final TypeCollector<K> delegate;
11757dd252788645e940eada959bdde927426e2531c9Paul Duffin
11767dd252788645e940eada959bdde927426e2531c9Paul Duffin      ForwardingTypeCollector(TypeCollector<K> delegate) {
11777dd252788645e940eada959bdde927426e2531c9Paul Duffin        this.delegate = delegate;
11787dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
11797dd252788645e940eada959bdde927426e2531c9Paul Duffin
11800888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override Class<?> getRawType(K type) {
11817dd252788645e940eada959bdde927426e2531c9Paul Duffin        return delegate.getRawType(type);
11827dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
11837dd252788645e940eada959bdde927426e2531c9Paul Duffin
11840888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override Iterable<? extends K> getInterfaces(K type) {
11857dd252788645e940eada959bdde927426e2531c9Paul Duffin        return delegate.getInterfaces(type);
11867dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
11877dd252788645e940eada959bdde927426e2531c9Paul Duffin
11880888a09821a98ac0680fad765217302858e70fa4Paul Duffin      @Override K getSuperclass(K type) {
11897dd252788645e940eada959bdde927426e2531c9Paul Duffin        return delegate.getSuperclass(type);
11907dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
11917dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
11927dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
11937dd252788645e940eada959bdde927426e2531c9Paul Duffin}
1194