docs: private static Type materializeTypeVariable(ArrayList<Type> typeHierarchy, TypeVariable<?> typeVar) {
  		TypeVariable<?> inTypeTypeVar = typeVar;
  		// iterate thru hierarchy from top to bottom until type variable gets a class assigned
  		for (int i = typeHierarchy.size() - 1; i >= 0; i--) {
  			Type curT = typeHierarchy.get(i);
  
  			// parameterized type
  			if (curT instanceof ParameterizedType) {
  				Class<?> rawType = ((Class<?>) ((ParameterizedType) curT).getRawType());
  
  				for (int paramIndex = 0; paramIndex < rawType.getTypeParameters().length; paramIndex++) {
  
  					TypeVariable<?> curVarOfCurT = rawType.getTypeParameters()[paramIndex];
  
  					// check if variable names match
  					if (sameTypeVars(curVarOfCurT, inTypeTypeVar)) {
  						Type curVarType = ((ParameterizedType) curT).getActualTypeArguments()[paramIndex];
  
  						// another type variable level
  						if (curVarType instanceof TypeVariable<?>) {
  							inTypeTypeVar = (TypeVariable<?>) curVarType;
  						}
  						// class
  						else {
  							return curVarType;
  						}
  					}
  				}
  			}
  		}
  		// can not be materialized, most likely due to type erasure
  		// return the type variable of the deepest level
  		return inTypeTypeVar;
  	}