@Nullable
  private PsiType evaluateReferenceExpressionType(PsiExpression expr) {
    final PsiReferenceExpression ref = (PsiReferenceExpression)expr;
    final PsiExpression qualifier = ref.getQualifierExpression();

    if (qualifier == null) {
      final PsiElement resolvee = ref.resolve();

      if (resolvee == null) {
        return null;
      }

      return resolvee instanceof PsiClass ? JavaPsiFacade.getElementFactory(resolvee.getProject()).createType((PsiClass)resolvee, PsiSubstitutor.EMPTY) : getType(resolvee);
    }
    else {
      final PsiType qualifierType = evaluateType(qualifier);
      if (!(qualifierType instanceof PsiArrayType)) {
        final PsiElement element = ref.resolve();

        final PsiClassType.ClassResolveResult result = resolveType(qualifierType);

        final PsiClass aClass = result.getElement();
        if (aClass != null) {
          final PsiSubstitutor aSubst = result.getSubstitutor();
          if (element instanceof PsiField field) {
            PsiType aType = field.getType();
            final PsiClass superClass = field.getContainingClass();
            if (InheritanceUtil.isInheritorOrSelf(aClass, superClass, true)) {
              aType = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY).substitute(aType);
            }
            return aSubst.substitute(aType);
          }  else if (element instanceof PsiMethod method){
            PsiType aType = method.getReturnType();
            final PsiClass superClass = method.getContainingClass();
            if (InheritanceUtil.isInheritorOrSelf(aClass, superClass, true)) {
              aType = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY).substitute(aType);
            } else if (InheritanceUtil.isInheritorOrSelf(superClass, aClass, true)) {
              final PsiMethod[] methods = method.findSuperMethods(aClass);
              if (methods.length > 0) {
                aType = methods[0].getReturnType();
              }
            /*}
            final Pair<PsiType, PsiType> pair = myRules.bindTypeParameters(qualifier.getType(), qualifierType, method, ref, myLabeler);
            if (pair != null) {
              final PsiClass psiClass = PsiUtil.resolveClassInType(aType);
              if (psiClass instanceof PsiTypeParameter) {
                aSubst = aSubst.put((PsiTypeParameter)psiClass, pair.getSecond());
              }*/
            }
            return aSubst.substitute(aType);
          }
        }
      }
    }
    return null;
  }
@Nullable
  private PsiType evaluateReferenceExpressionType(PsiExpression expr)