// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
**********************************************************************
*   Copyright (c) 2002-2016, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*/

package com.ibm.icu.text;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import com.ibm.icu.impl.Assert;
import com.ibm.icu.impl.RBBIDataWrapper;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UProperty;
import com.ibm.icu.text.RBBIRuleBuilder.IntPair;

/**
 *  This class is part of the RBBI rule compiler.
 *  It builds the state transition table used by the RBBI runtime
 *  from the expression syntax tree generated by the rule scanner.
 *
 *  This class is part of the RBBI implementation only.
 *  There is no user-visible public API here.
 */
class RBBITableBuilder {

    //
    //  RBBIStateDescriptor - The DFA is initially constructed as a set of these descriptors,
    //                        one for each state.
    static class RBBIStateDescriptor {
        boolean      fMarked;
        int          fAccepting;
        int          fLookAhead;
        SortedSet<Integer> fTagVals;
        int          fTagsIdx;
        Set<RBBINode> fPositions;                 // Set of parse tree positions associated
                                                  //   with this state.  Unordered (it's a set).
                                                  //   UVector contents are RBBINode *

        int[]        fDtran;                      // Transitions out of this state.
                                                   //   indexed by input character
                                                   //   contents is int index of dest state
                                                   //   in RBBITableBuilder.fDStates

        RBBIStateDescriptor(int maxInputSymbol) {
            fTagVals = new TreeSet<>();
            fPositions = new HashSet<>();
            fDtran = new int[maxInputSymbol+1];    // fDtran needs to be pre-sized.
                                                    //   It is indexed by input symbols, and will
                                                    //   hold  the next state number for each
                                                    //   symbol.
        }
    }


    private  RBBIRuleBuilder  fRB;

    /** The array index into RBBIRuleBuilder.fTreeRoots for the parse tree to operate on. */
    private  int  fRootIx;

    /** D states (Aho's terminology). Index is state number. */
    private  List<RBBIStateDescriptor> fDStates;

    /** Synthesized safe table, a List of row arrays.  */
    private List<short[]>    fSafeTable;

    private static final int MAX_STATE_FOR_8BITS_TABLE = 255;

    /** Map from rule number (fVal in look ahead nodes) to sequential lookahead index. */
    int[] fLookAheadRuleMap;

    //-----------------------------------------------------------------------------
    //
    //  Constructor    for RBBITableBuilder.
    //
    //                 rootNode is an index into the array of root nodes that is held by
    //                          the overall RBBIRuleBuilder.
    //-----------------------------------------------------------------------------
    RBBITableBuilder(RBBIRuleBuilder rb,  int rootNodeIx)  {
           fRootIx     = rootNodeIx;
           fRB         = rb;
           fDStates    = new ArrayList<>();
        }




       //-----------------------------------------------------------------------------
       //
       //   RBBITableBuilder::buildForwardTable  -  This is the main function for building
       //                          the DFA state transition table from the RBBI rules parse tree.
       //
       //-----------------------------------------------------------------------------
       void  buildForwardTable() {
           // If there were no rules, just return.  This situation can easily arise
           //   for the reverse rules.
           if (fRB.fTreeRoots[fRootIx]==null) {
               return;
           }

           //
           // Walk through the tree, replacing any references to $variables with a copy of the
           //   parse tree for the substition expression.
           //
           fRB.fTreeRoots[fRootIx] = fRB.fTreeRoots[fRootIx].flattenVariables();
           if (fRB.fDebugEnv!=null && fRB.fDebugEnv.indexOf("ftree")>=0) {
               System.out.println("Parse tree after flattening variable references.");
               fRB.fTreeRoots[fRootIx].printTree(true);
           }

           //
           // If the rules contained any references to {bof}
           //   add a {bof} <cat> <former root of tree> to the
           //   tree.  Means that all matches must start out with the
           //   {bof} fake character.
           //
           if (fRB.fSetBuilder.sawBOF()) {
               RBBINode bofTop    = new RBBINode(RBBINode.opCat);
               RBBINode bofLeaf   = new RBBINode(RBBINode.leafChar);
               bofTop.fLeftChild  = bofLeaf;
               bofTop.fRightChild = fRB.fTreeRoots[fRootIx];
               bofLeaf.fParent    = bofTop;
               bofLeaf.fVal       = 2;      // Reserved value for {bof}.
               fRB.fTreeRoots[fRootIx] = bofTop;
           }

           //
           // Add a unique right-end marker to the expression.
           //   Appears as a cat-node, left child being the original tree,
           //   right child being the end marker.
           //
           RBBINode cn = new RBBINode(RBBINode.opCat);
           cn.fLeftChild = fRB.fTreeRoots[fRootIx];
           fRB.fTreeRoots[fRootIx].fParent = cn;
           RBBINode endMarkerNode = cn.fRightChild = new RBBINode(RBBINode.endMark);
           cn.fRightChild.fParent = cn;
           fRB.fTreeRoots[fRootIx] = cn;

           //
           //  Replace all references to UnicodeSets with the tree for the equivalent
           //      expression.
           //
           fRB.fTreeRoots[fRootIx].flattenSets();
           if (fRB.fDebugEnv!=null && fRB.fDebugEnv.indexOf("stree")>=0) {
               System.out.println("Parse tree after flattening Unicode Set references.");
               fRB.fTreeRoots[fRootIx].printTree(true);
           }


           //
           // calculate the functions nullable, firstpos, lastpos and followpos on
           // nodes in the parse tree.
           //    See the alogrithm description in Aho.
           //    Understanding how this works by looking at the code alone will be
           //       nearly impossible.
           //
           calcNullable(fRB.fTreeRoots[fRootIx]);
           calcFirstPos(fRB.fTreeRoots[fRootIx]);
           calcLastPos(fRB.fTreeRoots[fRootIx]);
           calcFollowPos(fRB.fTreeRoots[fRootIx]);
           if (fRB.fDebugEnv!=null && fRB.fDebugEnv.indexOf("pos")>=0) {
               System.out.print("\n");
               printPosSets(fRB.fTreeRoots[fRootIx]);
           }

           //
           //  For "chained" rules, modify the followPos sets
           //
           if (fRB.fChainRules) {
               calcChainedFollowPos(fRB.fTreeRoots[fRootIx], endMarkerNode);
           }

           //
           //  BOF (start of input) test fixup.
           //
           if (fRB.fSetBuilder.sawBOF()) {
               bofFixup();
           }

           //
           // Build the DFA state transition tables.
           //
           buildStateTable();
           mapLookAheadRules();
           flagAcceptingStates();
           flagLookAheadStates();
           flagTaggedStates();

           //
           // Update the global table of rule status {tag} values
           // The rule builder has a global vector of status values that are common
           //    for all tables.  Merge the ones from this table into the global set.
           //
           mergeRuleStatusVals();
       }



