/*
**********************************************************************
*   Copyright (C) 1999 International Business Machines Corporation   *
*   and others. All rights reserved.                                 *
**********************************************************************
*   Date        Name        Description
*   12/9/99     rgillam     Ported from Java
**********************************************************************
*/

#include "unicode\rbbi.h"
#include "rbbi_bld.h"
#include "cmemory.h"
#include "unicode\unicode.h"

//=======================================================================
// RuleBasedBreakIterator.Builder
//=======================================================================
/**
 * The Builder class has the job of constructing a RuleBasedBreakIterator from a
 * textual description.  A Builder is constructed by RuleBasedBreakIterator's
 * constructor, which uses it to construct the iterator itself and then throws it
 * away.
 * <p>The construction logic is separated out into its own class for two primary
 * reasons:
 * <ul><li>The construction logic is quite complicated and large.  Separating it
 * out into its own class means the code must only be loaded into memory while a
 * RuleBasedBreakIterator is being constructed, and can be purged after that.
 * <li>There is a fair amount of state that must be maintained throughout the
 * construction process that is not needed by the iterator after construction.
 * Separating this state out into another class prevents all of the functions that
 * construct the iterator from having to have really long parameter lists,
 * (hopefully) contributing to readability and maintainability.</ul>
 * <p>It'd be really nice if this could be an independent class rather than an
 * inner class, because that would shorten the source file considerably, but
 * making Builder an inner class of RuleBasedBreakIterator allows it direct access
 * to RuleBasedBreakIterator's private members, which saves us from having to
 * provide some kind of "back door" to the Builder class that could then also be
 * used by other classes.
 */

const int32_t
RuleBasedBreakIteratorBuilder::END_STATE_FLAG = 0x8000;

const int32_t
RuleBasedBreakIteratorBuilder::DONT_LOOP_FLAG = 0x4000;

const int32_t
RuleBasedBreakIteratorBuilder::LOOKAHEAD_STATE_FLAG = 0x2000;

const int32_t
RuleBasedBreakIteratorBuilder::ALL_FLAGS = END_STATE_FLAG
        | DONT_LOOP_FLAG | LOOKAHEAD_STATE_FLAG;
 
// constants for various characters
const UChar NULL_CHAR = 0x0000;
const UChar OPEN_PAREN = 0x28;
const UChar CLOSE_PAREN = 0x29;
const UChar OPEN_BRACKET = 0x5b;
const UChar CLOSE_BRACKET = 0x5d;
const UChar OPEN_BRACE = 0x7b;
const UChar CLOSE_BRACE = 0x7d;
const UChar SEMICOLON = 0x3b;
const UChar EQUAL_SIGN = 0x3d;
const UChar MINUS = 0x2d;
const UChar CARET = 0x5e;
const UChar AMPERSAND = 0x26;
const UChar COLON = 0x3a;
const UChar ASTERISK = 0x2a;
const UChar PLUS = 0x2b;
const UChar QUESTION = 0x3f;
const UChar PERIOD = 0x2e;
const UChar PIPE = 0x7c;
const UChar BANG = 0x21;
const UChar SLASH = 0x2f;
const UChar BACKSLASH = 0x5c;

const UChar ASCII_LOW = 0x20;
const UChar ASCII_HI = 0x7f;

const UnicodeString IGNORE_NAME = UnicodeString("$ignore");
        
//============================================================================

/**
 * This class is a completely non-general quick-and-dirty class to make up
 * for the fact that at the time of this writing (12/20/99) there was no
 * general hash table class in the ICU.  When one is created, this class should
 * be removed and the code that depends on this class should be altered to use
 * the regular hash-table class.  This class is just here as a temporary measure
 * until that happens.                          --rtg 12/20/99
 */
class ExpressionList {
private:
    UVector keys;
    UVector sets;
    UVector strings;

public:
    static const UnicodeSet setNotThere; // an empty UnicodeSet we can use as a return value
                                         // in get() when the key isn't found
    static const UnicodeString stringNotThere;
    ExpressionList();
    ~ExpressionList();

    const UnicodeSet& getSet(const UnicodeString& key) const;
    void putSet(const UnicodeString& key, UnicodeSet* valueToAdopt);

    const UnicodeString& getString(const UnicodeString& key) const;
    void putString(const UnicodeString& key, UnicodeString* valueToAdopt);

    const UnicodeString& getKeyAt(int32_t x) const { return *((UnicodeString*)keys[x]); }
    const UnicodeSet& operator[](int32_t x) const { return *((UnicodeSet*)sets[x]); }
    int32_t size() const { return keys.size(); }
};

const UnicodeSet
ExpressionList::setNotThere;

const UnicodeString
ExpressionList::stringNotThere;

ExpressionList::ExpressionList()
{
}

ExpressionList::~ExpressionList()
{
    for (int32_t i = 0; i < keys.size(); i++) {
        delete (UnicodeString*)keys[i];
        delete (UnicodeSet*)sets[i];
        delete (UnicodeString*)strings[i];
    }
}

const UnicodeSet&
ExpressionList::getSet(const UnicodeString& key) const
{
    for (int32_t i = 0; i < keys.size(); i++) {
        if (key == *((UnicodeString*)keys[i])) {
            return *((UnicodeSet*)sets[i]);
        }
    }
    return setNotThere;
}

void
ExpressionList::putSet(const UnicodeString& key, UnicodeSet* valueToAdopt)
{
    const UnicodeSet& theSet = getSet(key);
    if (&theSet != &setNotThere) {
        UnicodeSet* value = (UnicodeSet*)(&theSet);
        value->clear();
        value->addAll(*valueToAdopt);
        delete valueToAdopt;
    }
    else {
        keys.addElement(new UnicodeString(key));
        sets.addElement(valueToAdopt);
        strings.addElement(new UnicodeString);
    }
}

const UnicodeString&
ExpressionList::getString(const UnicodeString& key) const
{
    for (int32_t i = 0; i < keys.size(); i++) {
        if (key == *((UnicodeString*)keys[i])) {
            return *((UnicodeString*)strings[i]);
        }
    }
    return stringNotThere;
}

void
ExpressionList::putString(const UnicodeString& key, UnicodeString* valueToAdopt)
{
    const UnicodeString& theString = getString(key);
    if (&theString != &stringNotThere) {
        UnicodeString* value = (UnicodeString*)(&theString);
        *value = *valueToAdopt;
        delete valueToAdopt;
    }
    else {
        keys.addElement(new UnicodeString(key));
        sets.addElement(new UnicodeSet);
        strings.addElement(valueToAdopt);
    }
}
//============================================================================

#define error(message, position, context) \
    setUpErrorMessage(message, position, context); \
    err = U_PARSE_ERROR; \
    return

void
stringDeleter(void* o) {
    delete (UnicodeString*)o;
}

void
usetDeleter(void* o) {
    delete (UnicodeSet*)o;
}

void
tableRowDeleter(void* o) {
    delete [] (int16_t*)o;
}

void
vectorDeleter(void* o) {
    delete (UVector*)o;
}

void
mergeRowDeleter(void* o) {
    delete [] (int32_t*)o;
}

/**
 * No special construction is required for the Builder.
 */
RuleBasedBreakIteratorBuilder::RuleBasedBreakIteratorBuilder(
                                    RuleBasedBreakIterator& iteratorToBuild)
: iterator(iteratorToBuild),
  tables(new RuleBasedBreakIteratorTables)
{
    iterator.tables = tables;

    tempRuleList.setDeleter(&stringDeleter);
    categories.setDeleter(&usetDeleter);
    tempStateTable.setDeleter(&tableRowDeleter);
    decisionPointStack.setDeleter(&vectorDeleter);
    // decisionPointList, loopingStates, and statesToBackfill (as well as the
    // individual elements in decisionPointStack) don't need deleters--
    // their element type is int32_t
    mergeList.setDeleter(&mergeRowDeleter);
}

RuleBasedBreakIteratorBuilder::~RuleBasedBreakIteratorBuilder()
{
    delete expressions;
}

/**
 * This is the main function for setting up the BreakIterator's tables.  It
 * just vectors different parts of the job off to other functions.
 */
void 
RuleBasedBreakIteratorBuilder::buildBreakIterator(const UnicodeString& description,
                                                  UErrorCode& err)
{
    if (U_FAILURE(err))
        return;

    UnicodeString tempDesc(description);
    
    buildRuleList(tempDesc, err);
    buildCharCategories(err);
    buildStateTable(err);
    buildBackwardsStateTable(err);
}

/**
 * Thus function has three main purposes:
 * <ul><li>Perform general syntax checking on the description, so the rest of the
 * build code can assume that it's parsing a legal description.
 * <li>Split the description into separate rules
 * <li>Perform variable-name substitutions (so that no one else sees variable names)
 * </ul>
 */
