+ /**
+ * Recursively iterates through all child nodes of the specified node and
+ * for those nodes that are of class <code>ofClass</code>, invokes
+ * <code>consumer</code>.
+ *
+ * @param node
+ * @param ofClass
+ * @param consumer
+ */
+ @SuppressWarnings("unchecked")
+ public static <T extends INode> INode forChildrenDeep(INode node, Class<T> ofClass, Function<T, INode> func) {
+ return forChildrenDeep(node, n -> ofClass.isInstance(n) ? func.apply((T) n) : null);
+ }
+
+ public static <T extends INode> INode forChildrenDeep(INode node, Function<INode, INode> func) {
+ INode ret = func.apply(node);
+ if (ret != null)
+ return ret;
+
+ if (node instanceof ParentNode<?>) {
+ if (node instanceof G2DParentNode) {
+ G2DParentNode g2dpn = (G2DParentNode) node;
+ for (IG2DNode n : g2dpn.getSortedNodes()) {
+ INode r = forChildrenDeep(n, func);
+ if (r != null) {
+ return r;
+ }
+ }
+ } else {
+ for (INode n : ((ParentNode<?>) node).getNodes()) {
+ INode r = forChildrenDeep(n, func);
+ if (r != null) {
+ return r;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+