       //-----------------------------------------------------------------------------
       //
       //   calcNullable.    Impossible to explain succinctly.  See Aho, section 3.9
       //
       //-----------------------------------------------------------------------------
       void calcNullable(RBBINode n) {
           if (n == null) {
               return;
           }
           if (n.fType == RBBINode.setRef ||
               n.fType == RBBINode.endMark ) {
               // These are non-empty leaf node types.
               n.fNullable = false;
               return;
           }

           if (n.fType == RBBINode.lookAhead || n.fType == RBBINode.tag) {
               // Lookahead marker node.  It's a leaf, so no recursion on children.
               // It's nullable because it does not match any literal text from the input stream.
               n.fNullable = true;
               return;
           }


           // The node is not a leaf.
           //  Calculate nullable on its children.
           calcNullable(n.fLeftChild);
           calcNullable(n.fRightChild);

           // Apply functions from table 3.40 in Aho
           if (n.fType == RBBINode.opOr) {
               n.fNullable = n.fLeftChild.fNullable || n.fRightChild.fNullable;
           }
           else if (n.fType == RBBINode.opCat) {
               n.fNullable = n.fLeftChild.fNullable && n.fRightChild.fNullable;
           }
           else if (n.fType == RBBINode.opStar || n.fType == RBBINode.opQuestion) {
               n.fNullable = true;
           }
           else {
               n.fNullable = false;
           }
       }




       //-----------------------------------------------------------------------------
       //
       //   calcFirstPos.    Impossible to explain succinctly.  See Aho, section 3.9
       //
       //-----------------------------------------------------------------------------
       void calcFirstPos(RBBINode n) {
           if (n == null) {
               return;
           }
           if (n.fType == RBBINode.leafChar  ||
               n.fType == RBBINode.endMark   ||
               n.fType == RBBINode.lookAhead ||
               n.fType == RBBINode.tag) {
               // These are non-empty leaf node types.
               n.fFirstPosSet.add(n);
               return;
           }

           // The node is not a leaf.
           //  Calculate firstPos on its children.
           calcFirstPos(n.fLeftChild);
           calcFirstPos(n.fRightChild);

           // Apply functions from table 3.40 in Aho
           if (n.fType == RBBINode.opOr) {
               n.fFirstPosSet.addAll(n.fLeftChild.fFirstPosSet);
               n.fFirstPosSet.addAll(n.fRightChild.fFirstPosSet);
           }
           else if (n.fType == RBBINode.opCat) {
               n.fFirstPosSet.addAll(n.fLeftChild.fFirstPosSet);
               if (n.fLeftChild.fNullable) {
                   n.fFirstPosSet.addAll(n.fRightChild.fFirstPosSet);
               }
           }
           else if (n.fType == RBBINode.opStar ||
                    n.fType == RBBINode.opQuestion ||
                    n.fType == RBBINode.opPlus) {
               n.fFirstPosSet.addAll(n.fLeftChild.fFirstPosSet);
           }
       }



       //-----------------------------------------------------------------------------
       //
       //   calcLastPos.    Impossible to explain succinctly.  See Aho, section 3.9
       //
       //-----------------------------------------------------------------------------
       void calcLastPos(RBBINode n) {
           if (n == null) {
               return;
           }
           if (n.fType == RBBINode.leafChar  ||
               n.fType == RBBINode.endMark   ||
               n.fType == RBBINode.lookAhead ||
               n.fType == RBBINode.tag) {
               // These are non-empty leaf node types.
               n.fLastPosSet.add(n);
               return;
           }

           // The node is not a leaf.
           //  Calculate lastPos on its children.
           calcLastPos(n.fLeftChild);
           calcLastPos(n.fRightChild);

           // Apply functions from table 3.40 in Aho
           if (n.fType == RBBINode.opOr) {
               n.fLastPosSet.addAll(n.fLeftChild.fLastPosSet);
               n.fLastPosSet.addAll(n.fRightChild.fLastPosSet);
           }
           else if (n.fType == RBBINode.opCat) {
               n.fLastPosSet.addAll(n.fRightChild.fLastPosSet);
               if (n.fRightChild.fNullable) {
                   n.fLastPosSet.addAll(n.fLeftChild.fLastPosSet);
               }
           }
           else if (n.fType == RBBINode.opStar     ||
                    n.fType == RBBINode.opQuestion ||
                    n.fType == RBBINode.opPlus) {
               n.fLastPosSet.addAll(n.fLeftChild.fLastPosSet);
           }
       }



       //-----------------------------------------------------------------------------
       //
       //   calcFollowPos.    Impossible to explain succinctly.  See Aho, section 3.9
       //
       //-----------------------------------------------------------------------------
       void calcFollowPos(RBBINode n) {
           if (n == null ||
               n.fType == RBBINode.leafChar ||
               n.fType == RBBINode.endMark) {
               return;
           }

           calcFollowPos(n.fLeftChild);
           calcFollowPos(n.fRightChild);

           // Aho rule #1
           if (n.fType == RBBINode.opCat) {
               for (RBBINode i /* is 'i' in Aho's description */ : n.fLeftChild.fLastPosSet) {
                   i.fFollowPos.addAll(n.fRightChild.fFirstPosSet);
               }
           }

           // Aho rule #2
           if (n.fType == RBBINode.opStar ||
               n.fType == RBBINode.opPlus) {
               for (RBBINode i /* again, n and i are the names from Aho's description */ : n.fLastPosSet) {
                   i.fFollowPos.addAll(n.fFirstPosSet);
               }
           }
       }

       //-----------------------------------------------------------------------------
       //
       //           addRuleRootNodes    Recursively walk a parse tree, adding all nodes flagged
       //                               as roots of a rule to a destination vector.
       //
       //-----------------------------------------------------------------------------
       void addRuleRootNodes(List<RBBINode> dest, RBBINode node) {
           if (node == null) {
               return;
           }
           if (node.fRuleRoot) {
               dest.add(node);
               // Note: rules cannot nest. If we found a rule start node,
               //       no child node can also be a start node.
               return;
           }
           addRuleRootNodes(dest, node.fLeftChild);
           addRuleRootNodes(dest, node.fRightChild);
       }

