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

        try {
            // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:462:2: ( ^( TEMPLATE ID rewrite_template_args ( DOUBLE_QUOTE_STRING_LITERAL | DOUBLE_ANGLE_STRING_LITERAL ) ) | rewrite_template_ref | rewrite_indirect_template_head | ACTION )
            int alt48=4;
            alt48 = dfa48.predict(input);
            switch (alt48) {
                case 1 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:462:6: ^( TEMPLATE ID rewrite_template_args ( DOUBLE_QUOTE_STRING_LITERAL | DOUBLE_ANGLE_STRING_LITERAL ) )
                    {
                    match(input,TEMPLATE,FOLLOW_TEMPLATE_in_rewrite_template2353); 

                    match(input, Token.DOWN, null); 
                    match(input,ID,FOLLOW_ID_in_rewrite_template2355); 
                    pushFollow(FOLLOW_rewrite_template_args_in_rewrite_template2357);
                    rewrite_template_args();

                    state._fsp--;

                    if ( (input.LA(1)>=DOUBLE_QUOTE_STRING_LITERAL && input.LA(1)<=DOUBLE_ANGLE_STRING_LITERAL) ) {
                        input.consume();
                        state.errorRecovery=false;
                    }
                    else {
                        MismatchedSetException mse = new MismatchedSetException(null,input);
                        throw mse;
                    }


                    match(input, Token.UP, null); 

                    }
                    break;
                case 2 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:465:4: rewrite_template_ref
                    {
                    pushFollow(FOLLOW_rewrite_template_ref_in_rewrite_template2380);
                    rewrite_template_ref();

                    state._fsp--;


                    }
                    break;
                case 3 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:466:4: rewrite_indirect_template_head
                    {
                    pushFollow(FOLLOW_rewrite_indirect_template_head_in_rewrite_template2385);
                    rewrite_indirect_template_head();

                    state._fsp--;


                    }
                    break;
                case 4 :
                    // back-end/koopa/trees/antlr/filter/generator/ANTLRv3TreeFilter.g:467:4: ACTION
                    {
                    match(input,ACTION,FOLLOW_ACTION_in_rewrite_template2390); 

                    }
                    break;

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