code: private static Type buildCommonType(final Class<?> type,
                                          final Map<Class<?>, LinkedHashMap<String, Type>> firstContext,
                                          final Map<Class<?>, LinkedHashMap<String, Type>> secondContext,
                                          final boolean alwaysIncludeInterfaces,
                                          final PathsCache cache) {
          final TypeVariable<? extends Class<?>>[] typeParameters = type.getTypeParameters();
          if (typeParameters.length > 0) {
              final Type[] params = new Type[typeParameters.length];
              final Map<String, Type> firstGenerics = firstContext.get(type);
              final Map<String, Type> secondGenerics = secondContext.get(type);
              int i = 0;
              boolean notAllObject = false;
              for (TypeVariable var : typeParameters) {
                  final Type sub1 = firstGenerics.get(var.getName());
                  final Type sub2 = secondGenerics.get(var.getName());
                  final Type paramType = buildParameterType(type, sub1, sub2, alwaysIncludeInterfaces, cache);
                  if (paramType != Object.class) {
                      notAllObject = true;
                  }
                  params[i++] = paramType;
              }
              final Type outer = TypeUtils.getOuter(type);
              // simplify to avoid redundant (actually absent) parametrization
              return outer != null || notAllObject
                      ? new ParameterizedTypeImpl(type, params, outer)
                      : type;
          } else {
              return type;
          }
      }
docs: Called when common class is found in order to properly resolve generics for the common class.
  For example, suppose we detect that {@link Comparable} is common for {@link Integer} and {@link Double}
  and now we need to know it's common generic (in context of both types) which is {@code Comparable<Number>}.
  <p>
  Infinite generics depth is supported (e.g. {@code List<Set<List<T>>>>}. Types commodity resolution is simply
  restarted for lower levels (recursion).
  
  @param type                    common type (may be interface) for original types
  @param firstContext            first type generics context
  @param secondContext           second type generics context
  @param alwaysIncludeInterfaces always search for common interfaces
  @param cache                   resolution types cache
  @return complete common type