       //-----------------------------------------------------------------------------
       //
       //   calcChainedFollowPos.    Modify the previously calculated followPos sets
       //                            to implement rule chaining.  NOT described by Aho
       //
       //-----------------------------------------------------------------------------
       void calcChainedFollowPos(RBBINode tree, RBBINode endMarkNode) {

           List<RBBINode> leafNodes      = new ArrayList<>();

           // get a list all leaf nodes
           tree.findNodes(leafNodes, RBBINode.leafChar);

           // Collect all leaf nodes that can start matches for rules
           // with inbound chaining enabled, which is the union of the
           // firstPosition sets from each of the rule root nodes.

           List<RBBINode> ruleRootNodes = new ArrayList<>();
           addRuleRootNodes(ruleRootNodes, tree);

           Set<RBBINode> matchStartNodes = new HashSet<>();
           for (RBBINode node: ruleRootNodes) {
               if (node.fChainIn) {
                   matchStartNodes.addAll(node.fFirstPosSet);
               }
           }

           // Iterate over all leaf nodes,
           //
           for (RBBINode endNode : leafNodes) {

               // Identify leaf nodes that correspond to overall rule match positions.
               //   These include the endMarkNode in their followPos sets.
               //
               // Note: do not consider other end marker nodes, those that are added to
               //       look-ahead rules. These can't chain; a match immediately stops
               //       further matching. This leaves exactly one end marker node, the one
               //       at the end of the complete tree.

               if (!endNode.fFollowPos.contains(endMarkNode)) {
                   continue;
               }

               // We've got a node that can end a match.

               // !!LBCMNoChain implementation:  If this node's val correspond to
               // the Line Break $CM char class, don't chain from it.
               // TODO:  Remove this. !!LBCMNoChain is deprecated, and is not used
               //             by any of the standard ICU rules.
               if (fRB.fLBCMNoChain) {
                   int c = this.fRB.fSetBuilder.getFirstChar(endNode.fVal);
                   if (c != -1) {
                       // c == -1 occurs with sets containing only the {eof} marker string.
                       int cLBProp = UCharacter.getIntPropertyValue(c, UProperty.LINE_BREAK);
                       if (cLBProp == UCharacter.LineBreak.COMBINING_MARK) {
                           continue;
                       }
                   }
               }


               // Now iterate over the nodes that can start a match, looking for ones
               //   with the same char class as our ending node.
               for (RBBINode startNode : matchStartNodes) {
                   if (startNode.fType != RBBINode.leafChar) {
                       continue;
                   }

                   if (endNode.fVal == startNode.fVal) {
                       // The end val (character class) of one possible match is the
                       //   same as the start of another.

                       // Add all nodes from the followPos of the start node to the
                       //  followPos set of the end node, which will have the effect of
                       //  letting matches transition from a match state at endNode
                       //  to the second char of a match starting with startNode.
                       endNode.fFollowPos.addAll(startNode.fFollowPos);
                   }
               }
           }
       }


       //-----------------------------------------------------------------------------
       //
       //   bofFixup.    Fixup for state tables that include {bof} beginning of input testing.
       //                Do an swizzle similar to chaining, modifying the followPos set of
       //                the bofNode to include the followPos nodes from other {bot} nodes
       //                scattered through the tree.
       //
       //                This function has much in common with calcChainedFollowPos().
       //
       //-----------------------------------------------------------------------------
       void bofFixup() {
           //
           //   The parse tree looks like this ...
           //         fTree root  --.       <cat>
           //                               /     \
           //                            <cat>   <#end node>
           //                           /     \
           //                     <bofNode>   rest
           //                               of tree
           //
           //    We will be adding things to the followPos set of the <bofNode>
           //
           RBBINode  bofNode = fRB.fTreeRoots[fRootIx].fLeftChild.fLeftChild;
           Assert.assrt(bofNode.fType == RBBINode.leafChar);
           Assert.assrt(bofNode.fVal == 2);

           // Get all nodes that can be the start a match of the user-written rules
           //  (excluding the fake bofNode)
           //  We want the nodes that can start a match in the
           //     part labeled "rest of tree"
           //
           Set<RBBINode> matchStartNodes = fRB.fTreeRoots[fRootIx].fLeftChild.fRightChild.fFirstPosSet;
           for (RBBINode startNode : matchStartNodes) {
               if (startNode.fType != RBBINode.leafChar) {
                   continue;
               }

               if (startNode.fVal == bofNode.fVal) {
                   //  We found a leaf node corresponding to a {bof} that was
                   //    explicitly written into a rule.
                   //  Add everything from the followPos set of this node to the
                   //    followPos set of the fake bofNode at the start of the tree.
                   //
                   bofNode.fFollowPos.addAll(startNode.fFollowPos);
               }
           }
       }

       //-----------------------------------------------------------------------------
       //
       //   buildStateTable()    Determine the set of runtime DFA states and the
       //                        transition tables for these states, by the algorithm
       //                        of fig. 3.44 in Aho.
       //
       //                        Most of the comments are quotes of Aho's psuedo-code.
       //
       //-----------------------------------------------------------------------------
       void buildStateTable() {
           //
           // Add a dummy state 0 - the stop state.  Not from Aho.
           int      lastInputSymbol = fRB.fSetBuilder.getNumCharCategories() - 1;
           RBBIStateDescriptor failState = new RBBIStateDescriptor(lastInputSymbol);
           fDStates.add(failState);

           // initially, the only unmarked state in Dstates is firstpos(root),
           //       where toot is the root of the syntax tree for (r)#;
           RBBIStateDescriptor initialState = new RBBIStateDescriptor(lastInputSymbol);
           initialState.fPositions.addAll(fRB.fTreeRoots[fRootIx].fFirstPosSet);
           fDStates.add(initialState);

           // while there is an unmarked state T in Dstates do begin
           for (;;) {
               RBBIStateDescriptor T = null;
               int              tx;
               for (tx=1; tx<fDStates.size(); tx++) {
                   RBBIStateDescriptor temp  = fDStates.get(tx);
                   if (temp.fMarked == false) {
                       T = temp;
                       break;
                   }
               }
               if (T == null) {
                   break;
               }

               // mark T;
               T.fMarked = true;

               // for each input symbol a do begin
               int  a;
               for (a = 1; a<=lastInputSymbol; a++) {
                   // let U be the set of positions that are in followpos(p)
                   //    for some position p in T
                   //    such that the symbol at position p is a;
                   Set<RBBINode> U = null;
                   for (RBBINode p : T.fPositions) {
                       if ((p.fType == RBBINode.leafChar) &&  (p.fVal == a)) {
                           if (U == null) {
                               U = new HashSet<>();
                           }
                           U.addAll(p.fFollowPos);
                       }
                   }

                   // if U is not empty and not in DStates then
                   int  ux = 0;
                   boolean    UinDstates = false;
                   if (U != null) {
                       Assert.assrt(U.size() > 0);
                       int  ix;
                       for (ix=0; ix<fDStates.size(); ix++) {
                           RBBIStateDescriptor temp2;
                           temp2 = fDStates.get(ix);
                           if (U.equals(temp2.fPositions)) {
                               U  = temp2.fPositions;
                               ux = ix;
                               UinDstates = true;
                               break;
                           }
                       }

                       // Add U as an unmarked state to Dstates
                       if (!UinDstates)
                       {
                           RBBIStateDescriptor newState = new RBBIStateDescriptor(lastInputSymbol);
                           newState.fPositions = U;
                           fDStates.add(newState);
                           ux = fDStates.size()-1;
                       }

                       // Dtran[T, a] := U;
                       T.fDtran[a] = ux;
                   }
               }
           }
       }

