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 dup(Tree t) {
   if (t == null) {
     return null;
   }
   GrammarAST dup_t = new GrammarAST();
   dup_t.initialize(t);
   return dup_t;
 }
 public void _findAllType(int ttype, List<GrammarAST> nodes) {
   // check this node (the root) first
   if (this.getType() == ttype) nodes.add(this);
   // check children
   for (int i = 0; i < getChildCount(); i++) {
     GrammarAST child = (GrammarAST) getChild(i);
     child._findAllType(ttype, nodes);
   }
 }
 /**
  * Duplicate a tree, assuming this is a root node of a tree-- duplicate that node and what's
  * below; ignore siblings of root node.
  */
 public static GrammarAST dupTreeNoActions(GrammarAST t, GrammarAST parent) {
   if (t == null) {
     return null;
   }
   GrammarAST result = (GrammarAST) t.dupNode();
   for (GrammarAST subchild : getChildrenForDupTree(t)) {
     result.addChild(dupTreeNoActions(subchild, result));
   }
   return result;
 }
 public void setTreeEnclosingRuleNameDeeply(String rname) {
   enclosingRuleName = rname;
   if (getChildCount() == 0) return;
   for (Object child : getChildren()) {
     if (!(child instanceof GrammarAST)) {
       continue;
     }
     GrammarAST grammarAST = (GrammarAST) child;
     grammarAST.setTreeEnclosingRuleNameDeeply(rname);
   }
 }
 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;
 }
 /**
  * Make nodes unique based upon Token so we can add them to a Set; if not a GrammarAST, check
  * type.
  */
 @Override
 public boolean equals(Object ast) {
   if (this == ast) {
     return true;
   }
   if (!(ast instanceof GrammarAST)) {
     return this.getType() == ((Tree) ast).getType();
   }
   GrammarAST t = (GrammarAST) ast;
   return token.getLine() == t.getLine()
       && token.getCharPositionInLine() == t.getCharPositionInLine();
 }