private static PsiType createParameterizedType(final PsiType t,
                                                 final PsiTypeVariableFactory factory,
                                                 final boolean upper,
                                                 final PsiElement context) {
    if (t == null || (upper && t.getCanonicalText().equals(CommonClassNames.JAVA_LANG_OBJECT))) {
      return factory.create(context);
    }

    if (t instanceof PsiClassType) {
      final PsiClassType.ClassResolveResult result = resolveType(t);
      final PsiSubstitutor aSubst = result.getSubstitutor();
      final PsiClass aClass = result.getElement();

      PsiSubstitutor theSubst = PsiSubstitutor.EMPTY;

      final Set<PsiTypeVariable> cluster = new HashSet<>();

      for (final PsiTypeParameter parm : aSubst.getSubstitutionMap().keySet()) {
        final PsiType type = createParameterizedType(aSubst.substitute(parm), factory, false, context);

        if (type instanceof PsiTypeVariable) {
          cluster.add((PsiTypeVariable)type);
        }

        theSubst = theSubst.put(parm, type);
      }

      if (cluster.size() > 1) {
        factory.registerCluster(cluster);
      }

      return JavaPsiFacade.getElementFactory(aClass.getProject()).createType(aClass, theSubst);
    }
    else if (t instanceof PsiArrayType) {
      return createParameterizedType(((PsiArrayType)t).getComponentType(), factory, upper, context).createArrayType();
    }

    return t;
  }
private static PsiType createParameterizedType(final PsiType t,
                                                 final PsiTypeVariableFactory factory,
                                                 final boolean upper,
                                                 final PsiElement context)