public String toString(Predicate<GExpansion> filter) {
   StringBuilder builder = new StringBuilder();
   this.print(builder, 0, filter);
   return builder.toString();
 }
  private void print(StringBuilder builder, int indent, Predicate<GExpansion> filter) {
    if (!filter.test(this)) return;

    builder.append("\n");
    Utils.printIndent(builder, indent);
    String kindString = kind.toString();
    if (negativeLookahead) kindString = "negative" + kindString;
    builder.append(Utils.lowerCaseFirst(kindString)).append("(");

    switch (kind) {
      case LookAhead:
        if (semanticLookahead != null) {
          builder.append("{ ");
          builder.append(Printer.printToString(semanticLookahead, true).trim());
          builder.append(" }");
          break;
        }
        if (amount != -1) {
          builder.append(amount);
          break;
        }
      case Choice:
      case Sequence:
      case ZeroOrOne:
      case ZeroOrMore:
      case OneOrMore:
        for (GExpansion child : children) {
          child.print(builder, indent + 1, filter);
        }
        builder.append("\n");
        Utils.printIndent(builder, indent);
        break;
      case NonTerminal:
        if (this.name != null) builder.append(this.name).append(", ");
        builder.append(symbol);
        break;
      case Terminal:
        if (this.name != null) builder.append(this.name).append(", ");
        builder.append(symbol);
        break;
      case Action:
        builder.append("{");
        if (action.size() == 1 && action.first().kind() != org.jlato.tree.Kind.IfStmt) {
          builder.append(" ");
          builder.append(Printer.printToString(action.first(), true).trim());
          builder.append(" ");
        } else {
          builder.append("\n");
          Utils.printIndented(action, builder, indent + 1);
          Utils.printIndent(builder, indent);
        }
        builder.append("}");
        break;
      default:
    }

    builder.append(")");
  }
 @Override
 public String toString() {
   StringBuilder builder = new StringBuilder();
   this.print(builder, 0, e -> true);
   return builder.toString();
 }