private static List<GrammarAST> getChildrenForDupTree(GrammarAST t) {
    List<GrammarAST> result = new ArrayList<GrammarAST>();
    for (int i = 0; i < t.getChildCount(); i++) {
      GrammarAST child = (GrammarAST) t.getChild(i);
      int ttype = child.getType();
      if (ttype == ANTLRParser.REWRITES
          || ttype == ANTLRParser.REWRITE
          || ttype == ANTLRParser.ACTION) {
        continue;
      }

      if (ttype == ANTLRParser.BANG || ttype == ANTLRParser.ROOT) {
        for (GrammarAST subchild : getChildrenForDupTree(child)) result.add(subchild);
      } else {
        result.add(child);
      }
    }
    if (result.size() == 1
        && result.get(0).getType() == ANTLRParser.EOA
        && t.getType() == ANTLRParser.ALT) {
      // can't have an empty alt, insert epsilon
      result.add(0, new GrammarAST(ANTLRParser.EPSILON, "epsilon"));
    }

    return result;
  }
 public static GrammarAST dupTree(GrammarAST t) {
   if (t == null) {
     return null;
   }
   GrammarAST root = dup(t); // make copy of root
   // copy all children of root.
   for (int i = 0; i < t.getChildCount(); i++) {
     GrammarAST child = (GrammarAST) t.getChild(i);
     root.addChild(dupTree(child));
   }
   return root;
 }