      /**
       * mapLookAheadRules
       *
       */
      void mapLookAheadRules() {
          fLookAheadRuleMap =  new int[fRB.fScanner.numRules() + 1];

          // Counter used when assigning lookahead rule numbers.
          // Contains the last look-ahead number already in use.
          // The first look-ahead number is 2;
          // Number 1 is reserved for non-lookahead accepting states.
          int laSlotsInUse = RBBIDataWrapper.ACCEPTING_UNCONDITIONAL;

          for (RBBIStateDescriptor sd: fDStates) {
              int laSlotForState = 0;

              // Establish the look-ahead slot for this state, if the state covers
              // any look-ahead nodes - corresponding to the '/' in look-ahead rules.

              // If any of the look-ahead nodes already have a slot assigned, use it,
              // otherwise assign a new one.

              boolean sawLookAheadNode = false;
              for (RBBINode node: sd.fPositions) {
                  if (node.fType != RBBINode.lookAhead) {
                      continue;
                  }
                  sawLookAheadNode = true;
                  int ruleNum = node.fVal;     // Set when rule was originally parsed.
                  assert(ruleNum < fLookAheadRuleMap.length);
                  assert(ruleNum > 0);
                  int laSlot = fLookAheadRuleMap[ruleNum];
                  if (laSlot != 0) {
                      if (laSlotForState == 0) {
                          laSlotForState = laSlot;
                      } else {
                          // TODO: figure out if this can fail, change to setting an error code if so.
                          assert(laSlot == laSlotForState);
                      }
                  }
              }
              if (!sawLookAheadNode) {
                  continue;
              }

              if (laSlotForState == 0) {
                  laSlotForState = ++laSlotsInUse;
              }

              // For each look ahead node covered by this state,
              // set the mapping from the node's rule number to the look ahead slot.
              // There can be multiple nodes/rule numbers going to the same la slot.

              for (RBBINode node: sd.fPositions) {
                  if (node.fType != RBBINode.lookAhead) {
                      continue;
                  }
                  int ruleNum = node.fVal;     // Set when rule was originally parsed.
                  int existingVal = fLookAheadRuleMap[ruleNum];
                  assert(existingVal == 0 || existingVal == laSlotForState);
                  fLookAheadRuleMap[ruleNum] = laSlotForState;
              }
          }

      }

       //-----------------------------------------------------------------------------
       //
       //   flagAcceptingStates    Identify accepting states.
       //                          First get a list of all of the end marker nodes.
       //                          Then, for each state s,
       //                              if s contains one of the end marker nodes in its list of tree positions then
       //                                  s is an accepting state.
       //
       //-----------------------------------------------------------------------------
       void     flagAcceptingStates() {
           List<RBBINode> endMarkerNodes = new ArrayList<>();
           RBBINode    endMarker;
           int     i;
           int     n;

           fRB.fTreeRoots[fRootIx].findNodes(endMarkerNodes, RBBINode.endMark);

           for (i=0; i<endMarkerNodes.size(); i++) {
               endMarker = endMarkerNodes.get(i);
               for (n=0; n<fDStates.size(); n++) {
                   RBBIStateDescriptor sd = fDStates.get(n);
                   if (sd.fPositions.contains(endMarker)) {
                       // Any non-zero value for fAccepting means this is an accepting node.
                       // The value is what will be returned to the user as the break status.
                       // If no other value was specified, force it to ACCEPTING_UNCONDITIONAL (1).

                       if (sd.fAccepting==0) {
                           // State hasn't been marked as accepting yet.  Do it now.
                           sd.fAccepting = fLookAheadRuleMap[endMarker.fVal];
                           if (sd.fAccepting == 0) {
                               sd.fAccepting = RBBIDataWrapper.ACCEPTING_UNCONDITIONAL;
                           }
                       }
                       if (sd.fAccepting==RBBIDataWrapper.ACCEPTING_UNCONDITIONAL && endMarker.fVal != 0) {
                           // Both lookahead and non-lookahead accepting for this state.
                           // Favor the look-ahead, because a look-ahead match needs to
                           // immediately stop the run-time engine. First match, not longest.
                           sd.fAccepting = fLookAheadRuleMap[endMarker.fVal];
                       }
                       // implicit else:
                       // if sd.fAccepting already had a value other than 0 or 1, leave it be.
                   }
               }
           }
       }


       //-----------------------------------------------------------------------------
       //
       //    flagLookAheadStates   Very similar to flagAcceptingStates, above.
       //
       //-----------------------------------------------------------------------------
       void     flagLookAheadStates() {
           List<RBBINode> lookAheadNodes = new ArrayList<>();
           RBBINode    lookAheadNode;
           int     i;
           int     n;

           fRB.fTreeRoots[fRootIx].findNodes(lookAheadNodes, RBBINode.lookAhead);
           for (i=0; i<lookAheadNodes.size(); i++) {
               lookAheadNode = lookAheadNodes.get(i);
               for (n=0; n<fDStates.size(); n++) {
                   RBBIStateDescriptor sd = fDStates.get(n);
                   if (sd.fPositions.contains(lookAheadNode)) {
                       int lookaheadSlot = fLookAheadRuleMap[lookAheadNode.fVal];
                       assert(sd.fLookAhead == 0 || sd.fLookAhead == lookaheadSlot);
                       sd.fLookAhead = lookaheadSlot;
                   }
               }
           }
       }




