public static boolean isAccessible(@NotNull PsiMember member,
                                     @Nullable PsiClass memberClass,
                                     @Nullable PsiModifierList modifierList,
                                     @NotNull PsiElement place,
                                     @Nullable PsiClass accessObjectClass,
                                     @Nullable PsiElement fileResolveScope,
                                     @Nullable PsiFile placeFile) {
    if (modifierList == null || isInJavaDoc(place)) {
      return true;
    }

    if (placeFile instanceof JavaCodeFragment) {
      JavaCodeFragment fragment = (JavaCodeFragment)placeFile;
      JavaCodeFragment.VisibilityChecker visibilityChecker = fragment.getVisibilityChecker();
      if (visibilityChecker != null) {
        JavaCodeFragment.VisibilityChecker.Visibility visibility = visibilityChecker.isDeclarationVisible(member, place);
        if (visibility == JavaCodeFragment.VisibilityChecker.Visibility.VISIBLE) return true;
        if (visibility == JavaCodeFragment.VisibilityChecker.Visibility.NOT_VISIBLE) return false;
      }
    }
    else if (ignoreReferencedElementAccessibility(placeFile)) {
      return true;
    }

    if (accessObjectClass != null) {
      PsiClass containingClass = accessObjectClass.getContainingClass();
      if (!isAccessible(accessObjectClass, containingClass, accessObjectClass.getModifierList(), place, null, null, placeFile)) {
        return false;
      }
    }

    PsiFile file = placeFile == null ? null : FileContextUtil.getContextFile(placeFile); //TODO: implementation method!!!!
    if (PsiImplUtil.isInServerPage(file) && PsiImplUtil.isInServerPage(member.getContainingFile())) {
      return true;
    }

    int effectiveAccessLevel = PsiUtil.getAccessLevel(modifierList);
    if (ignoreReferencedElementAccessibility(file) || effectiveAccessLevel == PsiUtil.ACCESS_LEVEL_PUBLIC) {
      return true;
    }

    PsiManager manager = member.getManager();
    JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());

    if (effectiveAccessLevel == PsiUtil.ACCESS_LEVEL_PROTECTED) {
      if (facade.arePackagesTheSame(member, place)) {
        return true;
      }
      if (memberClass == null) {
        return false;
      }
      PsiClass contextClass;
      if (member instanceof PsiClass) {
        // if resolving supertype reference, skip its containing class with getContextClass
        contextClass = getContextClass(place);
      }
      else {
        contextClass = PsiTreeUtil.getContextOfType(place, PsiClass.class, false);
        if (isInClassAnnotationParameterList(place, contextClass)) return false;
        if (contextClass instanceof PsiAnonymousClass && 
            PsiTreeUtil.isAncestor(((PsiAnonymousClass)contextClass).getArgumentList(), place, true)) {
          contextClass = PsiTreeUtil.getContextOfType(contextClass, PsiClass.class, true);
        }
      }
      return canAccessProtectedMember(member, memberClass, accessObjectClass, contextClass,
                                      modifierList.hasModifierProperty(PsiModifier.STATIC));
    }

    if (effectiveAccessLevel == PsiUtil.ACCESS_LEVEL_PRIVATE) {
      if (memberClass == null) return true;
      if (accessObjectClass != null) {
        PsiClass topMemberClass = getTopLevelClass(memberClass, accessObjectClass);
        PsiClass topAccessClass = getTopLevelClass(accessObjectClass, memberClass);
        if (!manager.areElementsEquivalent(topMemberClass, topAccessClass)) return false;
        if (accessObjectClass instanceof PsiAnonymousClass && accessObjectClass.isInheritor(memberClass, true)) {
          if (!(place instanceof PsiAnonymousClass)) {
            return false;
          }
        }
      }

      PsiClass memberTopLevelClass = getTopLevelClass(memberClass, null);
      if (fileResolveScope == null) {
        PsiClass placeTopLevelClass = getTopLevelClass(place, null);
        return manager.areElementsEquivalent(placeTopLevelClass, memberTopLevelClass) &&
               !isInClassAnnotationParameterList(place, placeTopLevelClass);
      }
      else {
        PsiClass scopeTopLevelClass = getTopLevelClass(fileResolveScope, null);
        return manager.areElementsEquivalent(scopeTopLevelClass, memberTopLevelClass) &&
               fileResolveScope instanceof PsiClass &&
               !((PsiClass)fileResolveScope).isInheritor(memberClass, true);
      }
    }

    if (!facade.arePackagesTheSame(member, place)) return false;
    //if (modifierList.hasModifierProperty(PsiModifier.STATIC)) return true;
    // maybe inheritance lead through package-private class in other package ?
    final PsiClass placeClass = getContextClass(place);
    if (memberClass == null || placeClass == null) return true;
    // check only classes since interface members are public,  and if placeClass is interface,
    // then its members are static, and cannot refer to non-static members of memberClass
    if (memberClass.isInterface() || placeClass.isInterface()) return true;
    PsiClass clazz = accessObjectClass != null ?
                     accessObjectClass :
                     placeClass.getSuperClass(); //may start from super class
    if (clazz != null && clazz.isInheritor(memberClass, true)) {
      PsiClass superClass = clazz;
      while (!manager.areElementsEquivalent(superClass, memberClass)) {
        if (superClass == null || !facade.arePackagesTheSame(superClass, memberClass)) return false;
        superClass = superClass.getSuperClass();
      }
    }

    return true;
  }
public static boolean isAccessible(@NotNull PsiMember member,
                                     @Nullable PsiClass memberClass,
                                     @Nullable PsiModifierList modifierList,
                                     @NotNull PsiElement place,
                                     @Nullable PsiClass accessObjectClass,
                                     @Nullable PsiElement fileResolveScope,
                                     @Nullable PsiFile placeFile)