void 
RuleBasedBreakIteratorBuilder::buildRuleList(UnicodeString& description,
                                             UErrorCode& err)
{
    if (U_FAILURE(err))
        return;

    // invariants:
    // - parentheses must be balanced: ()[]{}
    // - nothing can be nested inside {}
    // - nothing can be nested inside [] except more []s
    // - pairs of ()[]{} must not be empty
    // - ; can only occur at the outer level
    // - | can only appear inside ()
    // - only one = or / can occur in a single rule
    // - = and / cannot both occur in the same rule
    // - the right-hand side of a = expression must be enclosed in [] or ()
    // - *. ?, and + may not occur at the beginning of a rule, nor may they follow
    //   =, /, (, (, |, }, ;, +, ?, or * (except that ? can follow *)
    // - the rule list must contain at least one / rule (which may or may not 
    //   actually contain a /
    // - no rule may be empty
    // - all printing characters in the ASCII range except letters and digits
    //   are reserved and must be preceded by \
    // - ! may only occur at the beginning of a rule

    // set up a vector to contain the broken-up description (each entry in the
    // vector is a separate rule) and a stack for keeping track of opening
    // punctuation
    UStack parenStack;

    UTextOffset p = 0;
    UTextOffset ruleStart = 0;
    UChar c = 0x0000;
    UChar lastC = 0x0000;
    UChar lastOpen = 0x0000;
    bool_t haveEquals = FALSE;
    bool_t haveSlash = FALSE;
    bool_t sawVarName = FALSE;
    bool_t sawIllegalChar = FALSE;
    int32_t illegalCharPos = 0;
    UChar expectedClose = 0x0000;

    // if the description doesn't end with a semicolon, tack a semicolon onto the end
    if (description.length() != 0 && description[description.length() - 1] != SEMICOLON) {
        description += SEMICOLON;
    }

    // for each character, do...
    while (p < description.length()) {
        c = description[p];
        switch (c) {
            // if the character is opening punctuation, verify that no nesting
            // rules are broken, and push the character onto the stack
            case OPEN_BRACE:
            case OPEN_BRACKET:
            case OPEN_PAREN:
                if (lastOpen == OPEN_BRACE) {
                    error("Can't nest brackets inside {}", p, description);
                }
                if (lastOpen == OPEN_BRACKET && c != OPEN_BRACKET) {
                    error("Can't nest anything in [] but []", p, description);
                }

                // if we see { anywhere except on the left-hand side of =,
                // we must be seeing a variable name that was never defined
                if (c == OPEN_BRACE && (haveEquals || haveSlash)) {
                    error("Unknown variable name", p, description);
                }

                lastOpen = c;
                parenStack.push((void*)c);
                if (c == OPEN_BRACE) {
                    sawVarName = TRUE;
                }
                break;

            // if the character is closing punctuation, verify that it matches the
            // last opening punctuation we saw, and that the brackets contain
            // something, then pop the stack
            case CLOSE_BRACE:
            case CLOSE_BRACKET:
            case CLOSE_PAREN:
                expectedClose = NULL_CHAR;
                switch (lastOpen) {
                    case OPEN_BRACE:
                        expectedClose = CLOSE_BRACE;
                        break;
                    case OPEN_BRACKET:
                        expectedClose = CLOSE_BRACKET;
                        break;
                    case OPEN_PAREN:
                        expectedClose = CLOSE_PAREN;
                        break;
                }
                if (c != expectedClose) {
                    error("Unbalanced parentheses", p, description);
                }
                if (lastC == lastOpen) {
                    error("Parens don't contain anything", p, description);
                }
                parenStack.pop();
                if (!parenStack.empty()) {
                    lastOpen = (UChar)(int32_t)parenStack.peek();
                }
                else {
                    lastOpen = NULL_CHAR;
                }
                break;

            // if the character is an asterisk, make sure it occurs in a place
            // where an asterisk can legally go
            case ASTERISK: 
            case PLUS: 
            case QUESTION:
                switch (lastC) {
                    case EQUAL_SIGN: case SLASH: case OPEN_PAREN: case PIPE:
                    case ASTERISK: case PLUS: case QUESTION: case SEMICOLON:
                    case NULL_CHAR:
                        error("Misplaced *, +, or ?", p, description);

                    default:
                        break;
                }
                break;

            // if the character is an equals sign, make sure we haven't seen another
            // equals sign or a slash yet
            case EQUAL_SIGN:
                if (haveEquals || haveSlash) {
                    error("More than one = or / in rule", p, description);
                }
                haveEquals = TRUE;
                sawIllegalChar = FALSE;
                break;

            // if the character is a slash, make sure we haven't seen another slash
            // or an equals sign yet
            case SLASH:
                if (haveEquals || haveSlash) {
                    error("More than one = or / in rule", p, description);
                }
                if (sawVarName) {
                    error("Unknown variable name", p, description);
                }
                haveSlash = TRUE;
                break;

            // if the character is an exclamation point, make sure it occurs only
            // at the beginning of a rule
            case BANG:
                if (lastC != SEMICOLON && lastC != NULL_CHAR) {
                    error("! can only occur at the beginning of a rule", p, description);
                }
                break;

            // if the character is a backslash, skip the character that follows it
            // (it'll get treated as a literal character)
            case BACKSLASH:
                ++p;
                break;

            // we don't have to do anything special on a period
            case PERIOD:
                break;

            // if the character is a syntax character that can only occur
            // inside [], make sure that it does in fact only occur inside []
            // (or in a variable name)
            case CARET:
            case MINUS:
            case COLON:
            case AMPERSAND:
                if (lastOpen != OPEN_BRACKET && lastOpen != OPEN_BRACE && !sawIllegalChar) {
                    sawIllegalChar = TRUE;
                    illegalCharPos = p;
                }
                break;

            // if the character is a semicolon, do the following...
            case SEMICOLON:
                // if we saw any illegal characters along the way, throw
                // an error
                if (sawIllegalChar) {
                    error("Illegal character", illegalCharPos, description);
                }
            
                // make sure the rule contains something and that there are no
                // unbalanced parentheses or brackets
                if (lastC == SEMICOLON || lastC == NULL_CHAR) {
                    error("Empty rule", p, description);
                }
                if (!parenStack.empty()) {
                    error("Unbalanced parenheses", p, description);
                }

                if (parenStack.empty()) {
                    // if the rule contained an = sign, call processSubstitution()
                    // to replace the substitution name with the substitution text
                    // wherever it appears in the description
                    if (haveEquals) {
                        processSubstitution(description, ruleStart, p + 1, p + 1, err);
                    }
                    else {
                        // otherwise, check to make sure the rule doesn't reference
                        // any undefined substitutions
                        if (sawVarName) {
                            error("Unknown variable name", p, description);
                        }

                        // then add it to tempRuleList
                        UnicodeString* newRule = new UnicodeString();
                        description.extractBetween(ruleStart, p, *newRule);
                        tempRuleList.addElement(newRule);
                    }

                    // and reset everything to process the next rule
                    ruleStart = p + 1;
                    haveEquals = haveSlash = sawVarName = sawIllegalChar = FALSE;
                }
                break;

            // if the character is a vertical bar, check to make sure that it
            // occurs inside a () expression and that the character that precedes
            // it isn't also a vertical bar
            case PIPE:
                if (lastC == PIPE) {
                    error("Empty alternative", p, description);
                }
                if (parenStack.empty() || lastOpen != OPEN_PAREN) {
                    error("Misplaced |", p, description);
                }
                break;

            // if the character is anything else (escaped characters are
            // skipped and don't make it here), it's an error
            default:
                if (c >= ASCII_LOW && c < ASCII_HI && !Unicode::isLetter(c)
                    && !Unicode::isDigit(c) && !sawIllegalChar) {
                    sawIllegalChar = TRUE;
                    illegalCharPos = p;
                }
                break;
        }
        lastC = c;
        ++p;
    }
    if (tempRuleList.size() == 0) {
        error("No valid rules in description", p, description);
    }
}

/**
 * This function performs variable-name substitutions.  First it does syntax
 * checking on the variable-name definition.  If it's syntactically valid, it
 * then goes through the remainder of the description and does a simple
 * find-and-replace of the variable name with its text.  (The variable text
 * must be enclosed in either [] or () for this to work.)
 */
void
RuleBasedBreakIteratorBuilder::processSubstitution(UnicodeString& description,
                                                   UTextOffset ruleStart,
                                                   UTextOffset ruleEnd,
                                                   UTextOffset startPos,
                                                   UErrorCode& err)
{
    if (U_FAILURE(err))
        return;

    // isolate out the text on either side of the equals sign
    UnicodeString substitutionRule;
    UnicodeString replace;
    UnicodeString replaceWith;

    description.extractBetween(ruleStart, ruleEnd, substitutionRule);
    UTextOffset equalPos = substitutionRule.indexOf(EQUAL_SIGN);
    substitutionRule.extractBetween(0, equalPos, replace);
    substitutionRule.extractBetween(equalPos + 1, substitutionRule.length() - 1, replaceWith);

    // check to see whether the substitution name is something we've declared
    // to be "special".  For RuleBasedBreakIterator itself, this is "$ignore".
    // This function takes care of any extra processing that has to be done
    // with "special" substitution names.
    handleSpecialSubstitution(replace, replaceWith, startPos, description, err);

    // perform various other syntax checks on the rule
    if (replaceWith.length() == 0) {
        error("Nothing on right-hand side of =", startPos, description);
    }
    if (replace.length() == 0) {
        error("Nothing on left-hand side of =", startPos, description);
    }
    if (!(replaceWith[0] == OPEN_BRACKET
            && replaceWith[replaceWith.length() - 1] == CLOSE_BRACKET)
        && !(replaceWith[0] == OPEN_PAREN
            && replaceWith[replaceWith.length() - 1] == CLOSE_PAREN)) {
        error("Illegal right-hand side for =", startPos, description);
    }

    // now go through the rest of the description (which hasn't been broken up
    // into separate rules yet) and replace every occurrence of the
    // substitution name with the substitution body
    if (replace[0] != OPEN_BRACE) {
        replace.insert(0, OPEN_BRACE);
        replace += CLOSE_BRACE;
    }

    description.removeBetween(ruleStart, ruleEnd);

    UTextOffset lastPos = startPos;
    UTextOffset pos = description.indexOf(replace, lastPos);
    while (pos != -1) {
        description.replaceBetween(pos, pos + replace.length(), replaceWith);
        lastPos = pos + replace.length();
        pos = description.indexOf(replace, lastPos);
    }
}