       //-----------------------------------------------------------------------------
       //
       //    flagTaggedStates
       //
       //-----------------------------------------------------------------------------
       void     flagTaggedStates() {
           List<RBBINode> tagNodes = new ArrayList<>();
           RBBINode    tagNode;
           int     i;
           int     n;

           fRB.fTreeRoots[fRootIx].findNodes(tagNodes, RBBINode.tag);
           for (i=0; i<tagNodes.size(); i++) {                   // For each tag node t (all of 'em)
               tagNode = tagNodes.get(i);

               for (n=0; n<fDStates.size(); n++) {              //    For each state  s (row in the state table)
                   RBBIStateDescriptor sd = fDStates.get(n);
                   if (sd.fPositions.contains(tagNode)) {       //       if  s include the tag node t
                       sd.fTagVals.add(Integer.valueOf(tagNode.fVal));
                   }
               }
           }
       }



       //-----------------------------------------------------------------------------
       //
       //  mergeRuleStatusVals
       //
       //      Allocate positions in the  global array of rule status {tag} values
       //
       //      The RBBI runtime uses an array of {sets of status values} that can
       //      be returned for boundaries.  Each accepting state that has non-zero
       //      status includes an index into this array.  The format of the array
       //      is
       //           Num of status values in group 1
       //              status val
       //              status val
       //              ...
       //           Num of status vals in group 2
       //              status val
       //              status val
       //              ...
       //           etc.
       //
       //
       //-----------------------------------------------------------------------------

       void  mergeRuleStatusVals() {
           //
           //  The basic outline of what happens here is this...
           //
           //    for each state in this state table
           //       if the status tag list for this state is in the global statuses list
           //           record where and
           //           continue with the next state
           //       else
           //           add the tag list for this state to the global list.
           //
           int n;

           // Pre-load a single tag of {0} into the table.
           //   We will need this as a default, for rule sets with no explicit tagging,
           //   or with explicit tagging of {0}.
           if (fRB.fRuleStatusVals.size() == 0) {
               fRB.fRuleStatusVals.add(Integer.valueOf(1));    // Num of statuses in group
               fRB.fRuleStatusVals.add(Integer.valueOf(0));    //   and our single status of zero

               SortedSet<Integer> s0 = new TreeSet<>();        // mapping for rules with no explicit tagging
               fRB.fStatusSets.put(s0, Integer.valueOf(0));    //   (key is an empty set).

               SortedSet<Integer> s1 = new TreeSet<>();        // mapping for rules with explicit tagging of {0}
               s1.add(Integer.valueOf(0));
               fRB.fStatusSets.put(s1, Integer.valueOf(0));
           }

           //    For each state, check whether the state's status tag values are
           //       already entered into the status values array, and add them if not.
           for (n=0; n<fDStates.size(); n++) {
               RBBIStateDescriptor sd = fDStates.get(n);
               Set<Integer> statusVals = sd.fTagVals;
               Integer arrayIndexI = fRB.fStatusSets.get(statusVals);
               if (arrayIndexI == null) {
                   // This is the first encounter of this set of status values.
                   //   Add them to the statusSets map, This map associates
                   //   the set of status values with an index in the runtime status
                   //   values array.
                   arrayIndexI = Integer.valueOf(fRB.fRuleStatusVals.size());
                   fRB.fStatusSets.put(statusVals, arrayIndexI);

                   // Add the new set of status values to the vector of values that
                   //   will eventually become the array used by the runtime engine.
                   fRB.fRuleStatusVals.add(Integer.valueOf(statusVals.size()));
                   fRB.fRuleStatusVals.addAll(statusVals);
               }

               // Save the runtime array index back into the state descriptor.
               sd.fTagsIdx = arrayIndexI.intValue();
           }
       }







       //-----------------------------------------------------------------------------
       //
       //  printPosSets   Debug function.  Dump Nullable, firstpos, lastpos and followpos
       //                 for each node in the tree.
       //
       //-----------------------------------------------------------------------------

       void printPosSets(RBBINode n) {
           if (n==null) {
               return;
           }
           RBBINode.printNode(n);
           System.out.print("         Nullable:  " + n.fNullable);

           System.out.print("         firstpos:  ");
           printSet(n.fFirstPosSet);

           System.out.print("         lastpos:   ");
           printSet(n.fLastPosSet);

           System.out.print("         followpos: ");
           printSet(n.fFollowPos);

           printPosSets(n.fLeftChild);
           printPosSets(n.fRightChild);
       }



       /**
        *  Find duplicate (redundant) character classes. Begin looking with categories.first.
        *  Duplicates, if found are returned in the categories parameter.
        *  This is an iterator-like function, used to identify character classes
        *  (state table columns) that can be eliminated.
        *  @param categories in/out parameter, specifies where to start looking for duplicates,
        *                and returns the first pair of duplicates found, if any.
        *  @return true if duplicate char classes were found, false otherwise.
        *  @internal
        */
       boolean findDuplCharClassFrom(RBBIRuleBuilder.IntPair categories) {
           int numStates = fDStates.size();
           int numCols = fRB.fSetBuilder.getNumCharCategories();

           int table_base = 0;
           int table_dupl = 0;
           for (; categories.first < numCols-1; ++categories.first) {
               // Note: dictionary & non-dictionary columns cannot be merged.
               //       The limitSecond value prevents considering mixed pairs.
               //       Dictionary categories are >= DictCategoriesStart.
               //       Non dict categories are   <  DictCategoriesStart.
               int limitSecond = categories.first < fRB.fSetBuilder.getDictCategoriesStart() ?
                   fRB.fSetBuilder.getDictCategoriesStart() : numCols;
               for (categories.second=categories.first+1; categories.second < limitSecond; ++categories.second) {
                   for (int state=0; state<numStates; state++) {
                       RBBIStateDescriptor sd = fDStates.get(state);
                       table_base = sd.fDtran[categories.first];
                       table_dupl = sd.fDtran[categories.second];
                       if (table_base != table_dupl) {
                           break;
                       }
                   }
                   if (table_base == table_dupl) {
                       return true;
                   }
               }
           }
           return false;
       }

       /**
        * Remove a column from the state table. Used when two character categories
        * have been found equivalent, and merged together, to eliminate the unneeded table column.
        */
       void removeColumn(int column) {
           int numStates = fDStates.size();
           for (int state=0; state<numStates; state++) {
               RBBIStateDescriptor sd = fDStates.get(state);
               assert(column < sd.fDtran.length);
               int[] newArray = Arrays.copyOf(sd.fDtran, sd.fDtran.length - 1);
               System.arraycopy(sd.fDtran, column+1, newArray, column, newArray.length - column);
               sd.fDtran = newArray;
           }
       }


