PsiSubstitutor (Collection<InferenceVariable> inferenceVariables) { final List<InferenceVariable> targetVars = new ArrayList<>(); Map<PsiTypeParameter, PsiType> map = new HashMap<>(); final InferenceVariable[] oldVars = inferenceVariables.toArray(new InferenceVariable[0]); for (InferenceVariable variable : oldVars) { final InferenceVariable newVariable = new InferenceVariable(variable.getCallContext(), variable.getParameter(), variable.getName()); map.put(variable, JavaPsiFacade.getElementFactory(variable.getProject()).createType(newVariable)); targetVars.add(newVariable); if (variable.isThrownBound()) { newVariable.setThrownBound(); } newVariable.putUserData(InferenceSession.ORIGINAL_CAPTURE, variable.getUserData(InferenceSession.ORIGINAL_CAPTURE)); } PsiSubstitutor substitutor = PsiSubstitutor.createSubstitutor(map); for (int i = 0; i < targetVars.size(); i++) { InferenceVariable var = targetVars.get(i); for (InferenceBound boundType : InferenceBound.values()) { for (PsiType bound : oldVars[i].getBounds(boundType)) { var.addBound(substitutor.substitute(bound), boundType, null); } } } return substitutor; }