/**
 * This function defines a protocol for handling substitution names that
 * are "special," i.e., that have some property beyond just being
 * substitutions.  At the RuleBasedBreakIterator level, we have one
 * special substitution name, "$ignore".  Subclasses can override this
 * function to add more.  Any special processing that has to go on beyond
 * that which is done by the normal substitution-processing code is done
 * here.
 */
void
RuleBasedBreakIteratorBuilder::handleSpecialSubstitution(const UnicodeString& replace, 
                                                         const UnicodeString& replaceWith,
                                                         int32_t startPos,
                                                         const UnicodeString& description,
                                                         UErrorCode& err)
{
    if (U_FAILURE(err))
        return;

    // if we get a definition for a substitution called "$ignore", it defines
    // the ignore characters for the iterator.  Check to make sure the expression
    // is a [] expression, and if it is, parse it and store the characters off
    // to the side.
    if (replace == IGNORE_NAME) {
        if (replaceWith.charAt(0) == OPEN_PAREN) {
            error("Ignore group can't be enclosed in (", startPos, description);
        }
        ignoreChars = UnicodeSet(replaceWith, err);
    }
}

/**
 * This function provides a hook for subclasses to mess with the character
 * category table.
 */
void
RuleBasedBreakIteratorBuilder::mungeExpressionList()
{
    // base class doesn't do anything-- this is here
    // for subclasses
}

/**
 * This function builds the character category table.  On entry,
 * tempRuleList is a vector of break rules that has had variable names substituted.
 * On exit, the charCategoryTable data member has been initialized to hold the
 * character category table, and tempRuleList's rules have been munged to contain
 * character category numbers everywhere a literal character or a [] expression
 * originally occurred.
 */
void
RuleBasedBreakIteratorBuilder::buildCharCategories(UErrorCode& err)
{
    if (U_FAILURE(err))
        return;

    int32_t bracketLevel = 0;
    UTextOffset p = 0;
    int32_t lineNum = 0;

    // build hash table of every literal character or [] expression in the rule list
    // and derive a UnicodeSet object representing the characters each refers to
    while (lineNum < tempRuleList.size()) {
        UnicodeString* line = (UnicodeString*)(tempRuleList[lineNum]);
        p = 0;
        while (p < line->length()) {
            UChar c = (*line)[p];
            switch (c) {
                // skip over all syntax characters except [
                case OPEN_PAREN: case CLOSE_PAREN: case ASTERISK: case PERIOD: case SLASH:
                case PIPE: case SEMICOLON: case QUESTION: case BANG: case PLUS:
                    break;

                // for [, find the matching ] (taking nested [] pairs into account)
                // and add the whole expression to the expression list
                case OPEN_BRACKET:
                    {
                        UTextOffset q = p + 1;
                        ++bracketLevel;
                        while (q < line->length() && bracketLevel != 0) {
                            c = (*line)[q];
                            if (c == OPEN_BRACKET) {
                                ++bracketLevel;
                            }
                            else if (c == CLOSE_BRACKET) {
                                --bracketLevel;
                            }
                            ++q;
                        }

                        UnicodeString temp;
                        line->extractBetween(p, q, temp);
                        if (&expressions->getSet(temp) == &ExpressionList::setNotThere) {
                            expressions->putSet(temp, new UnicodeSet(temp, err));
                        }
                        p = q - 1;
                    }
                    break;

                // for \ sequences, just move to the next character and treat
                // it as a single character
                case BACKSLASH:
                    ++p;
                    c = (*line)[p];
                    // DON'T break; fall through into "default" clause

                // for an isolated single character, add it to the expression list
                default:
                    {
                        UnicodeString temp;

                        line->extractBetween(p, p + 1, temp);
                        expressions->putSet(temp, new UnicodeSet(temp, err));
                    }
                    break;
            }
            ++p;
        }
        ++lineNum;
    }

    // create the temporary category table (which is a vector of UnicodeSet objects)
    if (ignoreChars.isEmpty()) {
        categories.addElement(new UnicodeSet(ignoreChars));
    }
    else {
        categories.addElement(new UnicodeSet());
    }
    ignoreChars.clear();

    // this is a hook to allow subclasses to add categories on their own
    mungeExpressionList();

    // Derive the character categories.  Go through the existing character categories
    // looking for overlap.  Any time there's overlap, we create a new character
    // category for the characters that overlapped and remove them from their original
    // category.  At the end, any characters that are left in the expression haven't
    // been mentioned in any category, so another new category is created for them.
    // For example, if the first expression is [abc], then a, b, and c will be placed
    // into a single character category.  If the next expression is [bcd], we will first
    // remove b and c from their existing category (leaving a behind), create a new
    // category for b and c, and then create another new category for d (which hadn't
    // been mentioned in the previous expression).
    // At no time should a character ever occur in more than one character category.

    // for each expression in the expressions list, do...
    for (int32_t i = 0; i < expressions->size(); i++) {
        // initialize the working char set to the chars in the current expression
        UnicodeSet e = UnicodeSet((*expressions)[i]);

        // for each category in the category list, do...
        for (int32_t j = categories.size() - 1; !e.isEmpty() && j > 0; j--) {

            // if there's overlap between the current working set of chars
            // and the current category...
            UnicodeSet* that = (UnicodeSet*)(categories[j]);
            UnicodeSet temp = UnicodeSet(e);
            temp.retainAll(*that);
            if (!temp.isEmpty()) {
                // if the current category is not a subset of the current
                // working set of characters, then remove the overlapping
                // characters from the current category and create a new
                // category for them
                if (temp != *that) {
                    that->removeAll(temp);
                    categories.addElement(new UnicodeSet(temp));
                }
                
                // and always remove the overlapping characters from the current
                // working set of characters
                e.removeAll(temp);
            }
        }

        // if there are still characters left in the working char set,
        // add a new category containing them
        if (!e.isEmpty()) {
            categories.addElement(new UnicodeSet(e));
        }
    }

    // we have the ignore characters stored in position 0.  Make an extra pass through
    // the character category list and remove anything from the ignore list that shows
    // up in some other category
    UnicodeSet allChars;
    for (int32_t i = 1; i < categories.size(); i++)
        allChars.addAll(*(UnicodeSet*)(categories[i]));
    UnicodeSet* ignoreChars = (UnicodeSet*)(categories[0]);
    ignoreChars->removeAll(allChars);

    // now that we've derived the character categories, go back through the expression
    // list and replace each UnicodeSet object with a String that represents the
    // character categories that expression refers to.  The String is encoded: each
    // character is a character category number (plus 0x100 to avoid confusing them
    // with syntax characters in the rule grammar)
    for (int32_t i = 0; i < expressions->size(); i++) {
        const UnicodeSet& cs = (*expressions)[i];
        UnicodeString* cats = new UnicodeString;

        // for each category...
        for (int32_t j = 1; j < categories.size(); j++) {

            // if the current expression contains characters in that category...
            if (cs.containsAll(*(UnicodeSet*)(categories[j]))) {

                // then add the encoded category number to the String for this
                // expression
                *cats += (UChar)(0x100 + j);
                if (cs == *(UnicodeSet*)(categories[j])) {
                    break;
                }
            }
        }

        // once we've finished building the encoded String for this expression,
        // replace the UnicodeSet object with it
        expressions->putString(expressions->getKeyAt(i), cats);
    }

    // and finally, we turn the temporary category table into a permanent category
    // table, which is a CompactByteArray. (we skip category 0, which by definition
    // refers to all characters not mentioned specifically in the rules)
    tables->charCategoryTable = ucmp8_open((int8_t)0);

    // for each category...
    for (int32_t i = 0; i < categories.size(); i++) {
        UnicodeSet& chars = *(UnicodeSet*)(categories[i]);
        const UnicodeString& pairs = chars.getPairs();

        // go through the character ranges in the category one by one...
        for (int32_t j = 0; j < pairs.length(); j += 2) {
            // and set the corresponding elements in the CompactArray accordingly
            if (i != 0) {
                ucmp8_setRange(tables->charCategoryTable, pairs[j], pairs[j + 1],
                        (int8_t)i);
            }

            // (category 0 is special-- it's the hiding place for the ignore
            // characters, whose real category number in the CompactArray is
            // -1 [this is because category 0 contains all characters not
            // specifically mentioned anywhere in the rules] )
            else {
                ucmp8_setRange(tables->charCategoryTable, pairs[j], pairs[j + 1],
                    RuleBasedBreakIterator::IGNORE);
            }
        }
    }

    // once we've populated the CompactArray, compact it
    ucmp8_compact(tables->charCategoryTable, 32);

    // initialize numCategories
    numCategories = categories.size();
    tables->numCategories = numCategories;
}

/**
 * This is the function that builds the forward state table.  Most of the real
 * work is done in parseRule(), which is called once for each rule in the
 * description.
 */
void
RuleBasedBreakIteratorBuilder::buildStateTable(UErrorCode& err)
{
    if (U_FAILURE(err))
        return;

    // initialize our temporary state table, and fill it with two states:
    // state 0 is a dummy state that allows state 1 to be the starting state
    // and 0 to represent "stop".  State 1 is added here to seed things
    // before we start parsing
    tempStateTable.addElement(new int16_t[tables->numCategories + 1]);
    tempStateTable.addElement(new int16_t[tables->numCategories + 1]);

    // call parseRule() for every rule in the rule list (except those which
    // start with !, which are actually backwards-iteration rules)
    for (int32_t i = 0; i < tempRuleList.size(); i++) {
        UnicodeString* rule = (UnicodeString*)tempRuleList[i];
        if ((*rule)[0] != BANG) {
            parseRule(*rule, TRUE);
        }
    }

    // finally, use finishBuildingStateTable() to minimize the number of
    // states in the table and perform some other cleanup work
    finishBuildingStateTable(TRUE);
}

