PsiType (PsiClassType psiClassType) { final PsiClassType.ClassResolveResult result = psiClassType.resolveGenerics(); final PsiClass psiClass = result.getElement(); if (psiClass != null) { final PsiTypeParameter[] typeParameters = psiClass.getTypeParameters(); final PsiType[] newParameters = new PsiType[typeParameters.length]; final PsiSubstitutor substitutor = result.getSubstitutor(); final HashSet<PsiTypeParameter> typeParametersSet = ContainerUtil.newHashSet(typeParameters); next: for (int i = 0; i < typeParameters.length; i++) { PsiType paramType = substitutor.substitute(typeParameters[i]); if (paramType instanceof PsiWildcardType) { final PsiType bound = ((PsiWildcardType)paramType).getBound(); for (PsiClassType paramBound : typeParameters[i].getExtendsListTypes()) { if (PsiTypesUtil.mentionsTypeParameters(paramBound, typeParametersSet)) { if (bound == null) { return null; } newParameters[i] = bound; continue next; } } if (((PsiWildcardType)paramType).isSuper()) { newParameters[i] = bound; } else { newParameters[i] = bound != null ? bound : PsiType.getJavaLangObject(psiClass.getManager(), psiClassType.getResolveScope()); for (PsiClassType paramBound : typeParameters[i].getExtendsListTypes()) { newParameters[i] = GenericsUtil.getGreatestLowerBound(newParameters[i], paramBound); } } } else { newParameters[i] = paramType; } } if (!isWellFormed(psiClass, typeParameters, newParameters)) { return null; } final PsiClassType parameterization = JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, newParameters); if (!psiClassType.isAssignableFrom(parameterization)) { return null; } return parameterization; } return null; }