/***************************************************************
         * Function: in_dstates
         **************************************************************/
        private int in_dstates
        (
            CBunch bunch
        )
        {
            CDfa dfa;

            if (CUtility.OLD_DEBUG)
            {
                System.Console.Write("Looking for Set : ");
                m_lexGen.print_set(bunch.m_nfa_set);
            }

            dfa = (CDfa)m_spec.m_dfa_sets[bunch.m_nfa_bit];

            if (null != dfa)
            {
                if (CUtility.OLD_DUMP_DEBUG)
                {
                    System.Console.WriteLine(" FOUND!");
                }

                return(dfa.m_label);
            }

            if (CUtility.OLD_DUMP_DEBUG)
            {
                System.Console.WriteLine(" NOT FOUND!");
            }
            return(NOT_IN_DSTATES);
        }
        /***************************************************************
         * function: add_to_dstates
         * Description: Takes as input a CBunch with details of
         * a dfa state that needs to be created.
         * 1) Allocates a new dfa state and saves it in
         * the appropriate CSpec vector.
         * 2) Initializes the fields of the dfa state
         * with the information in the CBunch.
         * 3) Returns index of new dfa.
         **************************************************************/
        private int add_to_dstates
        (
            CBunch bunch
        )
        {
            CDfa dfa;

            if (CUtility.DEBUG)
            {
                CUtility.ASSERT(null != bunch.m_nfa_set);
                CUtility.ASSERT(null != bunch.m_nfa_bit);
                CUtility.ASSERT(null != bunch.m_accept ||
                                CSpec.NONE == bunch.m_anchor);
            }

            /* Allocate, passing CSpec so dfa label can be Set. */
            dfa = CAlloc.newCDfa(m_spec);

            /* Initialize fields, including the mark field. */
            dfa.m_nfa_set = (Vector)bunch.m_nfa_set.Clone();
            dfa.m_nfa_bit = (SparseBitSet)bunch.m_nfa_bit.Clone();
            dfa.m_accept  = bunch.m_accept;
            dfa.m_anchor  = bunch.m_anchor;
            dfa.m_mark    = false;

            /* Register dfa state using BitSet in CSpec Hashtable. */
            m_spec.m_dfa_sets.Add(dfa.m_nfa_bit, dfa);
            /*registerCDfa(dfa);*/

            if (CUtility.OLD_DUMP_DEBUG)
            {
                System.Console.Write("Registering Set : ");
                m_lexGen.print_set(dfa.m_nfa_set);
                System.Console.WriteLine();
            }

            return(dfa.m_label);
        }
        /***************************************************************
         * Function: e_closure
         * Description: Alters and returns input Set.
         **************************************************************/
        private void e_closure
        (
            CBunch bunch
        )
        {
            Stack nfa_stack;
            int   size;
            int   i;
            CNfa  state;

            /* Debug checks. */
            if (CUtility.DEBUG)
            {
                CUtility.ASSERT(null != bunch);
                CUtility.ASSERT(null != bunch.m_nfa_set);
                CUtility.ASSERT(null != bunch.m_nfa_bit);
            }

            bunch.m_accept       = null;
            bunch.m_anchor       = CSpec.NONE;
            bunch.m_accept_index = CUtility.INT_MAX;

            /* Create initial stack. */
            nfa_stack = new Stack();
            size      = bunch.m_nfa_set.size();
            for (i = 0; i < size; ++i)
            {
                state = (CNfa)bunch.m_nfa_set.elementAt(i);

                if (CUtility.DEBUG)
                {
                    CUtility.ASSERT(bunch.m_nfa_bit.Get(state.m_label));
                }

                nfa_stack.Push(state);
            }

            /* Main loop. */
            //while (false == nfa_stack.empty())
            while (nfa_stack.Count > 0)
            {
                state = (CNfa)nfa_stack.Pop();

                if (CUtility.OLD_DUMP_DEBUG)
                {
                    if (null != state.m_accept)
                    {
                        System.Console.WriteLine("Looking at accepting state " + state.m_label
                                                 + " with <"
                                                 + (new string(state.m_accept.m_action, 0,
                                                               state.m_accept.m_action_read))
                                                 + ">");
                    }
                }

                if (null != state.m_accept &&
                    state.m_label < bunch.m_accept_index)
                {
                    bunch.m_accept_index = state.m_label;
                    bunch.m_accept       = state.m_accept;
                    bunch.m_anchor       = state.m_anchor;

                    if (CUtility.OLD_DUMP_DEBUG)
                    {
                        System.Console.WriteLine("Found accepting state " + state.m_label
                                                 + " with <"
                                                 + (new string(state.m_accept.m_action, 0,
                                                               state.m_accept.m_action_read))
                                                 + ">");
                    }

                    if (CUtility.DEBUG)
                    {
                        CUtility.ASSERT(null != bunch.m_accept);
                        CUtility.ASSERT(CSpec.NONE == bunch.m_anchor ||
                                        0 != (bunch.m_anchor & CSpec.END) ||
                                        0 != (bunch.m_anchor & CSpec.START));
                    }
                }

                if (CNfa.EPSILON == state.m_edge)
                {
                    if (null != state.m_next)
                    {
                        if (false == bunch.m_nfa_set.contains(state.m_next))
                        {
                            if (CUtility.DEBUG)
                            {
                                CUtility.ASSERT(false == bunch.m_nfa_bit.Get(state.m_next.m_label));
                            }

                            bunch.m_nfa_bit.Set(state.m_next.m_label);
                            bunch.m_nfa_set.addElement(state.m_next);
                            nfa_stack.Push(state.m_next);
                        }
                    }

                    if (null != state.m_next2)
                    {
                        if (false == bunch.m_nfa_set.contains(state.m_next2))
                        {
                            if (CUtility.DEBUG)
                            {
                                CUtility.ASSERT(false == bunch.m_nfa_bit.Get(state.m_next2.m_label));
                            }

                            bunch.m_nfa_bit.Set(state.m_next2.m_label);
                            bunch.m_nfa_set.addElement(state.m_next2);
                            nfa_stack.Push(state.m_next2);
                        }
                    }
                }
            }

            if (null != bunch.m_nfa_set)
            {
                sortStates(bunch.m_nfa_set);
            }

            return;
        }
        /***************************************************************
         * Function: move
         * Description: Returns null if resulting NFA Set is empty.
         **************************************************************/
        void move
        (
            Vector nfa_set,
            SparseBitSet nfa_bit,
            int b,
            CBunch bunch
        )
        {
            int  size;
            int  index;
            CNfa state;

            bunch.m_nfa_set = null;
            bunch.m_nfa_bit = null;

            size = nfa_set.Count;
            //  System.Console.WriteLine(size);
            for (index = 0; index < size; ++index)
            {
                state = (CNfa)nfa_set.elementAt(index);
                //   System.Console.WriteLine(index+" "+state.m_set);

                if (b == state.m_edge ||
                    (CNfa.CCL == state.m_edge &&
                     true == state.m_set.contains(b)))
                {
                    //     System.Console.WriteLine(state.m_edge+" "+b);
                    if (null == bunch.m_nfa_set)
                    {
                        if (CUtility.DEBUG)
                        {
                            CUtility.ASSERT(null == bunch.m_nfa_bit);
                        }

                        bunch.m_nfa_set = new Vector();

                        /*bunch.m_nfa_bit
                         * = new SparseBitSet(m_spec.m_nfa_states.size());*/
                        bunch.m_nfa_bit = new SparseBitSet();
                    }

                    bunch.m_nfa_set.addElement(state.m_next);

                    /*System.Console.WriteLine("Size of bitset: " + bunch.m_nfa_bit.size());
                     * System.Console.WriteLine("Reference index: " + state.m_next.m_label);
                     * System.out.flush();*/
                    bunch.m_nfa_bit.Set(state.m_next.m_label);
                }
            }

            if (null != bunch.m_nfa_set)
            {
                if (CUtility.DEBUG)
                {
                    CUtility.ASSERT(null != bunch.m_nfa_bit);
                }

                sortStates(bunch.m_nfa_set);
            }

            return;
        }
        /***************************************************************
         * Function: make_dtrans
         * Description: Creates uncompressed CDTrans transition table.
         **************************************************************/
        private void make_dtrans
        (
        )
        /* throws java.lang.CloneNotSupportedException*/
        {
            //CDfa next;
            CDfa    dfa;
            CBunch  bunch;
            int     i;
            int     nextstate;
            int     size;
            CDTrans dtrans;
            CNfa    nfa;
            int     istate;
            int     nstates;

            System.Console.Write("Working on DFA states.");

            /* Reference passing type and initializations. */
            bunch          = new CBunch();
            m_unmarked_dfa = 0;

            /* Allocate mapping array. */
            nstates = m_spec.m_state_rules.Length;
            m_spec.m_state_dtrans = new int[nstates];

            for (istate = 0; nstates > istate; ++istate)
            {
                /* CSA bugfix: if we skip all zero size rules, then
                 * an specification with no rules produces an illegal
                 * lexer (0 states) instead of a lexer that rejects
                 * everything (1 nonaccepting state). [27-Jul-1999]
                 * if (0 == m_spec.m_state_rules[istate].size())
                 * {
                 * m_spec.m_state_dtrans[istate] = CDTrans.F;
                 * continue;
                 * }
                 */

                /* Create start state and initialize fields. */
                //SI:testing
                //bunch.m_nfa_set = (Vector) m_spec.m_state_rules[istate].Clone();
                bunch.m_nfa_set = (Vector)((m_spec.m_state_rules[istate]).Clone());
                sortStates(bunch.m_nfa_set);

                bunch.m_nfa_bit = new SparseBitSet();

                /* Initialize bit Set. */
                size = bunch.m_nfa_set.size();
                for (i = 0; size > i; ++i)
                {
                    nfa = (CNfa)bunch.m_nfa_set.elementAt(i);
                    bunch.m_nfa_bit.Set(nfa.m_label);
                }

                bunch.m_accept       = null;
                bunch.m_anchor       = CSpec.NONE;
                bunch.m_accept_index = CUtility.INT_MAX;

                e_closure(bunch);
                add_to_dstates(bunch);

                m_spec.m_state_dtrans[istate] = m_spec.m_dtrans_vector.size();

                /* Main loop of CDTrans creation. */
                while (null != (dfa = get_unmarked()))
                {
                    System.Console.Write(".");
                    System.Console.Out.Flush();

                    if (CUtility.DEBUG)
                    {
                        CUtility.ASSERT(false == dfa.m_mark);
                    }

                    /* Get first unmarked node, then mark it. */
                    dfa.m_mark = true;

                    /* Allocate new CDTrans, then initialize fields. */
                    dtrans          = new CDTrans(m_spec.m_dtrans_vector.size(), m_spec);
                    dtrans.m_accept = dfa.m_accept;
                    dtrans.m_anchor = dfa.m_anchor;

                    /* Set CDTrans array for each character transition. */
                    for (i = 0; i < m_spec.m_dtrans_ncols; ++i)
                    {
                        if (CUtility.DEBUG)
                        {
                            CUtility.ASSERT(0 <= i);
                            CUtility.ASSERT(m_spec.m_dtrans_ncols > i);
                        }

                        /* Create new dfa Set by attempting character transition. */
                        move(dfa.m_nfa_set, dfa.m_nfa_bit, i, bunch);
                        if (null != bunch.m_nfa_set)
                        {
                            e_closure(bunch);
                        }

                        if (CUtility.DEBUG)
                        {
                            CUtility.ASSERT((null == bunch.m_nfa_set &&
                                             null == bunch.m_nfa_bit) ||
                                            (null != bunch.m_nfa_set &&
                                             null != bunch.m_nfa_bit));
                        }

                        /* Create new state or Set state to empty. */
                        if (null == bunch.m_nfa_set)
                        {
                            nextstate = CDTrans.F;
                        }
                        else
                        {
                            nextstate = in_dstates(bunch);

                            if (NOT_IN_DSTATES == nextstate)
                            {
                                nextstate = add_to_dstates(bunch);
                            }
                        }

                        if (CUtility.DEBUG)
                        {
                            CUtility.ASSERT(nextstate < m_spec.m_dfa_states.Count);
                        }

                        dtrans.m_dtrans[i] = nextstate;
                    }

                    if (CUtility.DEBUG)
                    {
                        CUtility.ASSERT(m_spec.m_dtrans_vector.size() == dfa.m_label);
                    }

                    m_spec.m_dtrans_vector.addElement(dtrans);
                }
            }

            System.Console.WriteLine();
        }