Trees { @NonNull public static <T> Iterable<T> breadthFirstIterable( @NonNull T root, @NonNull Function<? super T, ? extends Stream<? extends T>> children) { return new BreadthFirstIterable(root, children); } private  Trees(); @NonNull static Iterable<T> breadthFirstIterable(
            @NonNull T root,
            @NonNull Function<? super T, ? extends Stream<? extends T>> children); @NonNull static Stream<T> breadthFirstStream(
            @NonNull T root,
            @NonNull Function<? super T, ? extends Stream<? extends T>> children); @NonNull static Iterable<T> depthFirstIterable(
            @NonNull T root,
            @NonNull Function<? super T, ? extends Stream<? extends T>> children); @NonNull static Stream<T> depthFirstStream(
            @NonNull T root,
            @NonNull Function<? super T, ? extends Stream<? extends T>> children); static void prettyPrint(
            @NonNull T root,
            @NonNull Function<? super T, ? extends Stream<? extends T>> children,
            @NonNegative int maxLevel,
            @NonNull Function<? super T, ? extends CharSequence> toString,
            @NonNull Appendable appendable); @NonNull static String prettyPrintToString(
            @NonNull T root,
            @NonNull Function<? super T, ? extends Stream<? extends T>> children,
            @NonNegative int maxLevel,
            @NonNull Function<? super T, ? extends CharSequence> toString);  }
@Test public void testBreadthFirstIterable() { Node n1 = new Node("1"); Node n2 = new Node("2"); n1.children.add(n2); Node n3 = new Node("3"); n1.children.add(n3); Node n4 = new Node("4"); n1.children.add(n4); n2.children.add(new Node("5")); n2.children.add(new Node("6")); assertThat(Trees.breadthFirstStream(n1, Node::childrenStream).map(Node::getName)) .containsExactly("1", "2", "3", "4", "5", "6"); }