SliceNode (SliceNode oldRoot, NullableFunction<? super SliceNode, ? extends SliceNode> filter, PairProcessor<? super SliceNode, ? super List<SliceNode>> postProcessor) { SliceNode filtered = filter.fun(oldRoot); if (filtered == null) return null; List<SliceNode> childrenFiltered = new ArrayList<>(); if (oldRoot.myCachedChildren != null) { for (SliceNode child : oldRoot.myCachedChildren) { SliceNode childFiltered = filterTree(child, filter,postProcessor); if (childFiltered != null) { childrenFiltered.add(childFiltered); } } } boolean success = postProcessor == null || postProcessor.process(filtered, childrenFiltered); if (!success) return null; filtered.myCachedChildren = new ArrayList<>(childrenFiltered); return filtered; }