// returns list of resolved files if updated successfully, or null if write action or dumb mode
  // started
  private int[] processFile(
      @NotNull final VirtualFile file, int fileId, @NotNull final ProgressIndicator indicator) {
    final TIntHashSet forward;
    try {
      forward = calcForwardRefs(file, indicator);
    } catch (IndexNotReadyException e) {
      return null;
    } catch (ApplicationUtil.CannotRunReadActionException e) {
      return null;
    } catch (ProcessCanceledException e) {
      throw e;
    } catch (Exception e) {
      log(ExceptionUtil.getThrowableText(e));
      flushLog();
      return null;
    }

    int[] forwardIds = forward.toArray();
    fileIsResolved.set(fileId);
    logf(
        "  ---- " + file.getPresentableUrl() + " processed. forwardIds: " + toVfString(forwardIds));
    for (Listener listener : myListeners) {
      listener.fileResolved(file);
    }
    return forwardIds;
  }
 private static void addIdAndSuperClasses(PsiFile file, @NotNull TIntHashSet forward) {
   if (file instanceof PsiJavaFile
       && file.getName().equals("Object.class")
       && ((PsiJavaFile) file).getPackageName().equals("java.lang")) {
     return;
   }
   VirtualFile virtualFile = PsiUtilCore.getVirtualFile(file);
   if (virtualFile instanceof VirtualFileWithId
       && forward.add(getAbsId(virtualFile))
       && file instanceof PsiClassOwner) {
     for (PsiClass aClass : ((PsiClassOwner) file).getClasses()) {
       for (PsiClass superClass : aClass.getSupers()) {
         addIdAndSuperClasses(superClass.getContainingFile(), forward);
       }
     }
   }
 }
  @NotNull
  private TIntHashSet calcForwardRefs(
      @NotNull final VirtualFile virtualFile, @NotNull final ProgressIndicator indicator)
      throws IndexNotReadyException, ApplicationUtil.CannotRunReadActionException {

    final TIntHashSet forward = new TIntHashSet();

    final PsiFile psiFile =
        ApplicationUtil.tryRunReadAction(
            () -> {
              if (myProject.isDisposed()) throw new ProcessCanceledException();
              if (fileCount.incrementAndGet() % 100 == 0) {
                PsiManager.getInstance(myProject).dropResolveCaches();
                try {
                  storage.flush();
                  log.flush();
                } catch (IOException e) {
                  LOG.error(e);
                }
              }

              return PsiManager.getInstance(myProject).findFile(virtualFile);
            });
    final int fileId = getAbsId(virtualFile);
    if (psiFile != null) {
      bytesSize.addAndGet(virtualFile.getLength());
      final Set<PsiElement> resolved = new THashSet<PsiElement>();
      ApplicationUtil.tryRunReadAction(
          new Runnable() {
            @Override
            public void run() {
              indicator.checkCanceled();

              if (psiFile instanceof PsiJavaFile) {
                psiFile.accept(
                    new JavaRecursiveElementWalkingVisitor() {
                      @Override
                      public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
                        indicator.checkCanceled();
                        resolveReference(reference, resolved);

                        super.visitReferenceElement(reference);
                      }
                    });
              } else {
                psiFile.accept(
                    new PsiRecursiveElementWalkingVisitor() {
                      @Override
                      public void visitElement(PsiElement element) {
                        for (PsiReference reference : element.getReferences()) {
                          indicator.checkCanceled();
                          resolveReference(reference, resolved);
                        }
                        super.visitElement(element);
                      }
                    });
              }

              indicator.checkCanceled();
              for (PsiElement element : resolved) {
                PsiFile file = element.getContainingFile();
                addIdAndSuperClasses(file, forward);
              }
            }
          });
    }

    forward.remove(fileId);
    return forward;
  }