PsiSubstitutor (@NotNull JVMElementFactory factory, @Nullable PsiElement target, @Nullable PsiTypeParameterList sourceTypeParameterList, @Nullable PsiTypeParameterList targetTypeParameterList, @NotNull PsiSubstitutor substitutor, @NotNull PsiMethod sourceMethod) { if (sourceTypeParameterList == null || targetTypeParameterList == null || PsiUtil.isRawSubstitutor(sourceMethod, substitutor)) { return substitutor; } final Map<PsiTypeParameter, PsiType> substitutionMap = new HashMap<>(substitutor.getSubstitutionMap()); for (PsiTypeParameter typeParam : sourceTypeParameterList.getTypeParameters()) { final PsiTypeParameter substitutedTypeParam = substituteTypeParameter(factory, typeParam, substitutor, sourceMethod); final PsiTypeParameter resolvedTypeParam = resolveTypeParametersCollision(factory, sourceTypeParameterList, target, substitutedTypeParam, substitutor); targetTypeParameterList.add(resolvedTypeParam); if (substitutedTypeParam != resolvedTypeParam) { substitutionMap.put(typeParam, factory.createType(resolvedTypeParam)); } } return substitutionMap.isEmpty() ? substitutor : factory.createSubstitutor(substitutionMap); }