public final ANTLRv3TreeFilter.treeSpec_return treeSpec() throws RecognitionException {
        ANTLRv3TreeFilter.treeSpec_return retval = new ANTLRv3TreeFilter.treeSpec_return();
        retval.start = input.LT(1);

        CommonTree TOKEN_REF12=null;
        ANTLRv3TreeFilter.element_return e = null;


        try {
            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:296:2: ( ^( TREE_BEGIN TOKEN_REF (e= element )* ) -> {elts.size() == 1}? subtree(element=elts.get(0)scop=scopeid=$TOKEN_REF) -> subtree(element=eltsscop=scopeid=$TOKEN_REF))
            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:296:4: ^( TREE_BEGIN TOKEN_REF (e= element )* )
            {
             List<StringTemplate> elts = new LinkedList<StringTemplate>(); 
            match(input,TREE_BEGIN,FOLLOW_TREE_BEGIN_in_treeSpec1507); 

            match(input, Token.DOWN, null); 
            TOKEN_REF12=(CommonTree)match(input,TOKEN_REF,FOLLOW_TOKEN_REF_in_treeSpec1534); 
            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:304:8: (e= element )*
            loop37:
            do {
                int alt37=2;
                int LA37_0 = input.LA(1);

                if ( ((LA37_0>=BLOCK && LA37_0<=SYNPRED)||LA37_0==CHAR_RANGE||(LA37_0>=SEMPRED && LA37_0<=SYN_SEMPRED)||(LA37_0>=TREE_BEGIN && LA37_0<=BANG)||(LA37_0>=TOKEN_REF && LA37_0<=ACTION)||LA37_0==RULE_REF||LA37_0==71||LA37_0==87||LA37_0==89||LA37_0==92) ) {
                    alt37=1;
                }


                switch (alt37) {
            	case 1 :
            	    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:304:10: e= element
            	    {
            	    pushFollow(FOLLOW_element_in_treeSpec1555);
            	    e=element();

            	    state._fsp--;

            	     if (!(e!=null?e.st:null).toString().equals("epsilon")) {
            	                 elts.add((e!=null?e.st:null));
            	               }
            	             

            	    }
            	    break;

            	default :
            	    break loop37;
                }
            } while (true);


            match(input, Token.UP, null); 


            // TEMPLATE REWRITE
            // 312:5: -> {elts.size() == 1}? subtree(element=elts.get(0)scop=scopeid=$TOKEN_REF)
            if (elts.size() == 1) {
                retval.st = templateLib.getInstanceOf("subtree",
              new STAttrMap().put("element", elts.get(0)).put("scop", scope).put("id", TOKEN_REF12));
            }
            else // 318:5: -> subtree(element=eltsscop=scopeid=$TOKEN_REF)
            {
                retval.st = templateLib.getInstanceOf("subtree",
              new STAttrMap().put("element", elts).put("scop", scope).put("id", TOKEN_REF12));
            }


            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return retval;
    }