private void processFilesInReadAction(@NotNull VfsEventsMerger.VfsEventProcessor processor) {
    ApplicationManager.getApplication().assertReadAccessAllowed();

    int publishedEventIndex = getEventMerger().getPublishedEventIndex();
    int processedEventIndex = myProcessedEventIndex.get();
    if (processedEventIndex == publishedEventIndex) {
      return;
    }

    myWorkersFinishedSync.register();
    int phase = myWorkersFinishedSync.getPhase();
    try {
      myFileBasedIndex.waitUntilIndicesAreInitialized();
      getEventMerger().processChanges(new VfsEventsMerger.VfsEventProcessor() {
        @Override
        public boolean process(VfsEventsMerger.@NotNull ChangeInfo changeInfo) {
          return ConcurrencyUtil.withLock(myFileBasedIndex.myWriteLock, () -> {
            try {
              ProgressManager.getInstance().executeNonCancelableSection(() -> {
                processor.process(changeInfo);
              });
            }
            finally {
              IndexingStamp.flushCache(changeInfo.getFileId());
            }
            return true;
          });
        }
        @Override
        public void endBatch() {
          ConcurrencyUtil.withLock(myFileBasedIndex.myWriteLock, () -> {
            processor.endBatch();
          });
        }
      });
    }
    finally {
      myWorkersFinishedSync.arriveAndDeregister();
    }

    try {
      awaitWithCheckCancelled(myWorkersFinishedSync, phase);
    } catch (RejectedExecutionException | InterruptedException e) {
      LOG.warn(e);
      throw new ProcessCanceledException(e);
    }

    if (getEventMerger().getPublishedEventIndex() == publishedEventIndex) {
      myProcessedEventIndex.compareAndSet(processedEventIndex, publishedEventIndex);
    }
  }
private void processFilesInReadAction(@NotNull VfsEventsMerger.VfsEventProcessor processor)