private void processQueue(List<VFileEvent> events) throws RefreshCancelledException {
    nextDir:
    while (!mySemaphore.isUp()) {
      var file = myRefreshQueue.poll();
      if (file == null) {
        TimeoutUtil.sleep(1);
        continue;
      }

      var fs = file.getFileSystem();

      try {
        if (myRoots.contains(file)) {
          var attributes = computeAttributesForFile(fs, file);
          if (attributes == null) {
            scheduleDeletion(events, file);
            file.markClean();
            continue;
          }

          checkAndScheduleChildRefresh(events, fs, file.getParent(), file, attributes, false);

          if (!file.isDirty() || !file.isDirectory()) {
            continue;
          }
        }

        var dir = (VirtualDirectoryImpl)file;
        var mark = events.size();

        while (true) {
          checkCancelled(dir);
          var fullSync = dir.allChildrenLoaded();
          (fullSync ? myFullScans : myPartialScans).incrementAndGet();
          try {
            var success = fullSync ? fullDirRefresh(events, fs, dir) : partialDirRefresh(events, fs, dir);
            if (success) break;
            events.subList(mark, events.size()).clear();
            if (LOG.isTraceEnabled()) LOG.trace("retry: " + dir);
          }
          catch (InvalidVirtualFileAccessException e) {
            events.subList(mark, events.size()).clear();
            continue nextDir;
          }
          finally {
            clearFsCache(fs);
          }
        }
        myProcessed.incrementAndGet();

        if (myIsRecursive) {
          dir.markClean();
        }
      }
      finally {
        mySemaphore.up();
      }
    }
  }
private void processQueue(List<VFileEvent> events)