docs: private static Type[] getGenericInterfaces(Class<?> cls, Class<?> expectedClass,
                                                 Class<?> commonBaseCls) {
          if (Object.class == cls) {
              return emptyType;
          }
          Type[] cachedTypes = getTypes(cls, expectedClass, commonBaseCls);
          if (cachedTypes != null)
              return cachedTypes;
          if (expectedClass != null) {
              Type genericSuperType = cls.getGenericSuperclass();
              if (genericSuperType instanceof ParameterizedType) {
                  Class<?> actualType = InjectionUtils.getActualType(genericSuperType);
                  if (actualType != null && actualType.isAssignableFrom(expectedClass)) {
                      Type[] tempTypes = new Type[] { genericSuperType };
                      putTypes(cls, expectedClass, commonBaseCls, tempTypes);
                      return tempTypes;
                  } else if (commonBaseCls != null && commonBaseCls != Object.class 
                             && commonBaseCls.isAssignableFrom(expectedClass)
                             && commonBaseCls.isAssignableFrom(actualType)
                             || expectedClass.isAssignableFrom(actualType)) {
                      putTypes(cls, expectedClass, commonBaseCls, emptyType);
                      return emptyType;
                  }
              }
          }
          Type[] types = cls.getGenericInterfaces();
          if (types.length > 0) {
              putTypes(cls, expectedClass, commonBaseCls, types);
              return types;
          }
          Type[] superGenericTypes = getGenericInterfaces(cls.getSuperclass(), expectedClass, commonBaseCls);
          putTypes(cls, expectedClass, commonBaseCls, superGenericTypes);
          return superGenericTypes;
      }