void (List<? extends VFileEvent> events) { if (roots == null) return; HashSet<VirtualFile> files = new HashSet<>(); HashSet<VirtualFile> parents = new HashSet<>(); for (VFileEvent event : events) { if (event instanceof VFilePropertyChangeEvent) { if (hasEntry(event.getFile())) files.add(event.getFile()); } else if (event instanceof VFileCreateEvent create) { if (hasEntry(create.getParent())) parents.add(create.getParent()); } else if (event instanceof VFileCopyEvent copy) { if (hasEntry(copy.getNewParent())) parents.add(copy.getNewParent()); } else if (event instanceof VFileMoveEvent move) { if (hasEntry(move.getNewParent())) parents.add(move.getNewParent()); if (hasEntry(move.getOldParent())) parents.add(move.getOldParent()); } else if (event instanceof VFileDeleteEvent) { VirtualFile file = event.getFile(); if (hasEntry(file)) { files.add(file); //TODO:for all roots file = file.getParent(); parents.add(hasEntry(file) ? file : null); } } } for (VirtualFile parent : parents) { for (Root root : roots) { Entry<Node> entry = root.tree.findEntry(parent); if (entry != null) { UpdateResult<Node> update = root.updateChildren(state, entry); //TODO:listeners.isEmpty boolean removed = !update.getRemoved().isEmpty(); boolean inserted = !update.getInserted().isEmpty(); boolean contained = !update.getContained().isEmpty(); if (!removed && !inserted && !contained) continue; if (!removed && inserted) { if (listeners.isEmpty()) continue; listeners.treeNodesInserted(update.getEvent(this, entry, update.getInserted())); continue; } if (!inserted && removed) { if (listeners.isEmpty()) continue; listeners.treeNodesRemoved(update.getEvent(this, entry, update.getRemoved())); continue; } treeStructureChanged(entry, null, null); } } } for (VirtualFile file : files) { //TODO:update } //TODO:on valid thread / entry - mark as valid }