private static @NotNull PsiSubstitutor calculateMethodSubstitutor(PsiTypeParameter @NotNull [] typeParameters,
                                                                    @NotNull PsiMethod method,
                                                                    @NotNull PsiSubstitutor siteSubstitutor,
                                                                    PsiType @NotNull [] types1,
                                                                    PsiType @NotNull [] types2,
                                                                    @NotNull LanguageLevel languageLevel) {
    PsiSubstitutor substitutor = PsiResolveHelper.getInstance(method.getProject())
      .inferTypeArguments(typeParameters, types1, types2, languageLevel);
    for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(method)) {
      ProgressManager.checkCanceled();
      LOG.assertTrue(typeParameter != null);
      if (!substitutor.getSubstitutionMap().containsKey(typeParameter)) {
        PsiType type = siteSubstitutor.substitute(typeParameter);
        if (type instanceof PsiClassType && typeParameter.getOwner() == method) {
          final PsiClass aClass = ((PsiClassType)type).resolve();
          if (aClass instanceof PsiTypeParameter && ((PsiTypeParameter)aClass).getOwner() == method) {
            type = TypeConversionUtil.erasure(type, siteSubstitutor);
          }
        }
        substitutor = substitutor.put(typeParameter, type);
      } else {
        final PsiType type = substitutor.substitute(typeParameter);
        if (type instanceof PsiClassType) {
          final PsiClass aClass = ((PsiClassType)type).resolve();
          if (aClass instanceof PsiTypeParameter) {
            substitutor = substitutor.put(typeParameter, JavaPsiFacade.getElementFactory(aClass.getProject()).createType(aClass, siteSubstitutor));
          }
        }
      }
    }
    return substitutor;
  }
private static @NotNull PsiSubstitutor calculateMethodSubstitutor(PsiTypeParameter @NotNull [] typeParameters,
                                                                    @NotNull PsiMethod method,
                                                                    @NotNull PsiSubstitutor siteSubstitutor,
                                                                    PsiType @NotNull [] types1,
                                                                    PsiType @NotNull [] types2,
                                                                    @NotNull LanguageLevel languageLevel)