       /**
        *  Find duplicate (redundant) states, beginning at the specified pair,
        *  within this state table. This is an iterator-like function, used to
        *  identify states (state table rows) that can be eliminated.
        *  @param states in/out parameter, specifies where to start looking for duplicates,
        *                and returns the first pair of duplicates found, if any.
        *  @return true if duplicate states were found, false otherwise.
        *  @internal
        */
       boolean findDuplicateState(RBBIRuleBuilder.IntPair states) {
           int numStates = fDStates.size();
           int numCols = fRB.fSetBuilder.getNumCharCategories();

           for (; states.first<numStates-1; ++states.first) {
               RBBIStateDescriptor firstSD = fDStates.get(states.first);
               for (states.second=states.first+1; states.second<numStates; ++states.second) {
                   RBBIStateDescriptor duplSD = fDStates.get(states.second);
                   if (firstSD.fAccepting != duplSD.fAccepting ||
                           firstSD.fLookAhead != duplSD.fLookAhead ||
                           firstSD.fTagsIdx   != duplSD.fTagsIdx) {
                       continue;
                   }
                   boolean rowsMatch = true;
                   for (int col=0; col < numCols; ++col) {
                       int firstVal = firstSD.fDtran[col];
                       int duplVal = duplSD.fDtran[col];
                       if (!((firstVal == duplVal) ||
                               ((firstVal == states.first || firstVal == states.second) &&
                                       (duplVal  == states.first || duplVal  == states.second)))) {
                           rowsMatch = false;
                           break;
                       }
                   }
                   if (rowsMatch) {
                       return true;
                   }
               }
           }
           return false;
       }

       /**
        *  Find the next duplicate state in the safe reverse table. An iterator function.
        *  @param states in/out parameter, specifies where to start looking for duplicates,
        *                and returns the first pair of duplicates found, if any.
        *  @return true if duplicate states were found, false otherwise.
        *  @internal
        */
       boolean findDuplicateSafeState(RBBIRuleBuilder.IntPair states) {
           int numStates = fSafeTable.size();

           for (; states.first<numStates-1; ++states.first) {
               short[] firstRow = fSafeTable.get(states.first);
               for (states.second=states.first+1; states.second<numStates; ++states.second) {
                   short[] duplRow = fSafeTable.get(states.second);
                   boolean rowsMatch = true;
                   int numCols = firstRow.length;
                   for (int col=0; col < numCols; ++col) {
                       int firstVal = firstRow[col];
                       int duplVal = duplRow[col];
                       if (!((firstVal == duplVal) ||
                               ((firstVal == states.first || firstVal == states.second) &&
                                       (duplVal  == states.first || duplVal  == states.second)))) {
                           rowsMatch = false;
                           break;
                       }
                   }
                   if (rowsMatch) {
                       return true;
                   }
               }
           }
           return false;
       }

       /**
        * Remove a duplicate state (row) from the state table. All references to the deleted (second) state
        * are redirected to first state.
        * @param duplStates The duplicate pair of states.
        * @internal
        */
       void removeState(IntPair duplStates) {
           final int keepState = duplStates.first;
           final int duplState = duplStates.second;
           assert(keepState < duplState);
           assert(duplState < fDStates.size());

           fDStates.remove(duplState);

           int numStates = fDStates.size();
           int numCols = fRB.fSetBuilder.getNumCharCategories();
           for (int state=0; state<numStates; ++state) {
               RBBIStateDescriptor sd = fDStates.get(state);
               for (int col=0; col<numCols; col++) {
                   int existingVal = sd.fDtran[col];
                   int newVal = existingVal;
                   if (existingVal == duplState) {
                       newVal = keepState;
                   } else if (existingVal > duplState) {
                       newVal = existingVal - 1;
                   }
                   sd.fDtran[col] = newVal;
               }
           }
       }

       /**
        * Remove a duplicate state from the safe table.
        * @param duplStates The duplicate pair of states.  The first is kept, the second is removed.
        *                   All references to the second in the state table are retargeted
        *                   to the first.
        * @internal
        */
       void removeSafeState(IntPair duplStates) {
           final int keepState = duplStates.first;
           final int duplState = duplStates.second;
           assert(keepState < duplState);
           assert(duplState < fSafeTable.size());

           fSafeTable.remove(duplState);
           int numStates = fSafeTable.size();
           for (int state=0; state<numStates; ++state) {
               short[] row = fSafeTable.get(state);
               for (int col=0; col<row.length; col++) {
                   int existingVal = row[col];
                   int newVal = existingVal;
                   if (existingVal == duplState) {
                       newVal = keepState;
                   } else if (existingVal > duplState) {
                       newVal = existingVal - 1;
                   }
                   row[col] = (short)newVal;
               }
           }
       }


       /**
        *  Check for, and remove duplicate states (table rows).
        *  @return the number of states removed.
        *  @internal
        */
       int removeDuplicateStates() {
           IntPair dupls = new IntPair(3, 0);
           int numStatesRemoved = 0;

           while (findDuplicateState(dupls)) {
               // System.out.printf("Removing duplicate states (%d, %d)\n", dupls.first, dupls.second);
               removeState(dupls);
               ++numStatesRemoved;
           }
           return numStatesRemoved;
       }


       /**
        *  Calculate the size in bytes of the serialized form of this state transition table,
        *  which is identical to the ICU4C runtime form.
        *  Refer to common/rbbidata.h from ICU4C for the declarations of the structures
        *  being matched by this calculation.
        */
       int  getTableSize()  {
           if (fRB.fTreeRoots[fRootIx] == null) {
               return 0;
           }
           int size    = RBBIDataWrapper.RBBIStateTable.fHeaderSize;    // The header, with no rows to the table.
           int numRows = fDStates.size();
           int numCols = fRB.fSetBuilder.getNumCharCategories();
           boolean use8Bits = numRows <= MAX_STATE_FOR_8BITS_TABLE;
           int rowSize = (use8Bits ? 1 : 2 ) * (RBBIDataWrapper.NEXTSTATES + numCols);
           size   += numRows * rowSize;
           size = (size + 7) & ~7;   // round up to a multiple of 8 bytes
           return size;
       }



