Substitutes a free type variable with an actual type. See {@link GenericType this class's
javadoc} for an example.
1167
@NonNull
  public final <X> GenericType<T> where(
      @NonNull GenericTypeParameter<X> freeVariable, @NonNull GenericType<X> actualType) {
    TypeResolver resolver =
        new TypeResolver().where(freeVariable.getTypeVariable(), actualType.__getToken().getType());
    Type resolvedType = resolver.resolveType(this.token.getType());
    @SuppressWarnings("unchecked")
    TypeToken<T> resolvedToken = (TypeToken<T>) TypeToken.of(resolvedType);
    return new GenericType<>(resolvedToken);
  }
380467
public static TypeVariableConstraint withVariadicBound(String name, String variadicBound)
    {
        return new TypeVariableConstraint(name, false, false, variadicBound);
    }
384962
public static String getVariableType(String type) throws IOException {
        if (getVariableTypes() != null) {
            String newType = getVariableTypes().get(type);
            if (newType != null)
                return newType;
        }
        return type;
    }
517720
void writeSimple(Class<?> declaredType, Object value) throws IOException {
        // simple types have no need to write a type object
        Class<?> realType = value.getClass();
        if (realType == Integer.class) {
            output.writeInt(((Integer) value).intValue());
            return;
        } else if (realType == Double.class) {
            output.writeDouble(((Double) value).doubleValue());
            return;
        } else if (realType == Float.class) {
            output.writeFloat(((Float) value).floatValue());
            return;
        } else if (realType == Boolean.class) {
            output.writeBoolean(((Boolean) value).booleanValue());
            return;
        }

        // handle no declared type and subclasses
        Class<?> effectiveType = getAndSerializeEffectiveTypeIfRequired(value, declaredType);

        // long/short/byte only processed now to ensure that a distinction can be made between Integer and Long
        if (realType == Long.class) {
            output.writeLong(((Long) value).longValue());
            return;
        } else if (realType == Short.class) {
            output.writeInt(((Short) value).shortValue());
            return;
        } else if (realType == Byte.class) {
            output.writeInt(((Byte) value).byteValue());
            return;
        } else if (realType == byte[].class) {
            output.writeBytes((byte[]) value);
            return;
        }

        // write as a string
        try {
            writeObjectAsString(value, effectiveType);
        } catch (RuntimeException ex) {
            throw new IllegalArgumentException("Unable to convert type " + effectiveType.getName() + " declared as " + declaredType.getName(), ex);
        }
    }
308232
protected DeclaredType resolveTypeVariable(Element element, TypeVariable typeVariable) {
        Element enclosing = element.getEnclosingElement();

        while (enclosing instanceof Parameterizable) {
            Parameterizable parameterizable = (Parameterizable) enclosing;
            String name = typeVariable.toString();
            for (TypeParameterElement typeParameter : parameterizable.getTypeParameters()) {
                if (name.equals(typeParameter.toString())) {
                    List<? extends TypeMirror> bounds = typeParameter.getBounds();
                    if (bounds.size() == 1) {
                        TypeMirror typeMirror = bounds.get(0);
                        if (typeMirror.getKind() == TypeKind.DECLARED) {
                            return (DeclaredType) typeMirror;
                        }
                    }
                }
            }
            enclosing = enclosing.getEnclosingElement();
        }
        return null;
    }
915927
public <T> T convert(Object value, Class<T> type) {
		return converter.convert(value, type);
	}
140368
private ImmutableList<UTypeVar> freeTypeVars(Unifier unifier) {
    ImmutableList.Builder<UTypeVar> builder = ImmutableList.builder();
    for (UTypeVar var : typeVariables(unifier.getContext())) {
      if (unifier.getBinding(var.key()) == null) {
        builder.add(var);
      }
    }
    return builder.build();
  }
1366408
final List<Type> freeVarsIn(Type t) {
        ListBuffer<Type> buf = new ListBuffer<>();
        for (Type iv : inferenceVars()) {
            if (t.contains(iv)) {
                buf.add(iv);
            }
        }
        return buf.toList();
    }
23622
private static String getGenericTypeData(Type genericType) {
    List<String> types = Lists.newArrayList();
    if (genericType != null && genericType instanceof ParameterizedType) {
      for (Type t : ((ParameterizedType) genericType).getActualTypeArguments()) {
        if (t instanceof ParameterizedType) {
          String nestedGeneric = ((Class<?>) ((ParameterizedType) t).getRawType()).getSimpleName();
          nestedGeneric += getGenericTypeData(t);
          types.add(nestedGeneric);
        } else {
          types.add(((Class<?>) t).getSimpleName());
        }
      }
    }
    return (types.size() > 0) ? "<" + Joiner.on(", ").join(types) + ">" : "";
  }