/**
 * This is where most of the work really happens.  This routine parses a single
 * rule in the rule description, adding and modifying states in the state
 * table according to the new expression.  The state table is kept deterministic
 * throughout the whole operation, although some ugly postprocessing is needed
 * to handle the *? token.
 */
void
RuleBasedBreakIteratorBuilder::parseRule(const UnicodeString& rule,
                                         bool_t forward)
{
    // algorithm notes:
    //   - The basic idea here is to read successive character-category groups
    //   from the input string.  For each group, you create a state and point
    //   the appropriate entries in the previous state to it.  This produces a
    //   straight line from the start state to the end state.  The {}, *, and (|)
    //   idioms produce branches in this straight line.  These branches (states
    //   that can transition to more than one other state) are called "decision
    //   points."  A list of decision points is kept.  This contains a list of
    //   all states that can transition to the next state to be created.  For a
    //   straight line progression, the only thing in the decision-point list is
    //   the current state.  But if there's a branch, the decision-point list
    //   will contain all of the beginning points of the branch when the next
    //   state to be created represents the end point of the branch.  A stack is
    //   used to save decision point lists in the presence of nested parentheses
    //   and the like.  For example, when a { is encountered, the current decision
    //   point list is saved on the stack and restored when the corresponding }
    //   is encountered.  This way, after the } is read, the decision point list
    //   will contain both the state right before the } _and_ the state before
    //   the whole {} expression.  Both of these states can transition to the next
    //   state after the {} expression.
    //   - one complication arises when we have to stamp a transition value into
    //   an array cell that already contains one.  The updateStateTable() and
    //   mergeStates() functions handle this case.  Their basic approach is to
    //   create a new state that combines the two states that conflict and point
    //   at it when necessary.  This happens recursively, so if the merged states
    //   also conflict, they're resolved in the same way, and so on.  There are
    //   a number of tests aimed at preventing infinite recursion.
    //   - another complication arises with repeating characters.  It's somewhat
    //   ambiguous whether the user wants a greedy or non-greedy match in these cases.
    //   (e.g., whether "[a-z]*abc" means the SHORTEST sequence of letters ending in
    //   "abc" or the LONGEST sequence of letters ending in "abc".  We've adopted
    //   the *? to mean "shortest" and * by itself to mean "longest".  (You get the
    //   same result with both if there's no overlap between the repeating character
    //   group and the group immediately following it.)  Handling the *? token is
    //   rather complicated and involves keeping track of whether a state needs to
    //   be merged (as described above) or merely overwritten when you update one of
    //   its cells, and copying the contents of a state that loops with a *? token
    //   into some of the states that follow it after the rest of the table-building
    //   process is complete ("backfilling").
    // implementation notes:
    //   - This function assumes syntax checking has been performed on the input string
    //   prior to its being passed in here.  It assumes that parentheses are
    //   balanced, all literal characters are enclosed in [] and turned into category
    //   numbers, that there are no illegal characters or character sequences, and so
    //   on.  Violation of these invariants will lead to undefined behavior.
    //   - It'd probably be better to use linked lists rather than UVector and UStack
    //   to maintain the decision point list and stack.  I went for simplicity in
    //   this initial implementation.  If performance is critical enough, we can go
    //   back and fix this later.
    //   -There are a number of important limitations on the *? token.  It does not work
    //   right when followed by a repeating character sequence (e.g., ".*?(abc)*")
    //   (although it does work right when followed by a single repeating character).
    //   It will not always work right when nested in parentheses or braces (although
    //   sometimes it will).  It also will not work right if the group of repeating
    //   characters and the group of characters that follows overlap partially
    //   (e.g., "[a-g]*?[e-j]").  None of these capabilites was deemed necessary for
    //   describing breaking rules we know about, so we left them out for
    //   expeditiousness.
    //   - Rules such as "[a-z]*?abc;" will be treated the same as "[a-z]*?aa*bc;"--
    //   that is, if the string ends in "aaaabc", the break will go before the first
    //   "a" rather than the last one.  Both of these are limitations in the design
    //   of RuleBasedBreakIterator and not limitations of the rule parser.

    UTextOffset p = 0;
    int32_t currentState = 1;   // don't use state number 0; 0 means "stop"
    int32_t lastState = currentState;
    UnicodeString pendingChars;
    UnicodeString temp;

    int16_t* state;
    bool_t sawEarlyBreak = FALSE;

    // if we're adding rules to the backward state table, mark the initial state
    // as a looping state
    if (!forward) {
        loopingStates.addElement((void*)1);
    }

    // put the current state on the decision point list before we start
    decisionPointList.addElement((void*)currentState); // we want currentState to
                                                             // be 1 here...
    currentState = tempStateTable.size() - 1;   // but after that, we want it to be
                                                // 1 less than the state number of the next state
    while (p < rule.length()) {
        UChar c = rule[p];
        clearLoopingStates = FALSE;

        // this section handles literal characters, escaped characters (which are
        // effectively literal characters too), the . token, and [] expressions
        if (c == OPEN_BRACKET
            || c == BACKSLASH
            || Unicode::isLetter(c)
            || Unicode::isDigit(c)
            || c < ASCII_LOW
            || c == PERIOD
            || c >= ASCII_HI) {

            // if we're not on a period, isolate the expression and look up
            // the corresponding category list
            if (c != PERIOD) {
                UTextOffset q = p;

                // if we're on a backslash, the expression is the character
                // after the backslash
                if (c == BACKSLASH) {
                    q = p + 2;
                    ++p;
                }

                // if we're on an opening bracket, scan to the closing bracket
                // to isolate the expression
                else if (c == OPEN_BRACKET) {
                    int32_t bracketLevel = 1;
                    while (bracketLevel > 0) {
                        ++q;
                        c = rule[q];
                        if (c == OPEN_BRACKET) {
                            ++bracketLevel;
                        }
                        else if (c == CLOSE_BRACKET) {
                            --bracketLevel;
                        }
                        else if (c == BACKSLASH) {
                            ++q;
                        }
                    }
                    ++q;
                }

                // otherwise, the expression is just the character itself
                else {
                    q = p + 1;
                }

                // look up the category list for the expression and store it
                // in pendingChars
                rule.extractBetween(p, q, temp);
                pendingChars = expressions->getString(temp);

                // advance the current position past the expression
                p = q - 1;
            }

            // if the character we're on is a period, we end up down here
            else {
                int32_t rowNum = (int32_t)decisionPointList.lastElement();
                state = (int16_t*)tempStateTable[rowNum];

                // if the period is followed by an asterisk, then just set the current
                // state to loop back on itself
                if (p + 1 < rule.length() && rule[p + 1] == ASTERISK && state[0] != 0) {
                    decisionPointList.addElement((void*)state[0]);
                    pendingChars.remove();
                    ++p;
                    if (p + 1 < rule.length() && rule[p + 1] == QUESTION) {
//System.out.println("Saw *?");
                        setLoopingStates(&decisionPointList, decisionPointList);
                        ++p;
                    }
//System.out.println("Saw .*");
                }

                // otherwise, fabricate a category list ("pendingChars") with
                // every category in it
                else {
                    pendingChars.remove();
                    for (int32_t i = 0; i < numCategories; i++)
                        pendingChars += (UChar)(i + 0x100);
                }
            }

            // we'll end up in here for all expressions except for .*, which is
            // special-cased above
            if (pendingChars.length() != 0) {

                // if the expression is followed by an asterisk, then push a copy
                // of the current decision point list onto the stack
                if (p + 1 < rule.length() && (
                    rule[p + 1] == ASTERISK ||
                    rule[p + 1] == QUESTION
                )) {
                    UVector* clone = new UVector;
                    for (int32_t i = 0; i < decisionPointList.size(); i++) {
                        clone->addElement(decisionPointList[i]);
                        // (there's no ownership issue here because the vector
                        // elements are all integers)
                    }
                    decisionPointStack.push(clone);
                }

                // create a new state, add it to the list of states to backfill
                // if we have looping states to worry about, set its "don't make
                // me an accepting state" flag if we've seen a slash, and add
                // it to the end of the state table
                int32_t newState = tempStateTable.size();
                if (loopingStates.size() != 0) {
                    statesToBackfill.addElement((void*)newState);
                }
                state = new int16_t[numCategories + 1];
                if (sawEarlyBreak) {
                    state[numCategories] = DONT_LOOP_FLAG;
                }
                tempStateTable.addElement(state);

                // update everybody in the decision point list to point to
                // the new state (this also performs all the reconciliation
                // needed to make the table deterministic), then clear the
                // decision point list
                updateStateTable(decisionPointList, pendingChars, (int16_t)newState);
                decisionPointList.removeAllElements();

                // add all states created since the last literal character we've
                // seen to the decision point list
                lastState = currentState;
                do {
                    ++currentState;
                    decisionPointList.addElement((void*)currentState);
                } while (currentState + 1 < tempStateTable.size());
            }
        }

        // a * denotes a repeating character or group (* after () is handled separately
        // below).  In addition to restoring the decision point list, modify the
        // current state to point to itself on the appropriate character categories.
        if (c == PLUS || c == ASTERISK || c == QUESTION) {
            // when there's a *, update the current state to loop back on itself
            // on the character categories that caused us to enter this state
            if (c == ASTERISK || c == PLUS) {
                for (int32_t i = lastState + 1; i < tempStateTable.size(); i++) {
                    UVector temp2;
                    temp2.addElement((void*)i);
                    updateStateTable(temp2, pendingChars, (int16_t)(lastState + 1));
                }
            }

            // pop the top element off the decision point stack and merge
            // it with the current decision point list (this causes the divergent
            // paths through the state table to come together again on the next
            // new state)
            if (c == ASTERISK || c == QUESTION) {
                UVector* temp2 = (UVector*)decisionPointStack.pop();
                for (int32_t i = 0; i < temp2->size(); i++)
                    decisionPointList.addElement((*temp2)[i]);
                delete temp2;

                // a ? after a * modifies the behavior of * in cases where there is overlap
                // between the set of characters that repeat and the characters which follow.
                // Without the ?, all states following the repeating state, up to a state which
                // is reached by a character that doesn't overlap, will loop back into the
                // repeating state.  With the ?, the mark states following the *? DON'T loop
                // back into the repeating state.  Thus, "[a-z]*xyz" will match the longest
                // sequence of letters that ends in "xyz," while "[a-z]*? will match the
                // _shortest_ sequence of letters that ends in "xyz".
                // We use extra bookkeeping to achieve this effect, since everything else works
                // according to the "longest possible match" principle.  The basic principle
                // is that transitions out of a looping state are written in over the looping
                // value instead of being reconciled, and that we copy the contents of the
                // looping state into empty cells of all non-terminal states that follow the
                // looping state.
//System.out.println("c = " + c + ", p = " + p + ", rule.length() = " + rule.length());
                if (c == ASTERISK && p + 1 < rule.length() && rule[p + 1] == QUESTION) {
//System.out.println("Saw *?");
                    setLoopingStates(&decisionPointList, decisionPointList);
                    ++p;
                }
            }
        }

        // a ( marks the beginning of a sequence of characters.  Parentheses can either
        // contain several alternative character sequences (i.e., "(ab|cd|ef)"), or
        // they can contain a sequence of characters that can repeat (i.e., "(abc)*").  Thus,
        // A () group can have multiple entry and exit points.  To keep track of this,
        // we reserve TWO spots on the decision-point stack.  The top of the stack is
        // the list of exit points, which becomes the current decision point list when
        // the ) is reached.  The next entry down is the decision point list at the
        // beginning of the (), which becomes the current decision point list at every
        // entry point.
        // In addition to keeping track of the exit points and the active decision
        // points before the ( (i.e., the places from which the () can be entered),
        // we need to keep track of the entry points in case the expression loops
        // (i.e., is followed by *).  We do that by creating a dummy state in the
        // state table and adding it to the decision point list (BEFORE it's duplicated
        // on the stack).  Nobody points to this state, so it'll get optimized out
        // at the end.  It exists only to hold the entry points in case the ()
        // expression loops.
        if (c == OPEN_PAREN) {

            // add a new state to the state table to hold the entry points into
            // the () expression
            tempStateTable.addElement(new int16_t[numCategories + 1]);

            // we have to adjust lastState and currentState to account for the
            // new dummy state
            lastState = currentState;
            ++currentState;

            // add the current state to the decision point list (add it at the
            // BEGINNING so we can find it later)
            decisionPointList.insertElementAt((void*)currentState, 0);

            // finally, push a copy of the current decision point list onto the
            // stack (this keeps track of the active decision point list before
            // the () expression), followed by an empty decision point list
            // (this will hold the exit points)
            UVector* clone = new UVector;
            for (int32_t i = 0; i < decisionPointList.size(); i++) {
                clone->addElement(decisionPointList[i]);
            }
            decisionPointStack.push(clone);
            decisionPointStack.push(new UVector());
        }

        // a | separates alternative character sequences in a () expression.  When
        // a | is encountered, we add the current decision point list to the exit-point
        // list, and restore the decision point list to its state prior to the (.
        if (c == PIPE) {

            // pick out the top two decision point lists on the stack
            UVector* oneDown = (UVector*)decisionPointStack.pop();
            UVector* twoDown = (UVector*)decisionPointStack.peek();
            decisionPointStack.push(oneDown);

            // append the current decision point list to the list below it
            // on the stack (the list of exit points), and restore the
            // current decision point list to its state before the () expression
            for (int32_t i = 0; i < decisionPointList.size(); i++)
                oneDown->addElement(decisionPointList[i]);
            decisionPointList.removeAllElements();
            for (int32_t i = 0; i < twoDown->size(); i++)
                decisionPointList.addElement((*twoDown)[i]);
        }

        // a ) marks the end of a sequence of characters.  We do one of two things
        // depending on whether the sequence repeats (i.e., whether the ) is followed
        // by *):  If the sequence doesn't repeat, then the exit-point list is merged
        // with the current decision point list and the decision point list from before
        // the () is thrown away.  If the sequence does repeat, then we fish out the
        // state we were in before the ( and copy all of its forward transitions
        // (i.e., every transition added by the () expression) into every state in the
        // exit-point list and the current decision point list.  The current decision
        // point list is then merged with both the exit-point list AND the saved version
        // of the decision point list from before the ().  Then we throw out the *.
        if (c == CLOSE_PAREN) {

            // pull the exit point list off the stack, merge it with the current
            // decision point list, and make the merged version the current
            // decision point list
            UVector* exitPoints = (UVector*)decisionPointStack.pop();
            for (int32_t i = 0; i < exitPoints->size(); i++)
                decisionPointList.addElement((*exitPoints)[i]);
            delete exitPoints;

            // if the ) isn't followed by a *, then all we have to do is throw
            // away the other list on the decision point stack, and we're done
            if (p + 1 >= rule.length() || (
                    rule[p + 1] != ASTERISK &&
                    rule[p + 1] != PLUS &&
                    rule[p + 1] != QUESTION)
            ) {
                delete (UVector*)decisionPointStack.pop();
            }

            // but if the sequence repeats, we have a lot more work to do...
            else {

                // now exitPoints and decisionPointList have to point to equivalent
                // vectors, but not the SAME vector
                exitPoints = new UVector;
                for (int32_t i = 0; i < decisionPointList.size(); i++)
                    exitPoints->addElement(decisionPointList[i]);

                // pop the original decision point list off the stack
                UVector* temp2 = (UVector*)decisionPointStack.pop();

                // we squirreled away the row number of our entry point list
                // at the beginning of the original decision point list.  Fish
                // that state number out and retrieve the entry point list
                int32_t tempStateNum = (int32_t)temp2->firstElement();
                int16_t* tempState = (int16_t*)tempStateTable.elementAt(tempStateNum);

                // merge the original decision point list with the current
                // decision point list
                if (rule.charAt(p + 1) == QUESTION || rule.charAt(p + 1) == ASTERISK) {
                    for (int32_t i = 0; i < temp2->size(); i++)
                        decisionPointList.addElement((*temp2)[i]);
                    delete temp2;
                }

                // finally, copy every forward reference from the entry point
                // list into every state in the new decision point list
                if (rule[p + 1] == PLUS || rule[p + 1] == ASTERISK) {
                    for (int32_t i = 0; i < numCategories; i++) {
                        if (tempState[i] > tempStateNum) {
                            updateStateTable(*exitPoints,
                                             UnicodeString((UChar)(i + 0x100)),
                                             tempState[i]);
                        }
                    }
                }

                // update lastState and currentState, and throw away the *
                lastState = currentState;
                currentState = tempStateTable.size() - 1;
                ++p;
                delete exitPoints;
            }
        }

        // a / marks the position where the break is to go if the character sequence
        // matches this rule.  We update the flag word of every state on the decision
        // point list to mark them as ending states, and take note of the fact that
        // we've seen the slash
        if (c == SLASH) {
            sawEarlyBreak = TRUE;
            for (int32_t i = 0; i < decisionPointList.size(); i++) {
                state = (int16_t*)tempStateTable.elementAt((int32_t)decisionPointList[i]);
                state[numCategories] |= LOOKAHEAD_STATE_FLAG;
            }
        }

        // if we get here without executing any of the above clauses, we have a
        // syntax error.  However, for now we just ignore the offending character
        // and move on
/*
debugPrintln("====Parsed \"" + rule.substring(0, p + 1) + "\"...");
System.out.println("      currentState = " + currentState);
debugPrintVectorOfVectors("      decisionPointStack:", "        ", decisionPointStack);
debugPrintVector("        ", decisionPointList);
debugPrintVector("      loopingStates = ", loopingStates);
debugPrintVector("      statesToBackfill = ", statesToBackfill);
System.out.println("      sawEarlyBreak = " + sawEarlyBreak);
debugPrintTempStateTable();
*/

        // clearLoopingStates is a signal back from updateStateTable() that we've
        // transitioned to a state that won't loop back to the current looping
        // state.  (In other words, we've gotten to a point where we can no longer
        // go back into a *? we saw earlier.)  Clear out the list of looping states
        // and backfill any states that need to be backfilled.
        if (clearLoopingStates) {
            setLoopingStates(0, decisionPointList);
        }

        // advance to the next character, now that we've processed the current
        // character
        ++p;
    }

    // this takes care of backfilling any states that still need to be backfilled
    setLoopingStates(0, decisionPointList);

    // when we reach the end of the string, we do a postprocessing step to mark the
    // end states.  The decision point list contains every state that can transition
    // to the end state-- that is, every state that is the last state in a sequence
    // that matches the rule.  All of these states are considered "mark states"
    // or "accepting states"-- that is, states that cause the position returned from
    // next() to be updated.  A mark state represents a possible break position.
    // This allows us to look ahead and remember how far the rule matched
    // before following the new branch (see next() for more information).
    // The temporary state table has an extra "flag column" at the end where this
    // information is stored.  We mark the end states by setting a flag in their
    // flag column.
    // Now if we saw the / in the rule, then everything after it is lookahead
    // material and the break really goes where the slash is.  In this case,
    // we mark these states as BOTH accepting states and lookahead states.  This
    // signals that these states cause the break position to be updated to the
    // position of the slash rather than the current break position.
    for (int32_t i = 0; i < decisionPointList.size(); i++) {
        int32_t rowNum = (int32_t)decisionPointList[i];
        state = (int16_t*)tempStateTable[rowNum];
        state[numCategories] |= END_STATE_FLAG;
        if (sawEarlyBreak) {
            state[numCategories] |= LOOKAHEAD_STATE_FLAG;
        }
    }
/*
debugPrintln("====Parsed \"" + rule + ";");
System.out.println();
System.out.println("      currentState = " + currentState);
debugPrintVectorOfVectors("      decisionPointStack:", "        ", decisionPointStack);
debugPrintVector("        ", decisionPointList);
debugPrintVector("      loopingStates = ", loopingStates);
debugPrintVector("      statesToBackfill = ", statesToBackfill);
System.out.println("      sawEarlyBreak = " + sawEarlyBreak);
debugPrintTempStateTable();
*/
}

