code: public static <T> Class<?> getTypeArgument(final Class<? extends T> clazz, final TypeVariable<? extends GenericDeclaration> tv) {
          final Map<Type, Type> resolvedTypes = new HashMap<Type, Type>();
          Type type = clazz;
          // start walking up the inheritance hierarchy until we hit the end
          while (type != null && !Object.class.equals(getClass(type))) {
              if (type instanceof Class) {
                  // there is no useful information for us in raw types, so just
                  // keep going.
                  type = ((Class) type).getGenericSuperclass();
              } else {
                  final ParameterizedType parameterizedType = (ParameterizedType) type;
                  final Class<?> rawType = (Class) parameterizedType.getRawType();
  
                  final Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                  final TypeVariable<?>[] typeParameters = rawType.getTypeParameters();
                  for (int i = 0; i < actualTypeArguments.length; i++) {
                      if (typeParameters[i].equals(tv)) {
                          final Class cls = getClass(actualTypeArguments[i]);
                          if (cls != null) {
                              return cls;
                          }
                          //We don't know that the type we want is the one in the map, if this argument has been
                          //passed through multiple levels of the hierarchy.  Walk back until we run out.
                          Type typeToTest = resolvedTypes.get(actualTypeArguments[i]);
                          while (typeToTest != null) {
                              final Class classToTest = getClass(typeToTest);
                              if (classToTest != null) {
                                  return classToTest;
                              }
                              typeToTest = resolvedTypes.get(typeToTest);
                          }
                      }
                      resolvedTypes.put(typeParameters[i], actualTypeArguments[i]);
                  }
  
                  if (!rawType.equals(Object.class)) {
                      type = rawType.getGenericSuperclass();
                  }
              }
          }
  
          return null;
      }
docs: Returns the type argument
  
  @param clazz the Class to examine
  @param tv    the TypeVariable to look for
  @param <T>   the type of the Class
  @return the Class type