InferenceVariable[] (PsiElement context, final PsiSubstitutor siteSubstitutor, PsiTypeParameter @NotNull ... typeParameters) { List<InferenceVariable> result = new ArrayList<>(typeParameters.length); for (PsiTypeParameter parameter : typeParameters) { String name = parameter.getName(); if (myContext != null) { name += MathUtil.nonNegativeAbs(myContext.hashCode()); } InferenceVariable variable = new InferenceVariable(context, parameter, name); result.add(variable); final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myManager.getProject()); myInferenceSubstitution = myInferenceSubstitution.put(parameter, elementFactory.createType(variable)); myRestoreNameSubstitution = myRestoreNameSubstitution.put(variable, elementFactory.createType(parameter)); myInferenceVariables.add(variable); } for (InferenceVariable variable : result) { PsiTypeParameter parameter = variable.getParameter(); boolean added = false; final PsiClassType[] extendsListTypes = parameter.getExtendsListTypes(); for (PsiType classType : extendsListTypes) { classType = substituteWithInferenceVariables(siteSubstitutor.substitute(classType)); if (isProperType(classType)) { added = true; } variable.addBound(classType, InferenceBound.UPPER, null); } if (!added) { variable.addBound(PsiType.getJavaLangObject(parameter.getManager(), parameter.getResolveScope()), InferenceBound.UPPER, null); } } return result.toArray(new InferenceVariable[0]); }