       /**
        * Create a RBBIDataWrapper.RBBIStateTable for a newly compiled table.
        * RBBIDataWrapper.RBBIStateTable is similar to struct RBBIStateTable in ICU4C,
        * in common/rbbidata.h
        */
       RBBIDataWrapper.RBBIStateTable exportTable() {
           int                state;
           int                col;

           RBBIDataWrapper.RBBIStateTable table = new RBBIDataWrapper.RBBIStateTable();
           if (fRB.fTreeRoots[fRootIx] == null) {
               return table;
           }

           Assert.assrt(fRB.fSetBuilder.getNumCharCategories() < 0x7fff &&
               fDStates.size() < 0x7fff);
           table.fNumStates = fDStates.size();
           table.fDictCategoriesStart = fRB.fSetBuilder.getDictCategoriesStart();
           boolean use8Bits = table.fNumStates <= MAX_STATE_FOR_8BITS_TABLE;

           // Size of table size in shorts.
           int rowLen = RBBIDataWrapper.NEXTSTATES + fRB.fSetBuilder.getNumCharCategories();   // Row Length in shorts.
           int tableSize;
           if (use8Bits) {
               tableSize = (getTableSize() - RBBIDataWrapper.RBBIStateTable.fHeaderSize);       // fTable length in bytes.
               table.fTable = new char[tableSize];
               table.fRowLen = rowLen;                          // Row length in bytes.
           } else {
               tableSize = (getTableSize() - RBBIDataWrapper.RBBIStateTable.fHeaderSize) / 2;   // fTable length in shorts.
               table.fTable = new char[tableSize];
               table.fRowLen = rowLen * 2;                      // Row length in bytes.
           }

           if (fRB.fLookAheadHardBreak) {
               table.fFlags  |= RBBIDataWrapper.RBBI_LOOKAHEAD_HARD_BREAK;
           }
           if (fRB.fSetBuilder.sawBOF()) {
               table.fFlags  |= RBBIDataWrapper.RBBI_BOF_REQUIRED;
           }
           if (use8Bits) {
               table.fFlags  |= RBBIDataWrapper.RBBI_8BITS_ROWS;
           }

           int numCharCategories = fRB.fSetBuilder.getNumCharCategories();
           for (state=0; state<table.fNumStates; state++) {
               RBBIStateDescriptor sd = fDStates.get(state);
               int row = state*rowLen;
               if (use8Bits) {
                   Assert.assrt (0 <= sd.fAccepting && sd.fAccepting <= 255);
                   Assert.assrt (0 <= sd.fLookAhead && sd.fLookAhead <= 255);
               } else {
                   Assert.assrt (0 <= sd.fAccepting && sd.fAccepting <= 0xffff);
                   Assert.assrt (0 <= sd.fLookAhead && sd.fLookAhead <= 0xffff);
               }
               table.fTable[row + RBBIDataWrapper.ACCEPTING] = (char)sd.fAccepting;
               table.fTable[row + RBBIDataWrapper.LOOKAHEAD] = (char)sd.fLookAhead;
               table.fTable[row + RBBIDataWrapper.TAGSIDX]   = (char)sd.fTagsIdx;
               for (col=0; col<numCharCategories; col++) {
                   if (use8Bits) {
                       Assert.assrt (0 <= sd.fDtran[col] && sd.fDtran[col] <= MAX_STATE_FOR_8BITS_TABLE);
                   }
                   table.fTable[row + RBBIDataWrapper.NEXTSTATES + col] = (char)sd.fDtran[col];
               }
           }
           return table;
       }

       /**
        *   Synthesize a safe state table from the main state table.
        */
       void buildSafeReverseTable() {
           // Safe Reverse table construction is described in more detail in the corresponding
           // function in ICU4C, in source/common/rbbitblb.cpp. Not duplicated here because
           // it is too likely to get out of sync.

           // Each safe pair is stored as two chars in the safePair stringBuilder.
           StringBuilder safePairs = new StringBuilder();

           int numCharClasses = fRB.fSetBuilder.getNumCharCategories();
           int numStates = fDStates.size();

           for (int c1=0; c1<numCharClasses; ++c1) {
               for (int c2=0; c2 < numCharClasses; ++c2) {
                   int wantedEndState = -1;
                   int endState = 0;
                   for (int startState = 1; startState < numStates; ++startState) {
                       RBBIStateDescriptor startStateD = fDStates.get(startState);
                       int s2 = startStateD.fDtran[c1];
                       RBBIStateDescriptor s2StateD = fDStates.get(s2);
                       endState = s2StateD.fDtran[c2];
                       if (wantedEndState < 0) {
                           wantedEndState = endState;
                       } else {
                           if (wantedEndState != endState) {
                               break;
                           }
                       }
                   }
                   if (wantedEndState == endState) {
                       safePairs.append((char)c1);
                       safePairs.append((char)c2);
                       // System.out.printf("(%d, %d) ", c1, c2);
                   }
               }
               // System.out.printf("\n");
           }

           // Populate the initial safe table.
           // The table as a whole is a List<short[]>
           // Row 0 is the stop state.
           // Row 1 is the start sate.
           // Row 2 and beyond are other states, initially one per char class, but
           //   after initial construction, many of the states will be combined, compacting the table.)
           // The String holds the nextState data only. The four leading fields of a row, fAccepting,
           // fLookAhead, etc. are not needed for the safe table, and are omitted at this stage of building.

           assert(fSafeTable == null);
           fSafeTable = new ArrayList<>();
           for (int row=0; row<numCharClasses + 2; ++row) {
               fSafeTable.add(new short[numCharClasses]);
           }

           // From the start state, each input char class transitions to the state for that input.
           short[] startState = fSafeTable.get(1);
           for (int charClass=0; charClass < numCharClasses; ++charClass) {
               // Note: +2 to skip the start & stop state rows.
               startState[charClass] = (short)(charClass+2);
           }

           // Initially make every other state table row look like the start state row
           //    (except for the stop state, which remains all 0)
           for (int row=2; row<numCharClasses+2; ++row) {
               System.arraycopy(startState, 0, fSafeTable.get(row), 0, startState.length);
           }

           // Run through the safe pairs, set the next state to zero when pair has been seen.
           // Zero being the stop state, meaning we found a safe point.
           for (int pairIdx=0; pairIdx<safePairs.length(); pairIdx+=2) {
               int c1 = safePairs.charAt(pairIdx);
               int c2 = safePairs.charAt(pairIdx + 1);

               short[] rowState = fSafeTable.get(c2 + 2);
               rowState[c1] = 0;
           }

           // Remove duplicate or redundant rows from the table.
           RBBIRuleBuilder.IntPair states = new RBBIRuleBuilder.IntPair(1, 0);
           while (findDuplicateSafeState(states)) {
               // System.out.printf("Removing duplicate safe states (%d, %d)\n", states.first, states.second);
               removeSafeState(states);
           }
       }


