@PsiUtil.AccessLevel
    private int getEffectiveLevel(@NotNull PsiElement element,
                                  @NotNull PsiFile file,
                                  @NotNull PsiMember member,
                                  PsiClass memberClass,
                                  PsiPackage memberPackage) {
      if (member instanceof PsiClass && element instanceof PsiJavaCodeReferenceElement) {
        PsiMember exportingMember = ClassEscapesItsScopeInspection.getExportingMember((PsiJavaCodeReferenceElement)element);
        if (exportingMember != null) {
          final PsiModifierList modifierList = exportingMember.getModifierList();
          assert modifierList != null;
          return PsiUtil.getAccessLevel(modifierList);
        }
      }
      PsiClass innerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
      if (memberClass != null && PsiTreeUtil.isAncestor(innerClass, memberClass, false) ||
          innerClass != null && PsiTreeUtil.isAncestor(memberClass, innerClass, false)) {
        // access from the same file can be via private
        // except when used in annotation:
        // @Ann(value = C.VAL) class C { public static final String VAL = "xx"; }
        // or in implements/extends clauses
        if (VisibilityInspection.containsReferenceTo(innerClass.getModifierList(), member) ||
            VisibilityInspection.containsReferenceTo(innerClass.getImplementsList(), member) ||
            VisibilityInspection.containsReferenceTo(innerClass.getExtendsList(), member)) {
          return suggestPackageLocal(member);
        }

        return !member.hasModifierProperty(PsiModifier.ABSTRACT) &&
               (myVisibilityInspection.SUGGEST_PRIVATE_FOR_INNERS || !isInnerClass(memberClass)) &&
               (member.hasModifierProperty(PsiModifier.STATIC) || !calledOnInheritor(element, memberClass))
               ? PsiUtil.ACCESS_LEVEL_PRIVATE : suggestPackageLocal(member);
      }

      PsiExpression qualifier = getQualifier(element);
      PsiElement resolvedQualifier = qualifier instanceof PsiReference ? ((PsiReference)qualifier).resolve() : null;
      if (resolvedQualifier instanceof PsiVariable) {
        resolvedQualifier = PsiUtil.resolveClassInClassTypeOnly(((PsiVariable)resolvedQualifier).getType());
      }
      PsiPackage qualifierPackage = resolvedQualifier == null ? null : getPackage(resolvedQualifier);
      PsiPackage aPackage = getPackage(file);

      if (samePackage(memberPackage, aPackage)
          && (qualifierPackage == null || samePackage(qualifierPackage, aPackage))
          // java 9 will dislike split packages
          && sameModule(member.getContainingFile(), file)) {
        return suggestPackageLocal(member);
      }

      // can't access protected members via "qualifier.protectedMember = 0;"
      if (qualifier != null) return PsiUtil.ACCESS_LEVEL_PUBLIC;

      if (innerClass != null && memberClass != null && innerClass.isInheritor(memberClass, true)) {
        //access from subclass can be via protected, except for constructors
        PsiElement resolved = element instanceof PsiReference ? ((PsiReference)element).resolve() : null;
        boolean isConstructor = resolved instanceof PsiClass && element.getParent() instanceof PsiNewExpression
                                || resolved instanceof PsiMethod && ((PsiMethod)resolved).isConstructor();
        if (!isConstructor) {
          return PsiUtil.ACCESS_LEVEL_PROTECTED;
        }
      }
      return PsiUtil.ACCESS_LEVEL_PUBLIC;
    }
@PsiUtil.AccessLevel
    private int getEffectiveLevel(@NotNull PsiElement element,
                                  @NotNull PsiFile file,
                                  @NotNull PsiMember member,
                                  PsiClass memberClass,
                                  PsiPackage memberPackage)