void (@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); } }