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

        ANTLRv3TreeFilter.element_return e = null;


        try {
            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:183:3: ( ^( ALT (e= element )+ EOA ) -> {elts.size() == 1}? {elts.get(0)} -> seq(element=elts) | ^( ALT EPSILON EOA ) -> {%{\"[>EPSILON<]\"}})
            int alt27=2;
            int LA27_0 = input.LA(1);

            if ( (LA27_0==ALT) ) {
                int LA27_1 = input.LA(2);

                if ( (LA27_1==DOWN) ) {
                    int LA27_2 = input.LA(3);

                    if ( (LA27_2==EPSILON) ) {
                        alt27=2;
                    }
                    else if ( ((LA27_2>=BLOCK && LA27_2<=SYNPRED)||LA27_2==CHAR_RANGE||(LA27_2>=SEMPRED && LA27_2<=SYN_SEMPRED)||(LA27_2>=TREE_BEGIN && LA27_2<=BANG)||(LA27_2>=TOKEN_REF && LA27_2<=ACTION)||LA27_2==RULE_REF||LA27_2==71||LA27_2==87||LA27_2==89||LA27_2==92) ) {
                        alt27=1;
                    }
                    else {
                        NoViableAltException nvae =
                            new NoViableAltException("", 27, 2, input);

                        throw nvae;
                    }
                }
                else {
                    NoViableAltException nvae =
                        new NoViableAltException("", 27, 1, input);

                    throw nvae;
                }
            }
            else {
                NoViableAltException nvae =
                    new NoViableAltException("", 27, 0, input);

                throw nvae;
            }
            switch (alt27) {
                case 1 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:183:5: ^( ALT (e= element )+ EOA )
                    {
                     List<StringTemplate> elts = new LinkedList<StringTemplate>(); 
                    match(input,ALT,FOLLOW_ALT_in_alternative930); 

                    match(input, Token.DOWN, null); 
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:186:8: (e= element )+
                    int cnt26=0;
                    loop26:
                    do {
                        int alt26=2;
                        int LA26_0 = input.LA(1);

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


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

                    	    state._fsp--;

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

                    	    }
                    	    break;

                    	default :
                    	    if ( cnt26 >= 1 ) break loop26;
                                EarlyExitException eee =
                                    new EarlyExitException(26, input);
                                throw eee;
                        }
                        cnt26++;
                    } while (true);

                    match(input,EOA,FOLLOW_EOA_in_alternative973); 

                    match(input, Token.UP, null); 


                    // TEMPLATE REWRITE
                    // 195:5: -> {elts.size() == 1}? {elts.get(0)}
                    if (elts.size() == 1) {
                        retval.st = elts.get(0);
                    }
                    else // 196:5: -> seq(element=elts)
                    {
                        retval.st = templateLib.getInstanceOf("seq",
                      new STAttrMap().put("element", elts));
                    }


                    }
                    break;
                case 2 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:200:5: ^( ALT EPSILON EOA )
                    {
                    match(input,ALT,FOLLOW_ALT_in_alternative1027); 

                    match(input, Token.DOWN, null); 
                    match(input,EPSILON,FOLLOW_EPSILON_in_alternative1029); 
                    match(input,EOA,FOLLOW_EOA_in_alternative1038); 

                    match(input, Token.UP, null); 


                    // TEMPLATE REWRITE
                    // 204:6: -> {%{\"[>EPSILON<]\"}}
                    {
                        retval.st = new StringTemplate(templateLib,"[>EPSILON<]");
                    }


                    }
                    break;

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