void (RefManager refManager) { List<RefElement> roots = new ArrayList<>(); MultiMap<RefElement, RefElement> entitiesWithParents = new MultiMap<>(); refManager.iterate(new RefVisitor() { @Override public void visitElement(@NotNull RefEntity elem) { if (elem instanceof RefElement refElement) { entitiesWithParents.put(refElement, refElement.getInReferences()); if (refElement.getInReferences().isEmpty() || refElement.getInReferences().contains(refElement)) { roots.add(refElement); } } } }); StringBuilder result = new StringBuilder("\n"); for (RefElement root : roots) { List<List<RefElement>> paths = new ArrayList<>(); paths.add(new ArrayList<>()); traverse(root, paths, 0); String rootText = String.format("%s %s (owner: %s, reachable: %s, entry: %s):", root.getClass().getSimpleName(), root.getName(), root.getOwner(), root.isReachable(), root.isEntry()); result.append(rootText).append("\n"); for (List<RefElement> path : paths) { if (path.size() <= 1) continue; StringJoiner pathJoiner = new StringJoiner(" --> "); for (int i = 1; i < path.size(); i++) { RefElement element = path.get(i); String elementText = String.format("%s %s (owner: %s, reachable: %s)", element.getClass().getSimpleName(), element.getName(), element.getOwner(), element.isReachable()); pathJoiner.add(elementText); } result.append(" --> ").append(pathJoiner).append("\n"); } } LOG.warn(result.toString()); }