static SliceNode filterTree( SliceNode oldRoot, NullableFunction<SliceNode, SliceNode> filter, PairProcessor<SliceNode, List<SliceNode>> postProcessor) { SliceNode filtered = filter.fun(oldRoot); if (filtered == null) return null; List<SliceNode> childrenFiltered = new ArrayList<SliceNode>(); 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<SliceNode>(childrenFiltered); return filtered; }