void (@NotNull VirtualFile file, @Nullable List<? super Node> list, @NotNull Consumer<Object> consumer) { model.onValidThread(() -> { AreaInstance area = ProjectFileNode.findArea(file, root.getProject()); if (area != null) { TreeVisitor visitor = new TreeVisitor.ByComponent<>(file, AbstractTreeNode.class) { @Override protected boolean matches(@NotNull AbstractTreeNode pathComponent, @NotNull VirtualFile thisComponent) { if (pathComponent.canRepresent(thisComponent)) return true; if (pathComponent instanceof Node) return false; ProjectViewNode<?> node = pathComponent instanceof ProjectViewNode ? (ProjectViewNode<?>)pathComponent : null; return node != null && node.contains(thisComponent); } @Override protected boolean contains(@NotNull AbstractTreeNode pathComponent, @NotNull VirtualFile thisComponent) { Node node = pathComponent instanceof Node ? (Node)pathComponent : null; if (node == null || !node.contains(thisComponent, area)) { return false; } if (list != null) { list.add(node); } return true; } }; AbstractTreeWalker<AbstractTreeNode<?>> walker = new AbstractTreeWalker<>(visitor) { @Override protected Collection<AbstractTreeNode<?>> getChildren(@NotNull AbstractTreeNode pathComponent) { Node node = pathComponent instanceof Node ? (Node)pathComponent : null; return node != null && node.childrenValid ? node.children : Collections.emptyList(); } }; walker.start(root); walker.promise().onProcessed(path -> consumer.consume(path == null ? null : path.getLastPathComponent())); } }); }