/**
 * Update entries in the state table, and merge states when necessary to keep
 * the table deterministic.
 * @param rows The list of rows that need updating (the decision point list)
 * @param pendingChars A character category list, encoded in a String.  This is the
 * list of the columns that need updating.
 * @param newValue Update the cells specfied above to contain this value
 */
void
RuleBasedBreakIteratorBuilder::updateStateTable(const UVector& rows,
                                                const UnicodeString& pendingChars,
                                                int16_t newValue)
{
    // create a dummy state that has the specified row number (newValue) in
    // the cells that need to be updated (those specified by pendingChars)
    // and 0 in the other cells
    int16_t* newValues = new int16_t[numCategories + 1];
    for (int32_t i = 0; i < pendingChars.length(); i++)
        newValues[(int32_t)(pendingChars[i]) - 0x100] = newValue;

    // go through the list of rows to update, and update them by calling
    // mergeStates() to merge them the the dummy state we created
    for (int32_t i = 0; i < rows.size(); i++) {
        mergeStates((int32_t)rows[i], newValues, rows);
    }
}

/**
 * The real work of making the state table deterministic happens here.  This function
 * merges a state in the state table (specified by rowNum) with a state that is
 * passed in (newValues).  The basic process is to copy the nonzero cells in newStates
 * into the state in the state table (we'll call that oldValues).  If there's a
 * collision (i.e., if the same cell has a nonzero value in both states, and it's
 * not the SAME value), then we have to reconcile the collision.  We do this by
 * creating a new state, adding it to the end of the state table, and using this
 * function recursively to merge the original two states into a single, combined
 * state.  This process may happen recursively (i.e., each successive level may
 * involve collisions).  To prevent infinite recursion, we keep a log of merge
 * operations.  Any time we're merging two states we've merged before, we can just
 * supply the row number for the result of that merge operation rather than creating
 * a new state just like it.
 * @param rowNum The row number in the state table of the state to be updated
 * @param newValues The state to merge it with.
 * @param rowsBeingUpdated A copy of the list of rows passed to updateStateTable()
 * (itself a copy of the decision point list from parseRule()).  Newly-created
 * states get added to the decision point list if their "parents" were on it.
 */
