Substitutes a free type variable with an actual type. See {@link GenericType this class's
javadoc} for an example.
192794
@NonNull
  public final <X> GenericType<T> where(
      @NonNull GenericTypeParameter<X> freeVariable, @NonNull Class<X> actualType) {
    return where(freeVariable, GenericType.of(actualType));
  }
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);
        }
    }
34508
@SuppressWarnings({"PMD.AvoidProtectedMethodInFinalClassNotExtending",
            "PMD.CyclomaticComplexity",
            "checkstyle:CyclomaticComplexity"})
    protected static Type resolveTypeVariables(final Type type,
                                               final Map<String, Type> generics,
                                               final boolean countPreservedVariables) {
        Type resolvedGenericType = null;
        if (type instanceof TypeVariable) {
            // simple named generics resolved to target types
            resolvedGenericType = declaredGeneric((TypeVariable) type, generics);
        } else if (type instanceof ExplicitTypeVariable) {
            // special type used to preserve named generic (and differentiate from type variable)
            resolvedGenericType = declaredGeneric((ExplicitTypeVariable) type, generics, countPreservedVariables);
        } else if (type instanceof Class) {
            resolvedGenericType = type;
        } else if (type instanceof ParameterizedType) {
            // here parameterized type could shrink to class (if it has no arguments and owner class)
            resolvedGenericType = resolveParameterizedTypeVariables(
                    (ParameterizedType) type, generics, countPreservedVariables);
        } else if (type instanceof GenericArrayType) {
            // here generic array could shrink to array class (if component type shrink to simple class)
            resolvedGenericType = resolveGenericArrayTypeVariables(
                    (GenericArrayType) type, generics, countPreservedVariables);
        } else if (type instanceof WildcardType) {
            // here wildcard could shrink to upper type (if it has only one upper type)
            resolvedGenericType = resolveWildcardTypeVariables(
                    (WildcardType) type, generics, countPreservedVariables);
        }
        return resolvedGenericType;
    }
764417
public static Class<?> getListInnerClassFromGenericType(Type genericType) {
        ParameterizedType innerClass = (ParameterizedType) genericType;
        return (Class<?>) innerClass.getActualTypeArguments()[0];
    }
909355
private static Type fix(Type t) {
        if(!(t instanceof GenericArrayType))
            return t;

        GenericArrayType gat = (GenericArrayType) t;
        if(gat.getGenericComponentType() instanceof Class) {
            Class c = (Class) gat.getGenericComponentType();
            return Array.newInstance(c,0).getClass();
        }

        return t;
    }
967902
public static ParameterizedType newParameterizedType(
      final Class<?> raw, Iterable<? extends Type> typeArgs) {
    TypeResolver resolver = new TypeResolver();
    final List<TypeVariable<?>> vars = new ArrayList<TypeVariable<?>>();
    for (Type arg : typeArgs) {
      TypeVariable<?> var = TypeVariableGenerator.freshTypeVariable("T" + vars.size());
      vars.add(var);
      resolver = resolver.where(var, arg);
    }
    checkArgument(raw.getTypeParameters().length == vars.size(),
        "%s expected %s type parameters, while %s are provied",
        raw, raw.getTypeParameters().length, typeArgs);
    return (ParameterizedType) resolver.resolveType(new ParameterizedType() {
      @Override public Class<?> getRawType() { return raw; }
      @Override public Type getOwnerType() { return null; }
      @Override public Type[] getActualTypeArguments() { return vars.toArray(new Type[0]); }
    });
  }
1188892
static String actualTypeParametersString(TypeElement type) {
    List<? extends TypeParameterElement> typeParameters = type.getTypeParameters();
    if (typeParameters.isEmpty()) {
      return "";
    } else {
      return typeParameters
          .stream()
          .map(e -> e.getSimpleName().toString())
          .collect(joining(", ", "<", ">"));
    }
  }
915927
public <T> T convert(Object value, Class<T> type) {
		return converter.convert(value, type);
	}
1196021
@Override
    public GenericsContext type(final Class<?> type) {
        return type == currentType ? this : new GenericsContext(genericsInfo, type, root);
    }
57457
@SuppressWarnings("unchecked")
    public static <T extends Type> T unwrap(T type) {
        Type unwrapped = type;
        while (unwrapped instanceof SerializableTypeProxy) {
            unwrapped = ((SerializableTypeProxy) type).getTypeProvider().getType();
        }
        return (T) unwrapped;
    }
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));
    }
