private static boolean mayHaveScopeWideningSubclass(PsiClass aClass, Set<PsiClass> visited) {
    if (!aClass.hasModifierProperty(PsiModifier.PRIVATE)) return true;
    if (aClass instanceof PsiCompiledElement) return true; // don't check library code
    if (!visited.add(aClass)) return true; // prevent infinite recursion on broken code
    class LocalInheritorVisitor extends JavaRecursiveElementWalkingVisitor {
      private final Set<PsiClass> subclasses = new HashSet<>();

      @Override
      public void visitReferenceElement(@NotNull PsiJavaCodeReferenceElement reference) {
        final PsiElement parent = reference.getParent();
        if (!(parent instanceof PsiReferenceList)) return;
        final PsiElement grandParent = parent.getParent();
        if (!(grandParent instanceof PsiClass)) return;
        if (reference.isReferenceTo(aClass)) {
          subclasses.add((PsiClass)grandParent);
        }
      }

      @Override
      public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {}

      public boolean isExtended() {
        return !subclasses.isEmpty();
      }
    }
    PsiClass context = PsiUtil.getTopLevelClass(aClass);
    if (context == null) return false;
    final LocalInheritorVisitor visitor = new LocalInheritorVisitor();
    context.accept(visitor);
    return visitor.isExtended() && ContainerUtil.exists(visitor.subclasses, subclass -> mayHaveScopeWideningSubclass(subclass, visited));
  }
private static boolean mayHaveScopeWideningSubclass(PsiClass aClass, Set<PsiClass> visited)