       /**
        *  Calculate the size of the runtime form of this safe state table.
        */
       int getSafeTableSize() {
           if (fSafeTable == null) {
               return 0;
           }
           int size    = RBBIDataWrapper.RBBIStateTable.fHeaderSize;    // The header, with no rows to the table.
           int numRows = fSafeTable.size();
           int numCols = fSafeTable.get(0).length;
           boolean use8Bits = numRows <= MAX_STATE_FOR_8BITS_TABLE;

           int rowSize = (use8Bits ? 1 : 2 ) * (RBBIDataWrapper.NEXTSTATES + numCols);
           size += numRows * rowSize;
           // TODO: there are redundant round-up. Figure out best place, get rid of the rest.
           size = (size + 7) & ~7;   // round up to a multiple of 8 bytes
           return size;
       }


       /**
        *  Create a RBBIDataWrapper.RBBIStateTable for the safe reverse table.
        *  RBBIDataWrapper.RBBIStateTable is similar to struct RBBIStateTable in ICU4C,
        *  in common/rbbidata.h
        */
       RBBIDataWrapper.RBBIStateTable exportSafeTable() {
           RBBIDataWrapper.RBBIStateTable table = new RBBIDataWrapper.RBBIStateTable();
           table.fNumStates = fSafeTable.size();
           boolean use8Bits = table.fNumStates <= MAX_STATE_FOR_8BITS_TABLE;
           int numCharCategories = fSafeTable.get(0).length;

           // Size of table size in shorts.
           int rowLen = RBBIDataWrapper.NEXTSTATES + numCharCategories;
           // TODO: tableSize is basically numStates * numCharCategories,
           //       except for alignment padding. Clean up here, and in main exportTable().
           int tableSize = (getSafeTableSize() - RBBIDataWrapper.RBBIStateTable.fHeaderSize);     // fTable length in bytes.
           if (use8Bits) {
               table.fFlags  |= RBBIDataWrapper.RBBI_8BITS_ROWS;
               table.fTable = new char[tableSize];
               table.fRowLen = rowLen;                          // Row length in bytes.
           } else {
               tableSize /= 2;   // fTable length in shorts.
               table.fTable = new char[tableSize];
               table.fRowLen = rowLen * 2;                      // Row length in bytes.
           }

           for (int state=0; state<table.fNumStates; state++) {
               short[] rowArray = fSafeTable.get(state);
               int row = state * rowLen;

               for (int col=0; col<numCharCategories; col++) {
                   if (use8Bits) {
                       Assert.assrt (rowArray[col] <= MAX_STATE_FOR_8BITS_TABLE);
                   }
                   table.fTable[row + RBBIDataWrapper.NEXTSTATES + col] = (char)rowArray[col];
               }
           }
           return table;
       }


       //-----------------------------------------------------------------------------
       //
       //   printSet    Debug function.   Print the contents of a set of Nodes
       //
       //-----------------------------------------------------------------------------

       void printSet(Collection<RBBINode> s) {
           for (RBBINode n : s) {
               RBBINode.printInt(n.fSerialNum, 8);
           }
           System.out.println();
       }



       //-----------------------------------------------------------------------------
       //
       //   printStates    Debug Function.  Dump the fully constructed state transition table.
       //
       //-----------------------------------------------------------------------------

       void printStates() {
           int     c;    // input "character"
           int     n;    // state number

           System.out.print("state |           i n p u t     s y m b o l s \n");
           System.out.print("      | Acc  LA    Tag");
           for (c=0; c<fRB.fSetBuilder.getNumCharCategories(); c++) {
               RBBINode.printInt(c, 4);
           }
           System.out.print("\n");
           System.out.print("      |---------------");
           for (c=0; c<fRB.fSetBuilder.getNumCharCategories(); c++) {
               System.out.print("----");
           }
           System.out.print("\n");

           for (n=0; n<fDStates.size(); n++) {
               RBBIStateDescriptor sd = fDStates.get(n);
               RBBINode.printInt(n, 5);
               System.out.print(" | ");

               RBBINode.printInt(sd.fAccepting, 3);
               RBBINode.printInt(sd.fLookAhead, 4);
               RBBINode.printInt(sd.fTagsIdx, 6);
               System.out.print(" ");
               for (c=0; c<fRB.fSetBuilder.getNumCharCategories(); c++) {
                   RBBINode.printInt(sd.fDtran[c], 4);
               }
               System.out.print("\n");
           }
           System.out.print("\n\n");
       }


       /**
        * Debug Function.  Dump the fully constructed safe reverse table.
        */
       void printReverseTable() {
           int     c;    // input "character"

           System.out.printf("    Safe Reverse Table \n");
           if (fSafeTable == null) {
               System.out.printf("   --- nullptr ---\n");
               return;
           }
           int numCharCategories = fSafeTable.get(0).length;
           System.out.printf("state |           i n p u t     s y m b o l s \n");
           System.out.printf("      | Acc  LA    Tag");
           for (c=0; c< numCharCategories;  c++) {
               System.out.printf(" %2d", c);
           }
           System.out.printf("\n");
           System.out.printf("      |---------------");
           for (c=0; c<numCharCategories; c++) {
               System.out.printf("---");
           }
           System.out.printf("\n");

           for (int n=0; n<fSafeTable.size(); n++) {
               short rowArray[]  = fSafeTable.get(n);
               System.out.printf("  %3d | " , n);
               System.out.printf("%3d %3d %5d ", 0, 0, 0);  // Accepting, LookAhead, Tags
               for (c=0; c<numCharCategories; c++) {
                   System.out.printf(" %2d", rowArray[c]);
               }
               System.out.printf("\n");
           }
           System.out.printf("\n\n");
       }





       //-----------------------------------------------------------------------------
       //
       //   printRuleStatusTable    Debug Function.  Dump the common rule status table
       //
       //-----------------------------------------------------------------------------

       void printRuleStatusTable() {
           int  thisRecord = 0;
           int  nextRecord = 0;
           int      i;
           List<Integer> tbl = fRB.fRuleStatusVals;

           System.out.print("index |  tags \n");
           System.out.print("-------------------\n");

           while (nextRecord < tbl.size()) {
               thisRecord = nextRecord;
               nextRecord = thisRecord + tbl.get(thisRecord).intValue() + 1;
               RBBINode.printInt(thisRecord, 7);
               for (i=thisRecord+1; i<nextRecord; i++) {
                   int val = tbl.get(i).intValue();
                   RBBINode.printInt(val, 7);
               }
               System.out.print("\n");
           }
           System.out.print("\n\n");
       }



}
