+ public static boolean parentIsInSet(Set<Node> set, Node node) {
+ for (Node n = node.getParent(); n != null; n = n.getParent())
+ if (set.contains(n))
+ return true;
+ return false;
+ }
+
+ public static Set<Node> depthFirstFilter(Predicate<Node> filter, Collection<Node> nodes) {
+ Set<Node> result = new TreeSet<>(Node.CASE_INSENSITIVE_COMPARATOR);
+ for (Node n : nodes) {
+ Node newNode = depthFirstFilterRec(filter, n, null);
+ if (newNode != null)
+ result.add(newNode);
+ }
+ return result;
+ }
+
+ public static Node depthFirstFilter(Predicate<Node> filter, Node n) {
+ return depthFirstFilterRec(filter, n, null);
+ }
+
+ private static Node depthFirstFilterRec(Predicate<Node> filter, Node n, Node newParent) {
+ Collection<Node> children = n.getChildren();
+ if (children.isEmpty())
+ return filter.test(n) ? n.cloneWithoutChildren(newParent) : null;
+
+ Node newNode = n.cloneWithoutChildren(newParent);
+ int childCount = 0;
+ for (Node child : children) {
+ Node newChild = depthFirstFilterRec(filter, child, newNode);
+ if (newChild != null)
+ ++childCount;
+ }
+
+ return childCount > 0 ? newNode : null;
+ }
+