code: private static Type resolveWildcardCommodity(final Type first,
                                                   final Type second,
                                                   final boolean alwaysIncludeInterfaces,
                                                   final PathsCache cache) {
          final List<Type> firstTypes = collectContainedTypes(first);
          final List<Type> secondTypes = collectContainedTypes(second);
  
          final List<Type> res = new ArrayList<Type>();
          // compare each left type with each right and all non Object matches will compose target common type
          for (Type left : firstTypes) {
              for (Type right : secondTypes) {
                  final Type type = buildImpl(left, right, alwaysIncludeInterfaces, cache);
                  if (type != Object.class) {
                      if (type instanceof WildcardType) {
                          // unwrap wildcard because we actually need only all classes
                          mergeWildcardTypes(res, ((WildcardType) type).getUpperBounds());
                      } else {
                          mergeWildcardTypes(res, type);
                      }
                  }
              }
          }
          if (res.isEmpty()) {
              return Object.class;
          }
          return res.size() == 1 ? res.get(0) : WildcardTypeImpl.upper(res.toArray(new Type[0]));
      }
docs: Used when one of types is wildcard (contains multiple declaration types like {@code ? extends One & Two}).
  <p>
  All contained types from one type is compared for commodity with all contained types in another type.
  Overall commodity type is a wildcard with all non {@code Object} matches (of course after duplicates exclusion).
  
  @param first                   first type
  @param second                  second type
  @param alwaysIncludeInterfaces always search for common interfaces
  @param cache                   resolution types cache
  @return common type or Object if no commodity detected