code: private static <T extends GraphNode<T>> StringBuilder printTree(T node, Formatter<T> formatter,
                                                                      String indent, StringBuilder sb,
                                                                      Predicate<T> nodeFilter,
                                                                      Predicate<T> subTreeFilter) {
          if (nodeFilter.apply(node)) {
              String line = formatter.format(node);
              if (line != null) {
                  sb.append(indent).append(line).append("\n");
                  indent += "  ";
              }
          }
          if (subTreeFilter.apply(node)) {
              for (T sub : node.getChildren()) {
                  printTree(sub, formatter, indent, sb, nodeFilter, subTreeFilter);
              }
          }
          return sb;
      }
docs: private recursion helper