protected virtual StringTemplate WalkFixedDFAGeneratingStateMachine(
            StringTemplateGroup templates,
            DFA dfa,
            DFAState s,
            int k)
        {
            //System.Console.Out.WriteLine( "walk " + s.stateNumber + " in dfa for decision " + dfa.decisionNumber );
            if (s.IsAcceptState)
            {
                StringTemplate dfaST2 = templates.GetInstanceOf("dfaAcceptState");
                dfaST2.SetAttribute("alt", s.GetUniquelyPredictedAlt());
                return(dfaST2);
            }

            // the default templates for generating a state and its edges
            // can be an if-then-else structure or a switch
            string dfaStateName              = "dfaState";
            string dfaLoopbackStateName      = "dfaLoopbackState";
            string dfaOptionalBlockStateName = "dfaOptionalBlockState";
            string dfaEdgeName = "dfaEdge";

            if (parentGenerator.CanGenerateSwitch(s))
            {
                dfaStateName              = "dfaStateSwitch";
                dfaLoopbackStateName      = "dfaLoopbackStateSwitch";
                dfaOptionalBlockStateName = "dfaOptionalBlockStateSwitch";
                dfaEdgeName = "dfaEdgeSwitch";
            }

            StringTemplate dfaST = templates.GetInstanceOf(dfaStateName);

            if (dfa.NFADecisionStartState.decisionStateType == NFAState.LOOPBACK)
            {
                dfaST = templates.GetInstanceOf(dfaLoopbackStateName);
            }
            else if (dfa.NFADecisionStartState.decisionStateType == NFAState.OPTIONAL_BLOCK_START)
            {
                dfaST = templates.GetInstanceOf(dfaOptionalBlockStateName);
            }
            dfaST.SetAttribute("k", k);
            dfaST.SetAttribute("stateNumber", s.stateNumber);
            dfaST.SetAttribute("semPredState",
                               s.IsResolvedWithPredicates);

            /*
             * string description = dfa.getNFADecisionStartState().Description;
             * description = parentGenerator.target.getTargetStringLiteralFromString( description );
             * //System.Console.Out.WriteLine( "DFA: " + description + " associated with AST " + dfa.getNFADecisionStartState() );
             * if ( description != null )
             * {
             *  dfaST.SetAttribute( "description", description );
             * }
             */
            int      EOTPredicts = NFA.INVALID_ALT_NUMBER;
            DFAState EOTTarget   = null;

            //System.Console.Out.WriteLine( "DFA state " + s.stateNumber );
            for (int i = 0; i < s.NumberOfTransitions; i++)
            {
                Transition edge = (Transition)s.Transition(i);
                //System.Console.Out.WriteLine( "edge " + s.stateNumber + "-" + edge.label.ToString() + "->" + edge.target.stateNumber );
                if (edge.label.Atom == Label.EOT)
                {
                    // don't generate a real edge for EOT; track alt EOT predicts
                    // generate that prediction in the else clause as default case
                    EOTTarget   = (DFAState)edge.target;
                    EOTPredicts = EOTTarget.GetUniquelyPredictedAlt();

                    /*
                     * System.Console.Out.WriteLine("DFA s"+s.stateNumber+" EOT goes to s"+
                     *                 edge.target.stateNumber+" predicates alt "+
                     *                 EOTPredicts);
                     */
                    continue;
                }
                StringTemplate edgeST = templates.GetInstanceOf(dfaEdgeName);
                // If the template wants all the label values delineated, do that
                if (edgeST.GetFormalArgument("labels") != null)
                {
                    List <string> labels = edge.Label.Set.Select(value => parentGenerator.GetTokenTypeAsTargetLabel(value)).ToList();
                    edgeST.SetAttribute("labels", labels);
                }
                else
                { // else create an expression to evaluate (the general case)
                    edgeST.SetAttribute("labelExpr",
                                        parentGenerator.GenLabelExpr(templates, edge, k));
                }

                // stick in any gated predicates for any edge if not already a pred
                if (!edge.label.IsSemanticPredicate)
                {
                    DFAState        target = (DFAState)edge.target;
                    SemanticContext preds  =
                        target.GetGatedPredicatesInNFAConfigurations();
                    if (preds != null)
                    {
                        //System.Console.Out.WriteLine( "preds=" + target.getGatedPredicatesInNFAConfigurations() );
                        StringTemplate predST = preds.GenExpr(parentGenerator,
                                                              parentGenerator.Templates,
                                                              dfa);
                        edgeST.SetAttribute("predicates", predST);
                    }
                }

                StringTemplate targetST =
                    WalkFixedDFAGeneratingStateMachine(templates,
                                                       dfa,
                                                       (DFAState)edge.target,
                                                       k + 1);
                edgeST.SetAttribute("targetState", targetST);
                dfaST.SetAttribute("edges", edgeST);
                //System.Console.Out.WriteLine( "back to DFA " + dfa.decisionNumber + "." + s.stateNumber );
            }

            // HANDLE EOT EDGE
            if (EOTPredicts != NFA.INVALID_ALT_NUMBER)
            {
                // EOT unique predicts an alt
                dfaST.SetAttribute("eotPredictsAlt", EOTPredicts);
            }
            else if (EOTTarget != null && EOTTarget.NumberOfTransitions > 0)
            {
                // EOT state has transitions so must split on predicates.
                // Generate predicate else-if clauses and then generate
                // NoViableAlt exception as else clause.
                // Note: these predicates emanate from the EOT target state
                // rather than the current DFAState s so the error message
                // might be slightly misleading if you are looking at the
                // state number.  Predicates emanating from EOT targets are
                // hoisted up to the state that has the EOT edge.
                for (int i = 0; i < EOTTarget.NumberOfTransitions; i++)
                {
                    Transition     predEdge = (Transition)EOTTarget.Transition(i);
                    StringTemplate edgeST   = templates.GetInstanceOf(dfaEdgeName);
                    edgeST.SetAttribute("labelExpr",
                                        parentGenerator.GenSemanticPredicateExpr(templates, predEdge));
                    // the target must be an accept state
                    //System.Console.Out.WriteLine( "EOT edge" );
                    StringTemplate targetST =
                        WalkFixedDFAGeneratingStateMachine(templates,
                                                           dfa,
                                                           (DFAState)predEdge.target,
                                                           k + 1);
                    edgeST.SetAttribute("targetState", targetST);
                    dfaST.SetAttribute("edges", edgeST);
                }
            }
            return(dfaST);
        }