public final @NotNull TreeTraversal cached(final Map<Object, Object> cache) {
    return intercept("CACHED", new TraversalInterceptor() {
      @Override
      public @NotNull <TT> TraversalArgs<TT> intercept(@NotNull TraversalArgs<TT> args) {
        final Function<? super TT, ? extends Iterable<? extends TT>> tree = args.tree;
        final class WrappedTree implements Function<TT, Iterable<? extends TT>> {
          @Override
          public Iterable<? extends TT> fun(TT t) {
            //noinspection unchecked
            return (Iterable<? extends TT>)cache.computeIfAbsent(t, o -> JBIterable.from(tree.fun((TT)o)).collect());
          }
        }
        if (tree instanceof WrappedTree) {
          return args;
        }
        WrappedTree wrappedTree = new WrappedTree();
        return new TraversalArgs<>(args.roots, wrappedTree);
      }
    });
  }
public final @NotNull TreeTraversal cached(final Map<Object, Object> cache)