1257629
public static Type getSuperType(Type type) {
        if (type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            Type genericSuperClass = ((Class<?>) parameterizedType.getRawType()).getGenericSuperclass();
            if (genericSuperClass instanceof ParameterizedType) {
                /*
                 * Find erased generic types for the super class and replace
                 * with actual type arguments from the parameterized type
                 */
                Type[] superTypeArguments = getTypeArguments(genericSuperClass);
                List<Type> typeParameters = Arrays.asList(((Class<?>) parameterizedType.getRawType()).getTypeParameters());
                int j = 0;
                for (int i = 0; i != superTypeArguments.length; i++) {
                    if (typeParameters.contains(superTypeArguments[i])) {
                        superTypeArguments[i] = parameterizedType.getActualTypeArguments()[j++];
                    }
                }
                return new ParameterizedType() {
                    @Override
                    public Type[] getActualTypeArguments() {
                        return superTypeArguments;
                    }

                    @Override
                    public Type getRawType() {
                        return ((ParameterizedType) genericSuperClass).getRawType();
                    }

                    @Override
                    public Type getOwnerType() {
                        return null;
                    }
                };
            } else {
                return genericSuperClass;
            }
        } else {
            return ((Class<?>) type).getGenericSuperclass();
        }
    }
848548
@Override
    public <T extends ImmutableTerm> Optional<ImmutableSubstitution<T>> applyToSubstitution(
            ImmutableSubstitution<T> substitution) {

        if (isEmpty()) {
            return Optional.of(substitution);
        }

        try {
            ImmutableMap<Variable, T> newMap = ImmutableMap.copyOf(substitution.getImmutableMap().entrySet().stream()
                    .map(e -> new AbstractMap.SimpleEntry<>(applyToVariable(e.getKey()), applyToTerm(e.getValue())))
                    .distinct()
                    .filter(e -> ! e.getKey().equals(e.getValue()))
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                            (e1, e2) -> {
                                throw new NotASubstitutionException();
                            })));
            return Optional.of(substitutionFactory.getSubstitution(newMap));
        } catch (NotASubstitutionException e) {
            return Optional.empty();
        }
    }
1068118
public static TypeVariableName get(java.lang.reflect.TypeVariable<?> type) {
    return get(type, new LinkedHashMap<>());
  }
320321
private String genericTypeAsString(GenericsType genericsType, boolean showRedirect) {
        String ret = genericsType.getName();
        if (genericsType.getUpperBounds() != null) {
            ret += " extends ";
            for (int i = 0; i < genericsType.getUpperBounds().length; i++) {
                ClassNode classNode = genericsType.getUpperBounds()[i];
                if (classNode.equals(this)) {
                    ret += classNode.getName();
                } else {
                    ret += classNode.toString(showRedirect);
                }
                if (i + 1 < genericsType.getUpperBounds().length) ret += " & ";
            }
        } else if (genericsType.getLowerBound() !=null) {
            ClassNode classNode = genericsType.getLowerBound();
            if (classNode.equals(this)) {
                ret += " super " + classNode.getName();
            } else {
                ret += " super " + classNode;
            }
        }
        return ret;
    }
709121
private static Optional<Class> resolveSingleTypeArgument(Type genericType) {
        if (genericType instanceof ParameterizedType) {
            ParameterizedType pt = (ParameterizedType) genericType;
            Type[] actualTypeArguments = pt.getActualTypeArguments();
            if (actualTypeArguments.length == 1) {
                Type actualTypeArgument = actualTypeArguments[0];
                return resolveParameterizedTypeArgument(actualTypeArgument);
            }
        }
        return Optional.empty();
    }
821454
private void writeSimple(Class<?> declaredType, Object value) throws IOException {
        Class<?> realType = value.getClass();
        if (realType == Integer.class) {
            output.writeInt(((Integer) value).intValue());
        } else if (realType == Long.class) {
            output.writeLong(((Long) value).longValue());
        } else if (realType == Short.class) {
            output.writeInt(((Short) value).shortValue());
        } else if (realType == Byte.class) {
            output.writeInt(((Byte) value).byteValue());
        } else if (realType == Float.class) {
            float flt = ((Float) value).floatValue();
            if (Float.isNaN(flt)) {
                // write as string
                output.writeNull();
            } else if (Float.isInfinite(flt)) {
                // write as string
                output.writeString(Float.toString(flt));
            } else {
                output.writeFloat(flt);
            }
        } else if (realType == Double.class) {
            double dbl = ((Double) value).doubleValue();
            if (Double.isNaN(dbl)) {
                // write as string
                output.writeNull();
            } else if (Double.isInfinite(dbl)) {
                // write as string
                output.writeString(Double.toString(dbl));
            } else {
                output.writeDouble(dbl);
            }
        } else if (realType == Boolean.class) {
            output.writeBoolean(((Boolean) value).booleanValue());
        } 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);
                }
                output.writeString(converted);
            } catch (RuntimeException ex) {
                throw new IllegalArgumentException(
                        "Unable to convert type " + declaredType.getName() + " for real type: " + realType.getName(), ex);
            }
        }
    }