void
RuleBasedBreakIteratorBuilder::mergeStates(int32_t rowNum,
                                           int16_t* newValues,
                                           const UVector& rowsBeingUpdated)
{
    int16_t* oldValues = (int16_t*)(tempStateTable[rowNum]);
/*
System.out.print("***Merging " + rowNum + ":");
for (int32_t i = 0; i < oldValues.length; i++) System.out.print("\t" + oldValues[i]);
System.out.println();
System.out.print("    with   \t");
for (int32_t i = 0; i < newValues.length; i++) System.out.print("\t" + newValues[i]);
System.out.println();
*/

    bool_t isLoopingState = loopingStates.contains((void*)rowNum);

    // for each of the cells in the rows we're reconciling, do...
    for (int32_t i = 0; i < numCategories; i++) {

        // if they contain the same value, we don't have to do anything
        if (oldValues[i] == newValues[i]) {
            continue;
        }

        // if oldValues is a looping state and the state the current cell points to
        // is too, then we can just stomp over the current value of that cell (and
        // set the clear-looping-states flag if necessary)
        else if (isLoopingState && loopingStates.contains((void*)oldValues[i])) {
            if (newValues[i] != 0) {
                if (oldValues[i] == 0) {
                    clearLoopingStates = TRUE;
                }
                oldValues[i] = newValues[i];
            }
        }

        // if the current cell in oldValues is 0, copy in the corresponding value
        // from newValues
        else if (oldValues[i] == 0) {
            oldValues[i] = newValues[i];
        }

        // the last column of each row is the flag column.  Take care to merge the
        // flag words correctly
        else if (i == numCategories) {
            oldValues[i] = (int16_t)((newValues[i] & ALL_FLAGS) | oldValues[i]);
        }

        // if both newValues and oldValues have a nonzero value in the current
        // cell, and it isn't the same value both places...
        else if (oldValues[i] != 0 && newValues[i] != 0) {

            // look up this pair of cell values in the merge list.  If it's
            // found, update the cell in oldValues to point to the merged state
            int32_t combinedRowNum = searchMergeList(oldValues[i], newValues[i]);
            if (combinedRowNum != 0) {
                oldValues[i] = (int16_t)combinedRowNum;
            }

            // otherwise, we have to reconcile them...
            else {
                // copy our row numbers into variables to make things easier
                int32_t oldRowNum = oldValues[i];
                int32_t newRowNum = newValues[i];
                combinedRowNum = tempStateTable.size();

                // add this pair of row numbers to the merge list (create it first
                // if we haven't created the merge list yet)
                int32_t* entry = new int32_t[3];
                entry[0] = oldRowNum;
                entry[1] = newRowNum;
                entry[2] = combinedRowNum;
                mergeList.addElement(entry);

//System.out.println("***At " + rowNum + ", merging " + oldRowNum + " and " + newRowNum + " into " + combinedRowNum);

                // create a new row to represent the merged state, and copy the
                // contents of oldRow into it, then add it to the end of the
                // state table and update the original row (oldValues) to point
                // to the new, merged, state
                int16_t* newRow = new int16_t[numCategories + 1];
                int16_t* oldRow = (int16_t*)(tempStateTable[oldRowNum]);
                uprv_memcpy(newRow, oldRow, (numCategories + 1) * sizeof int16_t);
                tempStateTable.addElement(newRow);
                oldValues[i] = (int16_t)combinedRowNum;


//System.out.println("lastOldRowNum = " + lastOldRowNum);
//System.out.println("lastCombinedRowNum = " + lastCombinedRowNum);
//System.out.println("decisionPointList.contains(lastOldRowNum) = " + decisionPointList.contains(new Integer(lastOldRowNum)));
//System.out.println("decisionPointList.contains(lastCombinedRowNum) = " + decisionPointList.contains(new Integer(lastCombinedRowNum)));

                // if the decision point list contains either of the parent rows,
                // update it to include the new row as well
                if ((decisionPointList.contains((void*)oldRowNum)
                        || decisionPointList.contains((void*)newRowNum))
                    && !decisionPointList.contains((void*)combinedRowNum)
                ) {
                    decisionPointList.addElement((void*)combinedRowNum);
                }

                // do the same thing with the list of rows being updated
                if ((rowsBeingUpdated.contains((void*)oldRowNum)
                        || rowsBeingUpdated.contains((void*)newRowNum))
                    && !rowsBeingUpdated.contains((void*)combinedRowNum)
                ) {
                    decisionPointList.addElement((void*)combinedRowNum);
                }
                // now (groan) do the same thing for all the entries on the
                // decision point stack
                for (int32_t k = 0; k < decisionPointStack.size(); k++) {
                    UVector* dpl = (UVector*)decisionPointStack[k];
                    if ((dpl->contains((void*)oldRowNum)
                            || dpl->contains((void*)newRowNum))
                        && !dpl->contains((void*)combinedRowNum)
                    ) {
                        dpl->addElement((void*)combinedRowNum);
                    }
                }

                // FINALLY (puff puff puff), call mergeStates() recursively to copy
                // the row referred to by newValues into the new row and resolve any
                // conflicts that come up at that level
                mergeStates(combinedRowNum, (int16_t*)(tempStateTable.elementAt(
                                newValues[i])), rowsBeingUpdated);
            }
        }
    }
}

/**
 * The merge list is a list of pairs of rows that have been merged somewhere in
 * the process of building this state table, along with the row number of the
 * row containing the merged state.  This function looks up a pair of row numbers
 * and returns the row number of the row they combine into.  (It returns 0 if
 * this pair of rows isn't in the merge list.)
 */
