protected static HierarchicType _findSuperInterfaceChain(Type currentType, Class<?> target) {
   HierarchicType current = new HierarchicType(currentType);
   Class<?> raw = current.getRawClass();
   if (raw == target) {
     return current;
   }
   // Otherwise, keep on going down the rat hole; first implemented interaces
   Type[] parents = raw.getGenericInterfaces();
   // as long as there are superclasses
   // and unless we have already seen the type (<T extends X<T>>)
   if (parents != null) {
     for (Type parent : parents) {
       HierarchicType sup = _findSuperInterfaceChain(parent, target);
       if (sup != null) {
         sup.setSubType(current);
         current.setSuperType(sup);
         return current;
       }
     }
   }
   // and then super-class if any
   Type parent = raw.getGenericSuperclass();
   if (parent != null) {
     HierarchicType sup = _findSuperInterfaceChain(parent, target);
     if (sup != null) {
       sup.setSubType(current);
       current.setSuperType(sup);
       return current;
     }
   }
   return null;
 }
 protected static HierarchicType _findSuperClassChain(Type currentType, Class<?> target) {
   HierarchicType current = new HierarchicType(currentType);
   Class<?> raw = current.getRawClass();
   if (raw == target) {
     return current;
   }
   // Otherwise, keep on going down the rat hole...
   Type parent = raw.getGenericSuperclass();
   if (parent != null) {
     HierarchicType sup = _findSuperClassChain(parent, target);
     if (sup != null) {
       sup.setSubType(current);
       current.setSuperType(sup);
       return current;
     }
   }
   return null;
 }
 protected static JavaType _resolveVariableViaSubTypes(
     HierarchicType leafType, String variableName, TypeBindings bindings) {
   // can't resolve raw types; possible to have as-of-yet-unbound types too:
   if (leafType != null && leafType.isGeneric()) {
     TypeVariable<?>[] typeVariables = leafType.getRawClass().getTypeParameters();
     for (int i = 0, len = typeVariables.length; i < len; ++i) {
       TypeVariable<?> tv = typeVariables[i];
       if (variableName.equals(tv.getName())) {
         // further resolution needed?
         Type type = leafType.asGeneric().getActualTypeArguments()[i];
         if (type instanceof TypeVariable<?>) {
           return _resolveVariableViaSubTypes(
               leafType.getSubType(), ((TypeVariable<?>) type).getName(), bindings);
         }
         // no we're good for the variable (but it may have parameterization of its own)
         return instance._fromType(type, bindings);
       }
     }
   }
   return instance._unknownType();
 }