private static @NotNull PsiSubstitutor substituteTypeParameters(@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);
  }
private static @NotNull PsiSubstitutor substituteTypeParameters(@NotNull JVMElementFactory factory,
                                                                  @Nullable PsiElement target,
                                                                  @Nullable PsiTypeParameterList sourceTypeParameterList,
                                                                  @Nullable PsiTypeParameterList targetTypeParameterList,
                                                                  @NotNull PsiSubstitutor substitutor,
                                                                  @NotNull PsiMethod sourceMethod)