private boolean checkAccessibility(final PsiClass aClass) {
    // We don't care about accessibility in javadoc
    if (JavaResolveUtil.isInJavaDoc(myPlace)) {
      return true;
    }

    if (PsiImplUtil.isInServerPage(aClass.getContainingFile())) {
      PsiFile file = FileContextUtil.getContextFile(myPlace);
      if (PsiImplUtil.isInServerPage(file)) {
        return true;
      }
    }

    boolean accessible = true;
    if (aClass instanceof PsiTypeParameter) {
      accessible = !myStaticContext;
    }

    PsiManager manager = aClass.getManager();
    if (aClass.hasModifierProperty(PsiModifier.PRIVATE)) {
      PsiElement parent = aClass.getParent();
      while (true) {
        PsiElement parentScope = parent.getParent();
        if (parentScope instanceof PsiJavaFile) break;
        parent = parentScope;
        if (!(parentScope instanceof PsiClass)) break;
      }
      if (parent instanceof PsiDeclarationStatement) {
        parent = parent.getParent();
      }
      accessible = false;
      for (PsiElement placeParent = myPlace;
          placeParent != null;
          placeParent = placeParent.getContext()) {
        if (manager.areElementsEquivalent(placeParent, parent)) accessible = true;
      }
    }
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
    if (aClass.hasModifierProperty(PsiModifier.PROTECTED)) {
      accessible = false;
      if (myPlace != null && facade.arePackagesTheSame(aClass, myPlace)) {
        accessible = true;
      } else {
        if (aClass.getContainingClass() != null) {
          accessible =
              myAccessClass == null
                  || myPlace != null
                      && facade.getResolveHelper().isAccessible(aClass, myPlace, myAccessClass);
        }
      }
    }
    if (aClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) {
      if (myPlace == null || !facade.arePackagesTheSame(aClass, myPlace)) {
        accessible = false;
      }
    }
    return accessible;
  }
 private boolean isAmbiguousInherited(PsiClass containingClass1) {
   PsiClass psiClass = PsiTreeUtil.getParentOfType(myPlace, PsiClass.class);
   while (psiClass != null) {
     if (psiClass.isInheritor(containingClass1, false)) {
       return true;
     }
     psiClass = psiClass.getContainingClass();
   }
   return false;
 }
 private boolean isAccessible(PsiClass otherClass) {
   if (otherClass.hasModifierProperty(PsiModifier.PRIVATE)) {
     final PsiClass containingClass = otherClass.getContainingClass();
     PsiClass containingPlaceClass = PsiTreeUtil.getParentOfType(myPlace, PsiClass.class, false);
     while (containingPlaceClass != null) {
       if (containingClass == containingPlaceClass) {
         return true;
       }
       containingPlaceClass = PsiTreeUtil.getParentOfType(containingPlaceClass, PsiClass.class);
     }
     return false;
   }
   return true;
 }
  private Domination dominates(
      PsiClass aClass, boolean accessible, String fqName, ClassCandidateInfo info) {
    final PsiClass otherClass = info.getElement();
    assert otherClass != null;
    String otherQName = otherClass.getQualifiedName();
    if (fqName.equals(otherQName)) {
      return Domination.DOMINATED_BY;
    }

    final PsiClass containingClass1 = aClass.getContainingClass();
    final PsiClass containingClass2 = otherClass.getContainingClass();
    if (myAccessClass != null && !Comparing.equal(containingClass1, containingClass2)) {
      if (myAccessClass.equals(containingClass1)) return Domination.DOMINATES;
      if (myAccessClass.equals(containingClass2)) return Domination.DOMINATED_BY;
    }

    // JLS 8.5:
    // A class may inherit two or more type declarations with the same name, either from two
    // interfaces or from its superclass and an interface.
    // It is a compile-time error to attempt to refer to any ambiguously inherited class or
    // interface by its simple name.
    if (containingClass1 != null
        && containingClass2 != null
        && containingClass2.isInheritor(containingClass1, true)
        && !isImported(myCurrentFileContext)) {
      if (!isAmbiguousInherited(containingClass1)) {
        // shadowing
        return Domination.DOMINATED_BY;
      }
    }

    boolean infoAccessible = info.isAccessible() && isAccessible(otherClass);
    if (infoAccessible && !accessible) {
      return Domination.DOMINATED_BY;
    }
    if (!infoAccessible && accessible) {
      return Domination.DOMINATES;
    }

    // everything wins over class from default package
    boolean isDefault = StringUtil.getPackageName(fqName).length() == 0;
    boolean otherDefault =
        otherQName != null && StringUtil.getPackageName(otherQName).length() == 0;
    if (isDefault && !otherDefault) {
      return Domination.DOMINATED_BY;
    }
    if (!isDefault && otherDefault) {
      return Domination.DOMINATES;
    }

    // single import wins over on-demand
    boolean myOnDemand = isOnDemand(myCurrentFileContext, aClass);
    boolean otherOnDemand = isOnDemand(info.getCurrentFileResolveScope(), otherClass);
    if (myOnDemand && !otherOnDemand) {
      return Domination.DOMINATED_BY;
    }
    if (!myOnDemand && otherOnDemand) {
      return Domination.DOMINATES;
    }

    return Domination.EQUAL;
  }