@Nullable
  private static PsiType getExpectedTypeArg(PsiElement context,
                                            PsiClassType.ClassResolveResult expectedType,
                                            PsiSubstitutor superClassSubstitutor, PsiTypeParameter typeParam) {
    PsiClass expectedClass = expectedType.getElement();
    assert expectedClass != null;
    for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(expectedClass)) {
      PsiType paramSubstitution = superClassSubstitutor.substitute(parameter);
      PsiClass inheritorCandidateParameter = PsiUtil.resolveClassInType(paramSubstitution);
      if (inheritorCandidateParameter instanceof PsiTypeParameter &&
          ((PsiTypeParameter)inheritorCandidateParameter).getOwner() == typeParam.getOwner() &&
          inheritorCandidateParameter != typeParam) {
        continue;
      }

      PsiType argSubstitution = expectedType.getSubstitutor().substitute(parameter);
      PsiType substitution = JavaPsiFacade.getInstance(context.getProject()).getResolveHelper()
        .getSubstitutionForTypeParameter(typeParam, paramSubstitution, argSubstitution, true, PsiUtil.getLanguageLevel(context));
      if (substitution != null && substitution != PsiTypes.nullType()) {
        return substitution;
      }
    }
    return null;
  }
@Nullable
  private static PsiType getExpectedTypeArg(PsiElement context,
                                            PsiClassType.ClassResolveResult expectedType,
                                            PsiSubstitutor superClassSubstitutor, PsiTypeParameter typeParam)