void addRelevantPointersFrom(@NotNull VirtualFileSystemEntry parent,
                               @Nullable VirtualFile file,
                               int childNameId,
                               @NotNull MultiMap<? super VirtualFilePointerListener, ? super VirtualFilePointerImpl> toFirePointers,
                               @NotNull List<? super NodeToUpdate> toUpdateNodes,
                               boolean addSubdirectoryPointers,
                               @NotNull NewVirtualFileSystem fs,
                               boolean addRecursiveDirectoryPointers,
                               @NotNull VFileEvent event) {
    NodeToUpdate toUpdate = matchById(parent, file, childNameId, toFirePointers, false, addRecursiveDirectoryPointers, fs);
    if (toUpdate != null) {
      toUpdate.myEvent = event;
      toUpdateNodes.add(toUpdate);
      toUpdate.node.processPointers(pointer -> toFirePointers.putValue(pointer.myListener, pointer));
      if (addSubdirectoryPointers) {
        // when "a/b" changed, treat all "a/b/*" virtual file pointers as changed because that's what happens on directory rename "a"->"newA": "a" deleted and "newA" created
        addAllPointersStrictlyUnder(toUpdate.node, toFirePointers);
      }
    }
  }
void addRelevantPointersFrom(@NotNull VirtualFileSystemEntry parent,
                               @Nullable VirtualFile file,
                               int childNameId,
                               @NotNull MultiMap<? super VirtualFilePointerListener, ? super VirtualFilePointerImpl> toFirePointers,
                               @NotNull List<? super NodeToUpdate> toUpdateNodes,
                               boolean addSubdirectoryPointers,
                               @NotNull NewVirtualFileSystem fs,
                               boolean addRecursiveDirectoryPointers,
                               @NotNull VFileEvent event)