[LANG-775] [LANG-776] fix related bugs dealing with type variable inheritance

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1203429 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java b/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java
index bf4942f..8db8abf 100644
--- a/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java
+++ b/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java
@@ -216,9 +216,9 @@
                 toClass, typeVarAssigns);
 
         // now to check each type argument
-        for (Map.Entry<TypeVariable<?>, Type> entry : toTypeVarAssigns.entrySet()) {
-            Type toTypeArg = entry.getValue();
-            Type fromTypeArg = fromTypeVarAssigns.get(entry.getKey());
+        for (TypeVariable<?> var : toTypeVarAssigns.keySet()) {
+            Type toTypeArg = unrollVariableAssignments(var, toTypeVarAssigns);
+            Type fromTypeArg = unrollVariableAssignments(var, fromTypeVarAssigns);
 
             // parameters must either be absent from the subject type, within
             // the bounds of the wildcard type, or be an exact match to the
@@ -234,6 +234,19 @@
         return true;
     }
 
+    private static Type unrollVariableAssignments(TypeVariable<?> var, Map<TypeVariable<?>, Type> typeVarAssigns) {
+        Type result;
+        do {
+            result = typeVarAssigns.get(var);
+            if (result instanceof TypeVariable<?> && !result.equals(var)) {
+                var = (TypeVariable<?>) result;
+                continue;
+            }
+            break;
+        } while (true);
+        return result;
+    }
+
     /**
      * <p> Checks if the subject type may be implicitly cast to the target
      * generic array type following the Java generics rules. </p>
@@ -658,8 +671,8 @@
         HashMap<TypeVariable<?>, Type> typeVarAssigns = subtypeVarAssigns == null ? new HashMap<TypeVariable<?>, Type>()
                 : new HashMap<TypeVariable<?>, Type>(subtypeVarAssigns);
 
-        // no arguments for the parameters, or target class has been reached
-        if (cls.getTypeParameters().length > 0 || toClass.equals(cls)) {
+        // has target class been reached?
+        if (toClass.equals(cls)) {
             return typeVarAssigns;
         }