code: private static final Class<?> getRootType(Map<String, Class<?>> types,
                                                Type type) {
          
          // if type explicitly defined, pass thru as is
          if (type instanceof Class) {
              return (Class<?>) type;
          }
          
          // if type defined as parameter, pass thru root type
          else if (type instanceof ParameterizedType) {
              Type raw = ((ParameterizedType) type).getRawType();
              return getRootType(types, raw);
          }
          
          // if type defined as wildcard, pass thru bounds
          // NOTE: this does not support ? super X format
          else if (type instanceof WildcardType) {
              Type[] bounds = ((WildcardType) type).getUpperBounds();
              if (bounds.length >= 1) {
                  return getRootType(types, bounds[0]);
              }
          }
          
          // otherwise, either generic array or plain type variable
          // lookup in types and return specified type if provided
          else {
              TypeVariable<?> raw = getTypeVariable(type);
              if (raw != null) {
                  // verify type is overridden
                  String name = raw.getName();
                  if (types.containsKey(name)) {
                      // get actual type and convert to array if necessary
                      Class<?> actual = types.get(name);
                      int dimensions = getDimensions(type);
                      if (dimensions >= 1) {
                          actual = Array.newInstance
                          (
                              actual, dimensions
                          ).getClass();
                      }
                      
                      return actual;
                  }
              }
          }
          
          // nothing found
          return null;
      }
docs: Get the root class type based on the given type and set of named type
  variables.  If the type is already a Class, it is renamed as is.  If the
  type is a parameterized type, then the raw type is returned.  If the
  type is a wildcard, the lower bounds is returned.  Otherwise, if the
  type is a type variable, its associated value from the types is returned.
  
  @param types  The named type variales to pass thru
  @param type  The associated type
  
  @return  The underlying root class for the type