int32_t
RuleBasedBreakIteratorBuilder::searchMergeList(int32_t a, int32_t b)
{
    int32_t* entry;
    for (int32_t i = 0; i < mergeList.size(); i++) {
        entry = (int32_t*)(mergeList[i]);

        // we have a hit if the two row numbers match the two row numbers
        // in the beginning of the entry (the two that combine), in either
        // order
        if ((entry[0] == a && entry[1] == b) || (entry[0] == b && entry[1] == a)) {
            return entry[2];
        }

        // we also have a hit if one of the two row numbers matches the marged
        // row number and the other one matches one of the original row numbers
        if ((entry[2] == a && (entry[0] == b || entry[1] == b))) {
            return entry[2];
        }
        if ((entry[2] == b && (entry[0] == a || entry[1] == a))) {
            return entry[2];
        }
    }
    return 0;
}

/**
 * This function is used to update the list of current loooping states (i.e.,
 * states that are controlled by a *? construct).  It backfills values from
 * the looping states into unpopulated cells of the states that are currently
 * marked for backfilling, and then updates the list of looping states to be
 * the new list
 * @param newLoopingStates The list of new looping states
 * @param endStates The list of states to treat as end states (states that
 * can exit the loop).
 */
void
RuleBasedBreakIteratorBuilder::setLoopingStates(const UVector* newLoopingStates,
                                                const UVector& endStates)
{
    // if the current list of looping states isn't empty, we have to backfill
    // values from the looping states into the states that are waiting to be
    // backfilled
    if (!loopingStates.isEmpty()) {
        int32_t loopingState = (int32_t)loopingStates.lastElement();
        int32_t rowNum;

        // don't backfill into an end state OR any state reachable from an end state
        // (since the search for reachable states is recursive, it's split out into
        // a separate function, eliminateBackfillStates(), below)
        for (int32_t i = 0; i < endStates.size(); i++) {
            eliminateBackfillStates((int32_t)endStates[i]);
        }

        // we DON'T actually backfill the states that need to be backfilled here.
        // Instead, we MARK them for backfilling.  The reason for this is that if
        // there are multiple rules in the state-table description, the looping
        // states may have some of their values changed by a succeeding rule, and
        // this wouldn't be reflected in the backfilled states.  We mark a state
        // for backfilling by putting the row number of the state to copy from
        // into the flag cell at the end of the row
        for (int32_t i = 0; i < statesToBackfill.size(); i++) {
            rowNum = (int32_t)statesToBackfill.elementAt(i);
            int16_t* state = (int16_t*)tempStateTable[rowNum];
            state[numCategories] =
                (int16_t)((state[numCategories] & ALL_FLAGS) | loopingState);
        }
        statesToBackfill.removeAllElements();
        loopingStates.removeAllElements();
    }

    if (newLoopingStates != 0) {
        for (int32_t i = 0; i < newLoopingStates->size(); i++) {
            loopingStates.addElement((*newLoopingStates)[i]);
        }
    }
}

/**
 * This removes "ending states" and states reachable from them from the
 * list of states to backfill.
 * @param The row number of the state to remove from the backfill list
 */
void
RuleBasedBreakIteratorBuilder::eliminateBackfillStates(int32_t baseState)
{
    // don't do anything unless this state is actually in the backfill list...
    if (statesToBackfill.contains((void*)baseState)) {

        // if it is, take it out
        statesToBackfill.removeElement((void*)baseState);

        // then go through and recursively call this function for every
        // state that the base state points to
        int16_t* state = (int16_t*)tempStateTable[baseState];
        for (int32_t i = 0; i < numCategories; i++) {
            if (state[i] != 0) {
                eliminateBackfillStates(state[i]);
            }
        }
    }
}

/**
 * This function completes the backfilling process by actually doing the
 * backfilling on the states that are marked for it
 */
void
RuleBasedBreakIteratorBuilder::backfillLoopingStates(void)
{
    int16_t* state;
    int16_t* loopingState = 0;
    int32_t loopingStateRowNum = 0;
    int32_t fromState;

    // for each state in the state table...
    for (int32_t i = 0; i < tempStateTable.size(); i++) {
        state = (int16_t*)tempStateTable[i];

        // check the state's flag word to see if it's marked for backfilling
        // (it's marked for backfilling if any bits other than the two high-order
        // bits are set-- if they are, then the flag word, minus the two high bits,
        // is the row number to copy from)
        fromState = state[numCategories] & ~ALL_FLAGS;
        if (fromState > 0) {

            // load up the state to copy from (if we haven't already)
            if (fromState != loopingStateRowNum) {
                loopingStateRowNum = fromState;
                loopingState = (int16_t*)tempStateTable[loopingStateRowNum];
            }

            // clear out the backfill part of the flag word
            state[numCategories] &= ALL_FLAGS;

            // then fill all zero cells in the current state with values
            // from the corresponding cells of the fromState
            for (int32_t j = 0; j < numCategories + 1; j++) {
                if (state[j] == 0) {
                    state[j] = loopingState[j];
                }
                else if (state[j] == DONT_LOOP_FLAG) {
                    state[j] = 0;
                }
            }
        }
    }
}

/**
 * This function completes the state-table-building process by doing several
 * postprocessing steps and copying everything into its final resting place
 * in the iterator itself
 * @param forward TRUE if we're working on the forward state table
 */
void
RuleBasedBreakIteratorBuilder::finishBuildingStateTable(bool_t forward)
{
//debugPrintTempStateTable();
    // start by backfilling the looping states
    backfillLoopingStates();
//debugPrintTempStateTable();

    int32_t* rowNumMap = new int32_t[tempStateTable.size()];
    int32_t rowNumMapSize = tempStateTable.size();
    UStack rowsToFollow;
    rowsToFollow.push((void*)1);
    rowNumMap[1] = 1;

    // determine which states are no longer reachable from the start state
    // (the reachable states will have their row numbers in the row number
    // map, and the nonreachable states will have zero in the row number map)
    while (rowsToFollow.size() != 0) {
        int32_t rowNum = (int32_t)rowsToFollow.pop();
        int16_t* row = (int16_t*)(tempStateTable[rowNum]);

        for (int32_t i = 0; i < numCategories; i++) {
            if (row[i] != 0) {
                if (rowNumMap[row[i]] == 0) {
                    rowNumMap[row[i]] = row[i];
                    rowsToFollow.push((void*)row[i]);
                }
            }
        }
    }
/*
System.out.println("The following rows are not reachable:");
for (int32_t i = 1; i < rowNumMap.length; i++)
if (rowNumMap[i] == 0) System.out.print("\t" + i);
System.out.println();
*/

    int32_t newRowNum;

    // algorithm for minimizing the number of states in the table adapted from
    // Aho & Ullman, "Principles of Compiler Design"
    // The basic idea here is to organize the states into classes.  When we're done,
    // all states in the same class can be considered identical and all but one eliminated.

    // initially assign states to classes based on the number of populated cells they
    // contain (the class number is the number of populated cells)
    int32_t* stateClasses = new int32_t[tempStateTable.size()];
    int32_t nextClass = numCategories + 1;
    int16_t* state1 = 0;
    int16_t* state2 = 0;
    for (int32_t i = 1; i < tempStateTable.size(); i++) {
        if (rowNumMap[i] == 0) {
            continue;
        }
        state1 = (int16_t*)tempStateTable[i];
        for (int32_t j = 0; j < numCategories; j++) {
            if (state1[j] != 0) {
                ++stateClasses[i];
            }
        }
        if (stateClasses[i] == 0) {
            stateClasses[i] = nextClass;
        }
    }
    ++nextClass;

    // then, for each class, elect the first member of that class as that class's
    // "representative".  For each member of the class, compare it to the "representative."
    // If there's a column position where the state being tested transitions to a
    // state in a DIFFERENT class from the class where the "representative" transitions,
    // then move the state into a new class.  Repeat this process until no new classes
    // are created.
    int32_t currentClass;
    int32_t lastClass;
    bool_t split;

    do {
//System.out.println("Making a pass...");
        currentClass = 1;
        lastClass = nextClass;
        while (currentClass < nextClass) {
//System.out.print("States in class #" + currentClass +":");
            split = FALSE;
            state1 = state2 = 0;
            for (int32_t i = 0; i < tempStateTable.size(); i++) {
                if (stateClasses[i] == currentClass) {
//System.out.print("\t" + i);
                    if (state1 == 0) {
                        state1 = (int16_t*)tempStateTable[i];
                    }
                    else {
                        state2 = (int16_t*)tempStateTable[i];
                        for (int32_t j = 0; j < numCategories + 1; j++) {
                            if ((j == numCategories && state1[j] != state2[j] && forward)
                                    || (j != numCategories && stateClasses[state1[j]]
                                    != stateClasses[state2[j]])) {
                                stateClasses[i] = nextClass;
                                split = TRUE;
                                break;
                            }
                        }
                    }
                }
            }
            if (split) {
                ++nextClass;
            }
            ++currentClass;
//System.out.println();
        }
    } while (lastClass != nextClass);

    // at this point, all of the states in a class except the first one (the
    //"representative") can be eliminated, so update the row-number map accordingly
    int32_t* representatives = new int32_t[nextClass];
    for (int32_t i = 1; i < tempStateTable.size(); i++) {
        if (representatives[stateClasses[i]] == 0) {
            representatives[stateClasses[i]] = i;
        }
        else {
            rowNumMap[i] = representatives[stateClasses[i]];
        }
    }
    delete [] stateClasses;
    delete [] representatives;
//System.out.println("Renumbering...");

    // renumber all remaining rows...
    // first drop all that are either unreferenced or not a class representative
    for (int32_t i = 1; i < rowNumMapSize; i++) {
        if (rowNumMap[i] != i) {
            delete [] tempStateTable[i];
            tempStateTable.setElementAt(0, i);
        }
    }

    // then calculate everybody's new row number and update the row
    // number map appropriately (the first pass updates the row numbers
    // of all the class representatives [the rows we're keeping], and the
    // second pass updates the cross references for all the rows that
    // are being deleted)
    newRowNum = 1;
    for (int32_t i = 1; i < rowNumMapSize; i++) {
        if (tempStateTable[i] != 0) {
            rowNumMap[i] = newRowNum++;
        }
    }
    for (int32_t i = 1; i < rowNumMapSize; i++) {
        if (tempStateTable[i] == 0) {
            rowNumMap[i] = rowNumMap[rowNumMap[i]];
        }
    }
//for (int32_t i = 1; i < rowNumMap.length; i++) rowNumMap[i] = i; int32_t newRowNum = rowNumMap.length;

    // allocate the permanent state table, and copy the remaining rows into it
    // (adjusting all the cell values, of course)

    // this section does that for the forward state table
    if (forward) {
        tables->endStates = new bool_t[newRowNum];
        tables->lookaheadStates = new bool_t[newRowNum];
        tables->stateTable = new int16_t[newRowNum * numCategories];
        int32_t p = 0;
        int32_t p2 = 0;
        for (int32_t i = 0; i < tempStateTable.size(); i++) {
            int16_t* row = (int16_t*)(tempStateTable[i]);
            if (row == 0) {
                continue;
            }
            for (int32_t j = 0; j < numCategories; j++) {
                tables->stateTable[p] = (int16_t)(rowNumMap[row[j]]);
                ++p;
            }
            tables->endStates[p2] = ((row[numCategories] & END_STATE_FLAG) != 0);
            tables->lookaheadStates[p2] = ((row[numCategories] & LOOKAHEAD_STATE_FLAG) != 0);
            ++p2;
        }
    }

    // and this section does it for the backward state table
    else {
        tables->backwardsStateTable = new int16_t[newRowNum * numCategories];
        int32_t p = 0;
        for (int32_t i = 0; i < tempStateTable.size(); i++) {
            int16_t* row = (int16_t*)(tempStateTable[i]);
            if (row == 0) {
                continue;
            }
            for (int32_t j = 0; j < numCategories; j++) {
                tables->backwardsStateTable[p] = (int16_t)(rowNumMap[row[j]]);
                ++p;
            }
        }
    }

    delete [] rowNumMap;
}

