jetbrick-commons/src/main/java/jetbrick/reflect/TypeResolverUtils.java
public static Type resolveVariable(TypeVariable<?> variable, Class<?> implClass) {
        Class<?> rawType = getRawType(implClass, null);

        int index = ArrayUtils.indexOf(rawType.getTypeParameters(), variable);
        if (index >= 0) {
            return variable;
        }

        Class<?>[] interfaces = rawType.getInterfaces();
        Type[] genericInterfaces = rawType.getGenericInterfaces();

        for (int i = 0; i <= interfaces.length; i++) {
            Class<?> rawInterface;
            if (i < interfaces.length) {
                rawInterface = interfaces[i];
            } else {
                rawInterface = rawType.getSuperclass();
                if (rawInterface == null) {
                    continue;
                }
            }
            Type resolved = resolveVariable(variable, rawInterface);
            if (resolved instanceof Class || resolved instanceof ParameterizedType) {
                return resolved;
            }

            if (resolved instanceof TypeVariable) {
                TypeVariable<?> typeVariable = (TypeVariable<?>) resolved;
                index = ArrayUtils.indexOf(rawInterface.getTypeParameters(), typeVariable);
                if (index < 0) {
                    throw new IllegalArgumentException("Can't resolve type variable:" + typeVariable);
                }
                Type type = i < genericInterfaces.length ? genericInterfaces[i] : rawType.getGenericSuperclass();
                if (type instanceof Class) {
                    return Object.class;
                }
                if (type instanceof ParameterizedType) {
                    return ((ParameterizedType) type).getActualTypeArguments()[index];
                }
                throw new IllegalArgumentException("Unsupported type: " + type);
            }
        }
        return null;
    }
public static Type resolveVariable(TypeVariable<?> variable, Class<?> implClass) {
        Class<?> rawType = getRawType(implClass, null);

        int index = ArrayUtils.indexOf(rawType.getTypeParameters(), variable);
        if (index >= 0) {
            return variable;
        }

        Class<?>[] interfaces = rawType.getInterfaces();
        Type[] genericInterfaces = rawType.getGenericInterfaces();

        for (int i = 0; i <= interfaces.length; i++) {
            Class<?> rawInterface;
            if (i < interfaces.length) {
                rawInterface = interfaces[i];
            } else {
                rawInterface = rawType.getSuperclass();
                if (rawInterface == null) {
                    continue;
                }
            }
            Type resolved = resolveVariable(variable, rawInterface);
            if (resolved instanceof Class || resolved instanceof ParameterizedType) {
                return resolved;
            }

            if (resolved instanceof TypeVariable) {
                TypeVariable<?> typeVariable = (TypeVariable<?>) resolved;
                index = ArrayUtils.indexOf(rawInterface.getTypeParameters(), typeVariable);
                if (index < 0) {
                    throw new IllegalArgumentException("Can't resolve type variable:" + typeVariable);
                }
                Type type = i < genericInterfaces.length ? genericInterfaces[i] : rawType.getGenericSuperclass();
                if (type instanceof Class) {
                    return Object.class;
                }
                if (type instanceof ParameterizedType) {
                    return ((ParameterizedType) type).getActualTypeArguments()[index];
                }
                throw new IllegalArgumentException("Unsupported type: " + type);
            }
        }
        return null;
    }
Resolves <code>TypeVariable</code> with given implementation class.

@param variable - variable
@param implClass - implementation class
@return resolved type