code: public static Map<TypeVariable, Type> getTypeVariableMap(Class<?> clazz) {
  		Map<TypeVariable, Type> typeVariableMap = typeVariableCache.get(clazz);
  
  		if (typeVariableMap == null) {
  			typeVariableMap = new HashMap<TypeVariable, Type>();
  
  			// interfaces
  			extractTypeVariablesFromGenericInterfaces(clazz.getGenericInterfaces(), typeVariableMap);
  
  			try {
  				// super class
  				Class<?> type = clazz;
  				while (type.getSuperclass() != null && !Object.class.equals(type.getSuperclass())) {
  					Type genericType = type.getGenericSuperclass();
  					if (genericType instanceof ParameterizedType) {
  						ParameterizedType pt = (ParameterizedType) genericType;
  						populateTypeMapFromParameterizedType(pt, typeVariableMap);
  					}
  					extractTypeVariablesFromGenericInterfaces(type.getSuperclass().getGenericInterfaces(), typeVariableMap);
  					type = type.getSuperclass();
  				}
  			}
  			catch (MalformedParameterizedTypeException ex) {
  				// from getGenericSuperclass() - ignore and continue with member class check
  			}
  
  			try {
  				// enclosing class
  				Class<?> type = clazz;
  				while (type.isMemberClass()) {
  					Type genericType = type.getGenericSuperclass();
  					if (genericType instanceof ParameterizedType) {
  						ParameterizedType pt = (ParameterizedType) genericType;
  						populateTypeMapFromParameterizedType(pt, typeVariableMap);
  					}
  					type = type.getEnclosingClass();
  				}
  			}
  			catch (MalformedParameterizedTypeException ex) {
  				// from getGenericSuperclass() - ignore and preserve previously accumulated type variables
  			}
  
  			typeVariableCache.put(clazz, typeVariableMap);
  		}
  
  		return typeVariableMap;
  	}
docs: Build a mapping of {@link TypeVariable#getName TypeVariable names} to
  {@link Class concrete classes} for the specified {@link Class}. Searches
  all super types, enclosing types and interfaces.