private void analyzeEvents(@NotNull List<? extends VFileEvent> events) {
    if (events.isEmpty()) {
      return;
    }
    Set<String> toRefresh = new HashSet<>();
    FileWatcher fileWatcher = mySystem.getFileWatcher();

    Consumer<String> queuePath = path -> toRefresh.addAll(fileWatcher.mapToAllSymlinks(FileUtil.toSystemDependentName(path)));
    Consumer<VirtualFile> queueFile = file -> {
      if (file instanceof VirtualFileSystemEntry) {
        if (((VirtualFileSystemEntry)file).thisOrParentHaveSymlink() && !isUnderRecursiveOrCircularSymlink(file)) {
          String obj = file.getCanonicalPath();
          file = obj == null ? null : mySystem.findFileByPathIfCached(obj);
          if (file != null && fileWatcher.belongsToWatchRoots(FileUtil.toSystemDependentName(file.getPath()), !file.isDirectory())) {
            toRefresh.add(file.getPath());
          }
        }
        else {
          queuePath.accept(file.getPath());
        }
      }
    };

    for (VFileEvent event : events) {
      if (event.isFromRefresh() || event.getFileSystem() != mySystem) {
        continue;
      }
      if (event instanceof VFileContentChangeEvent
          || event instanceof VFileDeleteEvent) {
        queueFile.accept(event.getFile());
      }
      else if (event instanceof VFilePropertyChangeEvent) {
        VirtualFile file = ((VFilePropertyChangeEvent)event).getFile();
        if (((VFilePropertyChangeEvent)event).getPropertyName().equals(VirtualFile.PROP_NAME)) {
          queuePath.accept(((VFilePropertyChangeEvent)event).getOldPath());
          queueFile.accept(file.getParent());
        }
        else {
          queueFile.accept(file);
        }
      }
      else if (event instanceof VFileCreateEvent) {
        queueFile.accept(((VFileCreateEvent)event).getParent());
      }
      else if (event instanceof VFileCopyEvent) {
        queueFile.accept(((VFileCopyEvent)event).getNewParent());
      }
      else if (event instanceof VFileMoveEvent) {
        queueFile.accept(event.getFile());
        queueFile.accept(((VFileMoveEvent)event).getNewParent());
      }
    }
    if (!toRefresh.isEmpty()) {
      scheduleRefresh(toRefresh);
    }
  }
private void analyzeEvents(@NotNull List<? extends VFileEvent> events)