/**
 * This function builds the backward state table from the forward state
 * table and any additional rules (identified by the ! on the front)
 * supplied in the description
 */
void
RuleBasedBreakIteratorBuilder::buildBackwardsStateTable(UErrorCode& err)
{
    if (U_FAILURE(err))
        return;

    // create the temporary state table and seed it with two rows (row 0
    // isn't used for anything, and we have to create row 1 (the initial
    // state) before we can do anything else
    tempStateTable.removeAllElements();
    tempStateTable.addElement(new int16_t[numCategories + 1]);
    tempStateTable.addElement(new int16_t[numCategories + 1]);

    // although the backwards state table is built automatically from the forward
    // state table, there are some situations (the default sentence-break rules,
    // for example) where this doesn't yield enough stop states, causing a dramatic
    // drop in performance.  To help with these cases, the user may supply
    // supplemental rules that are added to the backward state table.  These have
    // the same syntax as the normal break rules, but begin with BANG to distinguish
    // them from normal break rules
    for (int32_t i = 0; i < tempRuleList.size(); i++) {
        UnicodeString* rule = (UnicodeString*)tempRuleList[i];
        if ((*rule)[0] == BANG) {
            rule->remove(0, 1);
            parseRule(*rule, FALSE);
        }
    }
    backfillLoopingStates();

    // Backwards iteration is qualitatively different from forwards iteration.
    // This is because backwards iteration has to be made to operate from no context
    // at all-- the user should be able to ask BreakIterator for the break position
    // immediately on either side of some arbitrary offset in the text.  The
    // forward iteration table doesn't let us do that-- it assumes complete
    // information on the context, which means starting from the beginning of the
    // document.
    // The way we do backward and random-access iteration is to back up from the
    // current (or user-specified) position until we see something we're sure is
    // a break position (it may not be the last break position immediately
    // preceding our starting point, however).  Then we roll forward from there to
    // locate the actual break position we're after.
    // This means that the backwards state table doesn't have to identify every
    // break position, allowing the building algorithm to be much simpler.  Here,
    // we use a "pairs" approach, scanning the forward-iteration state table for
    // pairs of character categories we ALWAYS break between, and building a state
    // table from that information.  No context is required-- all this state table
    // looks at is a pair of adjacent characters.

    // It's possible that the user has supplied supplementary rules (see above).
    // This has to be done first to keep parseRule() and friends from becoming
    // EVEN MORE complicated.  The automatically-generated states are appended
    // onto the end of the state table, and then the two sets of rules are
    // stitched together at the end.  Take note of the row number of the
    // first row of the auromatically-generated part.
    int32_t backTableOffset = tempStateTable.size();
    if (backTableOffset > 2) {
        ++backTableOffset;
    }

    // the automatically-generated part of the table models a two-dimensional
    // array where the two dimensions represent the two characters we're currently
    // looking at.  To model this as a state table, we actually need one additional
    // row to represent the initial state.  It gets populated with the row numbers
    // of the other rows (in order).
    for (int32_t i = 0; i < numCategories + 1; i++)
        tempStateTable.addElement(new int16_t[numCategories + 1]);

    int16_t* state = (int16_t*)tempStateTable[backTableOffset - 1];
    for (int32_t i = 0; i < numCategories; i++)
        state[i] = (int16_t)(i + backTableOffset);

    // scavenge the forward state table for pairs of character categories
    // that always have a break between them.  The algorithm is as follows:
    // Look down each column in the state table.  For each nonzero cell in
    // that column, look up the row it points to.  For each nonzero cell in
    // that row, populate a cell in the backwards state table: the row number
    // of that cell is the number of the column we were scanning (plus the
    // offset that locates this sub-table), and the column number of that cell
    // is the column number of the nonzero cell we just found.  This cell is
    // populated with its own column number (adjusted according to the actual
    // location of the sub-table).  This process will produce a state table
    // whose behavior is the same as looking up successive pairs of characters
    // in an array of Booleans to determine whether there is a break.
    int32_t numRows = tempStateTable.size() / numCategories;
    for (int32_t column = 0; column < numCategories; column++) {
        for (int32_t row = 0; row < numRows; row++) {
            int32_t nextRow = tables->lookupState(row, column);
            if (nextRow != 0) {
                for (int32_t nextColumn = 0; nextColumn < numCategories; nextColumn++) {
                    int32_t cellValue = tables->lookupState(nextRow, nextColumn);
                    if (cellValue != 0) {
                        state = (int16_t*)tempStateTable[nextColumn + backTableOffset];
                        state[column] = (int16_t)(column + backTableOffset);
                    }
                }
            }
        }
    }

//debugPrintTempStateTable();
    // if the user specified some backward-iteration rules with the ! token,
    // we have to merge the resulting state table with the auto-generated one
    // above.  First copy the populated cells from row 1 over the populated
    // cells in the auto-generated table.  Then copy values from row 1 of the
    // auto-generated table into all of the the unpopulated cells of the
    // rule-based table.
    if (backTableOffset > 1) {

        // for every row in the auto-generated sub-table, if a cell is
        // populated that is also populated in row 1 of the rule-based
        // sub-table, copy the value from row 1 over the value in the
        // auto-generated sub-table
        state = (int16_t*)tempStateTable[1];
        for (int32_t i = backTableOffset - 1; i < tempStateTable.size(); i++) {
            int16_t* state2 = (int16_t*)tempStateTable[i];
            for (int32_t j = 0; j < numCategories; j++) {
                if (state[j] != 0 && state2[j] != 0) {
                    state2[j] = state[j];
                }
            }
        }

        // now, for every row in the rule-based sub-table that is not
        // an end state, fill in all unpopulated cells with the values
        // of the corresponding cells in the first row of the auto-
        // generated sub-table.
        state = (int16_t*)tempStateTable[backTableOffset - 1];
        for (int32_t i = 1; i < backTableOffset - 1; i++) {
            int16_t* state2 = (int16_t*)tempStateTable[i];
            if ((state2[numCategories] & END_STATE_FLAG) == 0) {
                for (int32_t j = 0; j < numCategories; j++) {
                    if (state2[j] == 0) {
                        state2[j] = state[j];
                    }
                }
            }
        }
    }

//debugPrintTempStateTable();

    // finally, clean everything up and copy it into the actual BreakIterator
    // by calling finishBuildingStateTable()
    finishBuildingStateTable(FALSE);
/*
System.out.print("C:\t");
for (int32_t i = 0; i < numCategories; i++)
System.out.print(Integer.toString(i) + "\t");
System.out.println(); System.out.print("=================================================");
for (int32_t i = 0; i < backwardsStateTable.length; i++) {
if (i % numCategories == 0) {
System.out.println();
System.out.print(Integer.toString(i / numCategories) + ":\t");
}
if (backwardsStateTable[i] == 0) System.out.print(".\t"); else System.out.print(Integer.toString(backwardsStateTable[i]) + "\t");
}
System.out.println();
*/
}

void
RuleBasedBreakIteratorBuilder::setUpErrorMessage(const UnicodeString& message,
                                                 int32_t position,
                                                 const UnicodeString& context)
{
    static UChar lbrks[] = { 0x000a, 0x000a };

    errorMessage = context;
    errorMessage.insert(position, lbrks, 2);
    errorMessage.insert(0, lbrks, 1);
    errorMessage.insert(0, message);
}