1025402
private Map<String, JSType> buildTypeVariables(
      Map<TemplateType, JSType> inferredTypes) {
    Map<String, JSType> typeVars = new LinkedHashMap<>();
    for (Entry<TemplateType, JSType> e : inferredTypes.entrySet()) {
      // Only add the template type that do not have a type transformation
      if (!e.getKey().isTypeTransformation()) {
        typeVars.put(e.getKey().getReferenceName(), e.getValue());
      }
    }
    return typeVars;
  }
900419
public static Type unrollVariables(Map<TypeVariable<?>, Type> typeArguments, final Type type) {
        if (typeArguments == null) {
            typeArguments = Collections.emptyMap();
        }
        if (containsTypeVariables(type)) {
            if (type instanceof TypeVariable<?>) {
                return unrollVariables(typeArguments, typeArguments.get(type));
            }
            if (type instanceof ParameterizedType) {
                final ParameterizedType p = (ParameterizedType) type;
                final Map<TypeVariable<?>, Type> parameterizedTypeArguments;
                if (p.getOwnerType() == null) {
                    parameterizedTypeArguments = typeArguments;
                } else {
                    parameterizedTypeArguments = new HashMap<>(typeArguments);
                    parameterizedTypeArguments.putAll(TypeUtils.getTypeArguments(p));
                }
                final Type[] args = p.getActualTypeArguments();
                for (int i = 0; i < args.length; i++) {
                    final Type unrolled = unrollVariables(parameterizedTypeArguments, args[i]);
                    if (unrolled != null) {
                        args[i] = unrolled;
                    }
                }
                return parameterizeWithOwner(p.getOwnerType(), (Class<?>) p.getRawType(), args);
            }
            if (type instanceof WildcardType) {
                final WildcardType wild = (WildcardType) type;
                return wildcardType().withUpperBounds(unrollBounds(typeArguments, wild.getUpperBounds()))
                    .withLowerBounds(unrollBounds(typeArguments, wild.getLowerBounds())).build();
            }
        }
        return type;
    }
242598
public static Type resolveAt(Object o, TypeVariable<?> var) {
        Validate.notNull(var, "no variable to read");
        final GenericDeclaration genericDeclaration = var.getGenericDeclaration();
        Validate.isInstanceOf(Class.class, genericDeclaration, "%s is not declared by a Class",
            TypeUtils.toLongString(var));
        return resolveAt(o, var, TypeUtils.getTypeArguments(o.getClass(), (Class<?>) genericDeclaration));
    }
554838
public Formula substitute(final Variable variable, final Formula formula) {
        final Substitution subst = new Substitution();
        subst.addMapping(variable, formula);
        return this.substitute(subst);
    }
668243
private static boolean containsTypeVariables(final Type type) {
        if (type instanceof TypeVariable<?>) {
            return true;
        }
        if (type instanceof Class<?>) {
            return ((Class<?>) type).getTypeParameters().length > 0;
        }
        if (type instanceof ParameterizedType) {
            for (final Type arg : ((ParameterizedType) type).getActualTypeArguments()) {
                if (containsTypeVariables(arg)) {
                    return true;
                }
            }
            return false;
        }
        if (type instanceof WildcardType) {
            final WildcardType wild = (WildcardType) type;
            return containsTypeVariables(TypeUtils.getImplicitLowerBounds(wild)[0])
                    || containsTypeVariables(TypeUtils.getImplicitUpperBounds(wild)[0]);
        }
        return false;
    }
1342349
public static Class<?>[] getActualClass(Type genericType) {

        if (genericType instanceof ParameterizedType) {

            Type[] actualTypes = ((ParameterizedType) genericType).getActualTypeArguments();
            Class<?>[] actualClasses = new Class<?>[actualTypes.length];

            int i = 0;
            while (i < actualTypes.length) {
                Type actualType = actualTypes[i];
                if (actualType instanceof Class<?>) {
                    actualClasses[i] = (Class<?>) actualType;
                } else if (actualType instanceof GenericArrayType) {
                    Type componentType = ((GenericArrayType) actualType).getGenericComponentType();
                    actualClasses[i] = Array.newInstance((Class<?>) componentType, 0).getClass();
                }
                i++;
            }

            return actualClasses;
        }

        return EMPTY_CLASSES;
    }
180314
private Object writeSimple(Class<?> declaredType, Object value) {
        Class<?> realType = value.getClass();
        if (realType == Integer.class || realType == Long.class || realType == Short.class ||
                realType == Byte.class || realType == Float.class || realType == Double.class ||
                realType == Boolean.class) {
            return value;
        } else {
            // write as a string
            try {
                String converted = settings.getConverter().convertToString(realType, value);
                if (converted == null) {
                    throw new IllegalArgumentException("Unable to write because converter returned a null string: " + value);
                }
                return converted;
            } catch (RuntimeException ex) {
                throw new IllegalArgumentException(
                        "Unable to convert type " + declaredType.getName() + " for real type: " + realType.getName(), ex);
            }
        }
    }
341879
void addVar(TypeVar t) {
        this.undetvars = this.undetvars.prepend(infer.fromTypeVarFun.apply(t));
        this.inferencevars = this.inferencevars.prepend(t);
    }