/*
**********************************************************************
*   Copyright (C) 1999-2001, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   Date        Name        Description
*   10/20/99    alan        Creation.
**********************************************************************
*/

#include "unicode/uniset.h"
#include "unicode/parsepos.h"
#include "unicode/unicode.h"
#include "unicode/uscript.h"
#include "symtable.h"
#include "cmemory.h"
#include "rbt_rule.h"
#include "umutex.h"
#include "ucln_in.h"
#include "upropset.h"
#include "util.h"

// HIGH_VALUE > all valid values. 110000 for codepoints
#define UNICODESET_HIGH 0x0110000

// LOW <= all valid values. ZERO for codepoints
#define UNICODESET_LOW 0x000000

// initial storage. Must be >= 0
#define START_EXTRA 16

// extra amount for growth. Must be >= 0
#define GROW_EXTRA START_EXTRA

// Define UChar constants using hex for EBCDIC compatibility
// Used #define to reduce private static exports and memory access time.
#define SET_OPEN        ((UChar)0x005B) /*[*/
#define SET_CLOSE       ((UChar)0x005D) /*]*/
#define HYPHEN          ((UChar)0x002D) /*-*/
#define COMPLEMENT      ((UChar)0x005E) /*^*/
#define COLON           ((UChar)0x003A) /*:*/
#define BACKSLASH       ((UChar)0x005C) /*\*/
#define INTERSECTION    ((UChar)0x0026) /*&*/
#define UPPER_U         ((UChar)0x0055) /*U*/
#define LOWER_U         ((UChar)0x0075) /*u*/

// TEMPORARY: Remove when deprecated category code constructor is removed.
static const UChar CATEGORY_NAMES[] = {
    // Must be kept in sync with uchar.h/UCharCategory
    0x43, 0x6E, /* "Cn" */
    0x4C, 0x75, /* "Lu" */
    0x4C, 0x6C, /* "Ll" */
    0x4C, 0x74, /* "Lt" */
    0x4C, 0x6D, /* "Lm" */
    0x4C, 0x6F, /* "Lo" */
    0x4D, 0x6E, /* "Mn" */
    0x4D, 0x65, /* "Me" */
    0x4D, 0x63, /* "Mc" */
    0x4E, 0x64, /* "Nd" */
    0x4E, 0x6C, /* "Nl" */
    0x4E, 0x6F, /* "No" */
    0x5A, 0x73, /* "Zs" */
    0x5A, 0x6C, /* "Zl" */
    0x5A, 0x70, /* "Zp" */
    0x43, 0x63, /* "Cc" */
    0x43, 0x66, /* "Cf" */
    0x43, 0x6F, /* "Co" */
    0x43, 0x73, /* "Cs" */
    0x50, 0x64, /* "Pd" */
    0x50, 0x73, /* "Ps" */
    0x50, 0x65, /* "Pe" */
    0x50, 0x63, /* "Pc" */
    0x50, 0x6F, /* "Po" */
    0x53, 0x6D, /* "Sm" */
    0x53, 0x63, /* "Sc" */
    0x53, 0x6B, /* "Sk" */
    0x53, 0x6F, /* "So" */
    0x50, 0x69, /* "Pi" */
    0x50, 0x66, /* "Pf" */
    0x00
};

/**
 * Delimiter string used in patterns to close a category reference:
 * ":]".  Example: "[:Lu:]".
 */
static const UChar CATEGORY_CLOSE[] = {COLON, SET_CLOSE, 0x0000}; /* ":]" */

/**
 * Cleanup function for transliterator component; delegates to
 * Transliterator::cleanupRegistry().
 */
U_CFUNC UBool unicodeset_cleanup(void) {
    UnicodePropertySet::cleanup();
    return TRUE;
}

U_NAMESPACE_BEGIN

/**
 * Minimum value that can be stored in a UnicodeSet.
 */
const UChar32 UnicodeSet::MIN_VALUE = UNICODESET_LOW;

/**
 * Maximum value that can be stored in a UnicodeSet.
 */
const UChar32 UnicodeSet::MAX_VALUE = UNICODESET_HIGH - 1;

// HEY WHAT'S THIS DOING HERE?
// This is here until we have sufficient reason to add an entire
// separate unimatch.cpp source file just for one line.
const char UnicodeMatcher::fgClassID = 0;

const char UnicodeSet::fgClassID = 0;

//----------------------------------------------------------------
// Debugging
//----------------------------------------------------------------

// DO NOT DELETE THIS CODE.  This code is used to debug memory leaks.
// To enable the debugging, define the symbol DEBUG_MEM in the line
// below.  This will result in text being sent to stdout that looks
// like this:
//   DEBUG UnicodeSet: ct 0x00A39B20; 397 [\u0A81-\u0A83\u0A85-
//   DEBUG UnicodeSet: dt 0x00A39B20; 396 [\u0A81-\u0A83\u0A85-
// Each line lists a construction (ct) or destruction (dt) event, the
// object address, the number of outstanding objects after the event,
// and the pattern of the object in question.

// #define DEBUG_MEM

#ifdef DEBUG_MEM
#include <stdio.h>
static int32_t _dbgCount = 0;
#endif

static inline void _dbgct(UnicodeSet* set) {
#ifdef DEBUG_MEM
    UnicodeString str;
    set->toPattern(str, TRUE);
    char buf[40];
    str.extract(0, 39, buf, "");
    printf("DEBUG UnicodeSet: ct 0x%08X; %d %s\n", set, ++_dbgCount, buf);
#endif
}

static inline void _dbgdt(UnicodeSet* set) {
#ifdef DEBUG_MEM
    UnicodeString str;
    set->toPattern(str, TRUE);
    char buf[40];
    str.extract(0, 39, buf, "");
    printf("DEBUG UnicodeSet: dt 0x%08X; %d %s\n", set, --_dbgCount, buf);
#endif
}

//----------------------------------------------------------------
// Constructors &c
//----------------------------------------------------------------

/**
 * Constructs an empty set.
 */
UnicodeSet::UnicodeSet() :
    len(1), capacity(1 + START_EXTRA), bufferCapacity(0),
    buffer(0)
{
    list = new UChar32[capacity];
    list[0] = UNICODESET_HIGH;
    _dbgct(this);
}

/**
 * Constructs a set containing the given range. If <code>end >
 * start</code> then an empty set is created.
 *
 * @param start first character, inclusive, of range
 * @param end last character, inclusive, of range
 */
UnicodeSet::UnicodeSet(UChar32 start, UChar32 end) :
    len(1), capacity(1 + START_EXTRA), bufferCapacity(0),
    buffer(0)
{
    list = new UChar32[capacity];
    list[0] = UNICODESET_HIGH;
    complement(start, end);
    _dbgct(this);
}

/**
 * Constructs a set from the given pattern, optionally ignoring
 * white space.  See the class description for the syntax of the
 * pattern language.
 * @param pattern a string specifying what characters are in the set
 */
UnicodeSet::UnicodeSet(const UnicodeString& pattern,
                       UErrorCode& status) :
    len(0), capacity(START_EXTRA), bufferCapacity(0),
    buffer(0)
{
    list = new UChar32[capacity];
    applyPattern(pattern, status);
    _dbgct(this);
}

// For internal use by RuleBasedTransliterator
UnicodeSet::UnicodeSet(const UnicodeString& pattern, ParsePosition& pos,
                       const SymbolTable& symbols,
                       UErrorCode& status) :
    len(0), capacity(START_EXTRA), bufferCapacity(0),
    buffer(0)
{
    list = new UChar32[capacity];
    applyPattern(pattern, pos, &symbols, status);
    _dbgct(this);
}

/**
 * DEPRECATED Constructs a set from the given Unicode character category.
 * @param category an integer indicating the character category as
 * defined in uchar.h.
 * @deprecated To be removed after 2002-DEC-31
 */
UnicodeSet::UnicodeSet(int8_t category, UErrorCode& status) :
    len(0), capacity(START_EXTRA), bufferCapacity(0), list(0),
    buffer(0)
{
    static const UChar OPEN[] = { 91, 58, 0 }; // "[:"
    static const UChar CLOSE[]= { 58, 93, 0 }; // ":]"
    if (U_SUCCESS(status)) {
        if (category < 0 || category >= U_CHAR_CATEGORY_COUNT) {
            status = U_ILLEGAL_ARGUMENT_ERROR;
        } else {
            UnicodeString pattern(FALSE, CATEGORY_NAMES + category*2, 2);
            pattern.insert(0, OPEN);
            pattern.append(CLOSE);
            list = new UChar32[capacity];
            applyPattern(pattern, status);
        }
    }
    _dbgct(this);
}

/**
 * Constructs a set that is identical to the given UnicodeSet.
 */
UnicodeSet::UnicodeSet(const UnicodeSet& o) :
    UnicodeFilter(o),
    capacity(o.len + GROW_EXTRA), bufferCapacity(0),
    buffer(0)
{
    list = new UChar32[capacity];
    *this = o;
    _dbgct(this);
}

/**
 * Destructs the set.
 */
UnicodeSet::~UnicodeSet() {
    _dbgdt(this); // first!
    delete[] list;
    delete[] buffer;
}

/**
 * Assigns this object to be a copy of another.
 */
UnicodeSet& UnicodeSet::operator=(const UnicodeSet& o) {
    ensureCapacity(o.len);
    len = o.len;
    uprv_memcpy(list, o.list, len*sizeof(UChar32));
    pat = o.pat;
    return *this;
}

/**
 * Compares the specified object with this set for equality.  Returns
 * <tt>true</tt> if the two sets
 * have the same size, and every member of the specified set is
 * contained in this set (or equivalently, every member of this set is
 * contained in the specified set).
 *
 * @param o set to be compared for equality with this set.
 * @return <tt>true</tt> if the specified set is equal to this set.
 */
UBool UnicodeSet::operator==(const UnicodeSet& o) const {
    if (len != o.len) return FALSE;
    for (int32_t i = 0; i < len; ++i) {
        if (list[i] != o.list[i]) return FALSE;
    }
    return TRUE;
}

/**
 * Returns a copy of this object.  All UnicodeMatcher objects have
 * to support cloning in order to allow classes using
 * UnicodeMatchers, such as Transliterator, to implement cloning.
 */
UnicodeMatcher* UnicodeSet::clone() const {
    return new UnicodeSet(*this);
}

/**
 * Returns the hash code value for this set.
 *
 * @return the hash code value for this set.
 * @see Object#hashCode()
 */
int32_t UnicodeSet::hashCode(void) const {
    int32_t result = len;
    for (int32_t i = 0; i < len; ++i) {
        result *= 1000003;
        result += list[i];
    }
    return result;
}

//----------------------------------------------------------------
// Public API
//----------------------------------------------------------------

/**
 * Make this object represent the range <code>start - end</code>.
 * If <code>end > start</code> then this object is set to an
 * an empty range.
 *
 * @param start first character in the set, inclusive
 * @rparam end last character in the set, inclusive
 */
void UnicodeSet::set(UChar32 start, UChar32 end) {
    clear();
    complement(start, end);
}

/**
 * Modifies this set to represent the set specified by the given
 * pattern, optionally ignoring white space.  See the class
 * description for the syntax of the pattern language.
 * @param pattern a string specifying what characters are in the set
 * @param ignoreSpaces if <code>true</code>, all spaces in the
 * pattern are ignored.  Spaces are those characters for which
 * <code>Character.isSpaceChar()</code> is <code>true</code>.
 * Characters preceded by '\\' are escaped, losing any special
 * meaning they otherwise have.  Spaces may be included by
 * escaping them.
 * @exception <code>IllegalArgumentException</code> if the pattern
 * contains a syntax error.
 */
void UnicodeSet::applyPattern(const UnicodeString& pattern,
                              UErrorCode& status) {
    if (U_FAILURE(status)) {
        return;
    }

    ParsePosition pos(0);
    applyPattern(pattern, pos, NULL, status);
    if (U_FAILURE(status)) return;

    // Skip over trailing whitespace
    int32_t i = pos.getIndex();
    int32_t n = pattern.length();
    while (i<n && Unicode::isWhitespace(pattern.charAt(i))) {
        ++i;
    }

    if (i != n) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
    }
}

/**
 * Return true if the given position, in the given pattern, appears
 * to be the start of a UnicodeSet pattern.
 */
UBool UnicodeSet::resemblesPattern(const UnicodeString& pattern, int32_t pos) {
    return ((pos+1) < pattern.length() &&
            pattern.charAt(pos) == (UChar)91/*[*/) ||
        UnicodePropertySet::resemblesPattern(pattern, pos);
}

/**
 * Append the <code>toPattern()</code> representation of a
 * character to the given <code>StringBuffer</code>.
 */
void UnicodeSet::_appendToPat(UnicodeString& buf, UChar32 c, UBool useHexEscape) {
    if (useHexEscape) {
        // Use hex escape notation (\uxxxx or \Uxxxxxxxx) for anything
        // unprintable
        if (ICU_Utility::escapeUnprintable(buf, c)) {
            return;
        }
    }
    // Okay to let ':' pass through
    switch (c) {
    case SET_OPEN:
    case SET_CLOSE:
    case HYPHEN:
    case COMPLEMENT:
    case INTERSECTION:
    case BACKSLASH:
    case 123/*{*/:
    case 125/*}*/:
    case SymbolTable::SYMBOL_REF:
    case COLON:
        buf.append(BACKSLASH);
        break;
    default:
        // Escape whitespace
        if (u_isspace(c)) {
            buf.append(BACKSLASH);
        }
        break;
    }
    buf.append((UChar) c);
}

/**
 * Returns a string representation of this set.  If the result of
 * calling this function is passed to a UnicodeSet constructor, it
 * will produce another set that is equal to this one.
 */
UnicodeString& UnicodeSet::toPattern(UnicodeString& result,
                                     UBool escapeUnprintable) const {
    result.truncate(0);
    return _toPattern(result, escapeUnprintable);
}

/**
 * Append a string representation of this set to result.  This will be
 * a cleaned version of the string passed to applyPattern(), if there
 * is one.  Otherwise it will be generated.
 */
UnicodeString& UnicodeSet::_toPattern(UnicodeString& result,
                                      UBool escapeUnprintable) const {
    if (pat.length() > 0) {
        int32_t i;
        int32_t backslashCount = 0;
        for (i=0; i<pat.length(); ) {
            UChar32 c = pat.char32At(i);
            i += UTF_CHAR_LENGTH(c);
            if (escapeUnprintable && ICU_Utility::isUnprintable(c)) {
                // If the unprintable character is preceded by an odd
                // number of backslashes, then it has been escaped.
                // Before unescaping it, we delete the final
                // backslash.
                if ((backslashCount % 2) == 1) {
                    result.truncate(result.length() - 1);
                }
                ICU_Utility::escapeUnprintable(result, c);
                backslashCount = 0;
            } else {
                result.append(c);
                if (c == BACKSLASH) {
                    ++backslashCount;
                } else {
                    backslashCount = 0;
                }
            }
        }
        return result;
    }
    
    return _generatePattern(result, escapeUnprintable);
}

/**
 * Generate and append a string representation of this set to result.
 * This does not use this.pat, the cleaned up copy of the string
 * passed to applyPattern().
 */
UnicodeString& UnicodeSet::_generatePattern(UnicodeString& result,
                                            UBool escapeUnprintable) const {
    result.append(SET_OPEN);

//  // Check against the predefined categories.  We implicitly build
//  // up ALL category sets the first time toPattern() is called.
//  for (int8_t cat=0; cat<Unicode::GENERAL_TYPES_COUNT; ++cat) {
//      if (*this == getCategorySet(cat)) {
//          result.append(COLON);
//          result.append(CATEGORY_NAMES, cat*2, 2);
//          return result.append(CATEGORY_CLOSE);
//      }
//  }

    int32_t count = getRangeCount();

    // If the set contains at least 2 intervals and includes both
    // MIN_VALUE and MAX_VALUE, then the inverse representation will
    // be more economical.
    if (count > 1 &&
        getRangeStart(0) == MIN_VALUE &&
        getRangeEnd(count-1) == MAX_VALUE) {

        // Emit the inverse
        result.append(COMPLEMENT);

        for (int32_t i = 1; i < count; ++i) {
            UChar32 start = getRangeEnd(i-1)+1;
            UChar32 end = getRangeStart(i)-1;
            _appendToPat(result, start, escapeUnprintable);
            if (start != end) {
                result.append(HYPHEN);
                _appendToPat(result, end, escapeUnprintable);
            }
        }
    }

    // Default; emit the ranges as pairs
    else {
        for (int32_t i = 0; i < count; ++i) {
            UChar32 start = getRangeStart(i);
            UChar32 end = getRangeEnd(i);
            _appendToPat(result, start, escapeUnprintable);
            if (start != end) {
                result.append(HYPHEN);
                _appendToPat(result, end, escapeUnprintable);
            }
        }
    }
    
    return result.append(SET_CLOSE);
}

/**
 * Returns the number of elements in this set (its cardinality),
 * <em>n</em>, where <code>0 <= </code><em>n</em><code> <= 65536</code>.
 *
 * @return the number of elements in this set (its cardinality).
 */
int32_t UnicodeSet::size(void) const {
    int32_t n = 0;
    int32_t count = getRangeCount();
    for (int32_t i = 0; i < count; ++i) {
        n += getRangeEnd(i) - getRangeStart(i) + 1;
    }
    return n;
}

/**
 * Returns <tt>true</tt> if this set contains no elements.
 *
 * @return <tt>true</tt> if this set contains no elements.
 */
UBool UnicodeSet::isEmpty(void) const {
    return len == 1;
}

/**
 * Returns <tt>true</tt> if this set contains every character
 * in the specified range of chars.
 * If <code>end > start</code> then the results of this method
 * are undefined.
 *
 * @return <tt>true</tt> if this set contains the specified range
 * of chars.
 */
UBool UnicodeSet::contains(UChar32 start, UChar32 end) const {
    int32_t i = -1;
    for (;;) {
        if (start < list[++i]) break;
    }
    return ((i & 1) != 0 && end < list[i]);
}

/**
 * Returns <tt>true</tt> if this set contains the specified char.
 *
 * @return <tt>true</tt> if this set contains the specified char.
 */
UBool UnicodeSet::contains(UChar32 c) const {
    // Set i to the index of the start item greater than ch
    // We know we will terminate without length test!
    // LATER: for large sets, add binary search
    int32_t i = -1;
    for (;;) {
        if (c < list[++i]) break;
    }
    return ((i & 1) != 0); // return true if odd
}

/**
 * Returns <tt>true</tt> if this set contains any character whose low byte
 * is the given value.  This is used by <tt>RuleBasedTransliterator</tt> for
 * indexing.
 */
UBool UnicodeSet::matchesIndexValue(uint8_t v) const {
    /* The index value v, in the range [0,255], is contained in this set if
     * it is contained in any pair of this set.  Pairs either have the high
     * bytes equal, or unequal.  If the high bytes are equal, then we have
     * aaxx..aayy, where aa is the high byte.  Then v is contained if xx <=
     * v <= yy.  If the high bytes are unequal we have aaxx..bbyy, bb>aa.
     * Then v is contained if xx <= v || v <= yy.  (This is identical to the
     * time zone month containment logic.)
     */
    for (int32_t i=0; i<getRangeCount(); ++i) {
        UChar32 low = getRangeStart(i);
        UChar32 high = getRangeEnd(i);
        if ((low & ~0xFF) == (high & ~0xFF)) {
            if ((low & 0xFF) <= v && v <= (high & 0xFF)) {
                return TRUE;
            }
        } else if ((low & 0xFF) <= v || v <= (high & 0xFF)) {
            return TRUE;
        }
    }
    return FALSE;
}

/**
 * Implementation of UnicodeMatcher::matches().
 */
UMatchDegree UnicodeSet::matches(const Replaceable& text,
                                 int32_t& offset,
                                 int32_t limit,
                                 UBool incremental) {
    if (offset == limit) {
        if (contains(TransliterationRule::ETHER)) {
            return incremental ? U_PARTIAL_MATCH : U_MATCH;
        } else {
            return U_MISMATCH;
        }
    } else {
        return UnicodeFilter::matches(text, offset, limit, incremental);
    }
}

/**
 * Adds the specified range to this set if it is not already
 * present.  If this set already contains the specified range,
 * the call leaves this set unchanged.  If <code>end > start</code>
 * then an empty range is added, leaving the set unchanged.
 *
 * @param start first character, inclusive, of range to be added
 * to this set.
 * @param end last character, inclusive, of range to be added
 * to this set.
 */
void UnicodeSet::add(UChar32 start, UChar32 end) {
    if (start <= end) {
        UChar32 range[3] = { start, end+1, UNICODESET_HIGH };
        add(range, 2, 0);
    }
}

/**
 * Adds the specified character to this set if it is not already
 * present.  If this set already contains the specified character,
 * the call leaves this set unchanged.
 */
void UnicodeSet::add(UChar32 c) {
    add(c, c);
}

/**
 * Retain only the elements in this set that are contained in the
 * specified range.  If <code>end > start</code> then an empty range is
 * retained, leaving the set empty.
 *
 * @param start first character, inclusive, of range to be retained
 * to this set.
 * @param end last character, inclusive, of range to be retained
 * to this set.
 */
void UnicodeSet::retain(UChar32 start, UChar32 end) {
    if (start <= end) {
        UChar32 range[3] = { start, end+1, UNICODESET_HIGH };
        retain(range, 2, 0);
    } else {
        clear();
    }
}

void UnicodeSet::retain(UChar32 c) {
    retain(c, c);
}

/**
 * Removes the specified range from this set if it is present.
 * The set will not contain the specified range once the call
 * returns.  If <code>end > start</code> then an empty range is
 * removed, leaving the set unchanged.
 * 
 * @param start first character, inclusive, of range to be removed
 * from this set.
 * @param end last character, inclusive, of range to be removed
 * from this set.
 */
void UnicodeSet::remove(UChar32 start, UChar32 end) {
    if (start <= end) {
        UChar32 range[3] = { start, end+1, UNICODESET_HIGH };
        retain(range, 2, 2);
    }
}

/**
 * Removes the specified character from this set if it is present.
 * The set will not contain the specified range once the call
 * returns.
 */
void UnicodeSet::remove(UChar32 c) {
    remove(c, c);
}

/**
 * Complements the specified range in this set.  Any character in
 * the range will be removed if it is in this set, or will be
 * added if it is not in this set.  If <code>end > start</code>
 * then an empty range is xor'ed, leaving the set unchanged.
 *
 * @param start first character, inclusive, of range to be removed
 * from this set.
 * @param end last character, inclusive, of range to be removed
 * from this set.
 */
void UnicodeSet::complement(UChar32 start, UChar32 end) {
    if (start <= end) {
        UChar32 range[3] = { start, end+1, UNICODESET_HIGH };
        exclusiveOr(range, 2, 0);
    }
}

void UnicodeSet::complement(UChar32 c) {
    complement(c, c);
}

/**
 * Returns <tt>true</tt> if the specified set is a <i>subset</i>
 * of this set.
 *
 * @param c set to be checked for containment in this set.
 * @return <tt>true</tt> if this set contains all of the elements of the
 *         specified set.
 */
UBool UnicodeSet::containsAll(const UnicodeSet& c) const {
    // The specified set is a subset if all of its pairs are contained in
    // this set.  It's possible to code this more efficiently in terms of
    // direct manipulation of the inversion lists if the need arises.
    int32_t n = c.getRangeCount();
    for (int i=0; i<n; ++i) {
        if (!contains(c.getRangeStart(i), c.getRangeEnd(i))) {
            return FALSE;
        }
    }
    return TRUE;
}

/**
 * Return TRUE if every character in s is in this set.
 */
UBool UnicodeSet::containsAll(const UnicodeString& s) const {
    UChar32 cp;
    for (int32_t i = 0; i < s.length(); i += UTF_CHAR_LENGTH(cp)) {
        cp = s.char32At(i);
        if (!contains(cp)) return FALSE;
    }
    return TRUE;
}

/**
 * Adds all of the elements in the specified set to this set if
 * they're not already present.  This operation effectively
 * modifies this set so that its value is the <i>union</i> of the two
 * sets.  The behavior of this operation is unspecified if the specified
 * collection is modified while the operation is in progress.
 *
 * @param c set whose elements are to be added to this set.
 * @see #add(char, char)
 */
void UnicodeSet::addAll(const UnicodeSet& c) {
    add(c.list, c.len, 0);
}

/**
 * Retains only the elements in this set that are contained in the
 * specified set.  In other words, removes from this set all of
 * its elements that are not contained in the specified set.  This
 * operation effectively modifies this set so that its value is
 * the <i>intersection</i> of the two sets.
 *
 * @param c set that defines which elements this set will retain.
 */
void UnicodeSet::retainAll(const UnicodeSet& c) {
    retain(c.list, c.len, 0);
}

/**
 * Removes from this set all of its elements that are contained in the
 * specified set.  This operation effectively modifies this
 * set so that its value is the <i>asymmetric set difference</i> of
 * the two sets.
 *
 * @param c set that defines which elements will be removed from
 *          this set.
 */
void UnicodeSet::removeAll(const UnicodeSet& c) {
    retain(c.list, c.len, 2);
}

/**
 * Complements in this set all elements contained in the specified
 * set.  Any character in the other set will be removed if it is
 * in this set, or will be added if it is not in this set.
 *
 * @param c set that defines which elements will be xor'ed from
 *          this set.
 */
void UnicodeSet::complementAll(const UnicodeSet& c) {
    exclusiveOr(c.list, c.len, 0);
}

/**
 * Inverts this set.  This operation modifies this set so that its
 * value is its complement.  This is equivalent to the pseudo
 * code: <code>this = new UnicodeSet(UnicodeSet.MIN_VALUE,
 * UnicodeSet.MAX_VALUE).removeAll(this)</code>.
 */
void UnicodeSet::complement(void) {
    if (list[0] == UNICODESET_LOW) { 
        ensureBufferCapacity(len-1);
        uprv_memcpy(buffer, list + 1, (len-1)*sizeof(UChar32));
        --len;
    } else {
        ensureBufferCapacity(len+1);
        uprv_memcpy(buffer + 1, list, len*sizeof(UChar32));
        buffer[0] = UNICODESET_LOW;
        ++len;
    }
    swapBuffers();
    pat.truncate(0);
}

/**
 * Removes all of the elements from this set.  This set will be
 * empty after this call returns.
 */
void UnicodeSet::clear(void) {
    list[0] = UNICODESET_HIGH;
    len = 1;
    pat.truncate(0);
}

/**
 * Iteration method that returns the number of ranges contained in
 * this set.
 * @see #getRangeStart
 * @see #getRangeEnd
 */
int32_t UnicodeSet::getRangeCount() const {
    return len/2;
}

/**
 * Iteration method that returns the first character in the
 * specified range of this set.
 * @see #getRangeCount
 * @see #getRangeEnd
 */
UChar32 UnicodeSet::getRangeStart(int32_t index) const {
    return list[index*2];
}

/**
 * Iteration method that returns the last character in the
 * specified range of this set.
 * @see #getRangeStart
 * @see #getRangeEnd
 */
UChar32 UnicodeSet::getRangeEnd(int32_t index) const {
    return list[index*2 + 1] - 1;
}

/**
 * Reallocate this objects internal structures to take up the least
 * possible space, without changing this object's value.
 */
void UnicodeSet::compact() {
    if (len != capacity) {
        capacity = len;
        UChar32* temp = new UChar32[capacity];
        uprv_memcpy(temp, list, len*sizeof(UChar32));
        delete[] list;
        list = temp;
    }
    delete[] buffer;
    buffer = NULL;
}

//----------------------------------------------------------------
// Implementation: Pattern parsing
//----------------------------------------------------------------

/**
 * Parses the given pattern, starting at the given position.  The
 * character at pattern.charAt(pos.getIndex()) must be '[', or the
 * parse fails.  Parsing continues until the corresponding closing
 * ']'.  If a syntax error is encountered between the opening and
 * closing brace, the parse fails.  Upon return from a successful
 * parse, the ParsePosition is updated to point to the character
 * following the closing ']', and a StringBuffer containing a
 * pairs list for the parsed pattern is returned.  This method calls
 * itself recursively to parse embedded subpatterns.
 *
 * @param pattern the string containing the pattern to be parsed.
 * The portion of the string from pos.getIndex(), which must be a
 * '[', to the corresponding closing ']', is parsed.
 * @param pos upon entry, the position at which to being parsing.
 * The character at pattern.charAt(pos.getIndex()) must be a '['.
 * Upon return from a U_SUCCESSful parse, pos.getIndex() is either
 * the character after the closing ']' of the parsed pattern, or
 * pattern.length() if the closing ']' is the last character of
 * the pattern string.
 * @return a StringBuffer containing a pairs list for the parsed
 * substring of <code>pattern</code>
 * @exception IllegalArgumentException if the parse fails.
 */
void UnicodeSet::applyPattern(const UnicodeString& pattern,
                              ParsePosition& pos,
                              const SymbolTable* symbols,
                              UErrorCode& status) {
    if (U_FAILURE(status)) {
        return;
    }

    // Need to build the pattern in a temporary string because
    // _applyPattern calls add() etc., which set pat to empty.
    UnicodeString rebuiltPat;
    _applyPattern(pattern, pos, symbols, rebuiltPat, status);
    pat = rebuiltPat;
}

void UnicodeSet::_applyPattern(const UnicodeString& pattern,
                               ParsePosition& pos,
                               const SymbolTable* symbols,
                               UnicodeString& rebuiltPat,
                               UErrorCode& status) {

    if (U_FAILURE(status)) {
        return;
    }

    // If the pattern contains any of the following, we save a
    // rebuilt (variable-substituted) copy of the source pattern:
    // - a category
    // - an intersection or subtraction operator
    // - an anchor (trailing '$', indicating RBT ether)
    UBool rebuildPattern = FALSE;
    UnicodeString newPat(SET_OPEN);
    int32_t nestedPatStart = - 1; // see below for usage
    UBool nestedPatDone = FALSE; // see below for usage

    UBool invert = FALSE;
    clear();

    const UChar32 NONE = (UChar32) -1;
    UChar32 lastChar = NONE; // This is either a char (0..10FFFF) or NONE
    UBool isLastLiteral = FALSE; // TRUE if lastChar was a literal
    UChar lastOp = 0;

    /* This loop iterates over the characters in the pattern.  We start at
     * the position specified by pos.  We exit the loop when either a
     * matching closing ']' is seen, or we read all characters of the
     * pattern.  In the latter case an error will be thrown.
     */

    /* Pattern syntax:
     *  pat := '[' '^'? elem* ']'
     *  elem := a | a '-' a | set | set op set
     *  set := pat | (a set variable)
     *  op := '&' | '-'
     *  a := (a character, possibly defined by a var)
     */

    // mode 0: No chars parsed yet; next must be '['
    // mode 1: '[' seen; if next is '^' or ':' then special
    // mode 2: '[' '^'? seen; parse pattern and close with ']'
    // mode 3: '[:' seen; parse category and close with ':]'
    // mode 4: ']' seen; parse complete
    // mode 5: Top-level property pattern seen
    int8_t mode = 0;
    int32_t i = pos.getIndex();
    int32_t limit = pattern.length();
    UnicodeSet nestedAux;
    const UnicodeSet* nestedSet; // never owned
    UnicodeString scratch;
    /* In the case of an embedded SymbolTable variable, we look it up and
     * then take characters from the resultant char[] array.  These chars
     * are subjected to an extra level of lookup in the SymbolTable in case
     * they are stand-ins for a nested UnicodeSet.  */
    const UnicodeString* varValueBuffer = NULL;
    int32_t ivarValueBuffer = 0;
    int32_t anchor = 0;
    UChar32 c;
    while (i<limit) {
        /* If the next element is a single character, c will be set to it,
         * and nestedSet will be null.  In this case isLiteral indicates
         * whether the character should assume special meaning if it has
         * one.  If the next element is a nested set, either via a variable
         * reference, or via an embedded "[..]"  or "[:..:]" pattern, then
         * nestedSet will be set to the pairs list for the nested set, and
         * c's value should be ignored.
         */
        nestedSet = NULL;
        UBool isLiteral = FALSE;
        if (varValueBuffer != NULL) {
            if (ivarValueBuffer < varValueBuffer->length()) {
                c = varValueBuffer->char32At(ivarValueBuffer);
                ivarValueBuffer += UTF_CHAR_LENGTH(c);
                const UnicodeMatcher *m = symbols->lookupMatcher(c); // may be NULL
                if (m != NULL && m->getDynamicClassID() != UnicodeSet::getStaticClassID()) {
                    status = U_ILLEGAL_ARGUMENT_ERROR;
                    return;
                }
                nestedSet = (UnicodeSet*) m;
                nestedPatDone = FALSE;
            } else {
                varValueBuffer = NULL;
                c = pattern.char32At(i);
                i += UTF_CHAR_LENGTH(c);
            }
        } else {
            c = pattern.char32At(i);
            i += UTF_CHAR_LENGTH(c);
        }

        // Ignore whitespace.  This is not Unicode whitespace, but Java
        // whitespace, a subset of Unicode whitespace.
        if (u_isspace(c)) {
            continue;
        }

        // Keep track of the count of characters after an alleged anchor
        if (anchor > 0) {
            ++anchor;
        }

        // Parse the opening '[' and optional following '^'
        switch (mode) {
        case 0:
            if (UnicodePropertySet::resemblesPattern(pattern, i-1)) {
                mode = 3;
                break; // Fall through
            } else if (c == SET_OPEN) {
                mode = 1; // Next look for '^' or ':'
                continue;
            } else {
                // throw new IllegalArgumentException("Missing opening '['");
                status = U_ILLEGAL_ARGUMENT_ERROR;
                return;
            }
        case 1:
            mode = 2;
            switch (c) {
            case COMPLEMENT:
                invert = TRUE;
                newPat.append(c);
                continue; // Back to top to fetch next character
            case HYPHEN:
                isLiteral = TRUE; // Treat leading '-' as a literal
                break; // Fall through
            }
            // else fall through and parse this character normally
        }

        // After opening matter is parsed ("[", "[^", or "[:"), the mode
        // will be 2 if we want a closing ']', or 3 if we should parse a
        // category and close with ":]".

        // Only process escapes, variable references, and nested sets
        // if we are _not_ retrieving characters from the variable
        // buffer.  Characters in the variable buffer have already
        // benn through escape and variable reference processing.
        if (varValueBuffer == NULL) {
            /**
             * Handle property set patterns.
             */
            if (UnicodePropertySet::resemblesPattern(pattern, i-1)) {
                ParsePosition pp(i-1);
                UnicodeSet *s = UnicodePropertySet::createFromPattern(pattern, pp);
                if (s == NULL) {
                    // assert(pp.getIndex() == i-1);
                    //throw new IllegalArgumentException("Invalid property pattern " +
                    //                                   pattern.substring(i-1));
                    status = U_INVALID_PROPERTY_PATTERN;
                    return;
                }
                // TODO This is very inefficient.  We create a new UnicodeSet,
                // then do an assignment, then delete it.  Clean this up in
                // the future so that either (1) we just use the new set
                // directly, and delete it when we're done, or (2) even better,
                // UnicodePropertySet takes an existing set.
                nestedAux = *s;
                delete s;
                nestedSet = &nestedAux;
                nestedPatStart = newPat.length();
                nestedPatDone = TRUE; // we're going to do it just below
                
                switch (lastOp) {
                case HYPHEN:
                case INTERSECTION:
                    newPat.append(lastOp);
                    break;
                }

                // If we have a top-level property pattern, then trim
                // off the opening '[' and use the property pattern
                // as the entire pattern.
                if (mode == 3) {
                    newPat.truncate(0);
                }
                UnicodeString str;
                pattern.extractBetween(i-1, pp.getIndex(), str);
                newPat.append(str);
                rebuildPattern = TRUE;
                
                i = pp.getIndex(); // advance past property pattern
                
                if (mode == 3) {
                    // Entire pattern is a category; leave parse
                    // loop.  This is one of 2 ways we leave this
                    // loop if the pattern is well-formed.
                    *this = nestedAux;
                    mode = 5;
                    break;
                }
            }
            
            /* Handle escapes.  If a character is escaped, then it assumes its
             * literal value.  This is true for all characters, both special
             * characters and characters with no special meaning.  We also
             * interpret '\\uxxxx' Unicode escapes here (as literals).
             */
            else if (c == BACKSLASH) {
                UChar32 escaped = pattern.unescapeAt(i);
                if (escaped == (UChar32) -1) {
                    status = U_ILLEGAL_ARGUMENT_ERROR;
                    return;
                }
                isLiteral = TRUE;
                c = escaped;
            }

            /* Parse variable references.  These are treated as literals.  If a
             * variable refers to a UnicodeSet, its stand in character is
             * returned in the UChar[] buffer.
             * Variable names are only parsed if varNameToChar is not null.
             * Set variables are only looked up if varCharToSet is not null.
             */
            else if (symbols != NULL && !isLiteral && c == SymbolTable::SYMBOL_REF) {
                pos.setIndex(i);
                UnicodeString name = symbols->parseReference(pattern, pos, limit);
                if (name.length() != 0) {
                    varValueBuffer = symbols->lookup(name);
                    if (varValueBuffer == NULL) {
                        //throw new IllegalArgumentException("Undefined variable: "
                        //                                   + name);
                        status = U_ILLEGAL_ARGUMENT_ERROR;
                        return;
                    }
                    ivarValueBuffer = 0;
                    i = pos.getIndex(); // Make i point PAST last char of var name
                } else {
                    // Got a null; this means we have an isolated $.
                    // Tentatively assume this is an anchor.
                    anchor = 1;
                }
                continue; // Back to the top to get varValueBuffer[0]
            }

            /* An opening bracket indicates the first bracket of a nested
             * subpattern.
             */
            else if (!isLiteral && c == SET_OPEN) {
                // Record position before nested pattern
                nestedPatStart = newPat.length();

                // Recurse to get the pairs for this nested set.
                // Backup i to '['.
                pos.setIndex(--i);
                switch (lastOp) {
                case HYPHEN:
                case INTERSECTION:
                    newPat.append(lastOp);
                    break;
                }
                nestedAux._applyPattern(pattern, pos, symbols, newPat, status);
                nestedSet = &nestedAux;
                nestedPatDone =  TRUE;
                if (U_FAILURE(status)) {
                    return;
                }
                i = pos.getIndex();
            }
        }

        /* At this point we have either a character c, or a nested set.  If
         * we have encountered a nested set, either embedded in the pattern,
         * or as a variable, we have a non-null nestedSet, and c should be
         * ignored.  Otherwise c is the current character, and isLiteral
         * indicates whether it is an escaped literal (or variable) or a
         * normal unescaped character.  Unescaped characters '-', '&', and
         * ']' have special meanings.
         */
        if (nestedSet != NULL) {
            if (lastChar != NONE) {
                if (lastOp != 0) {
                    // throw new IllegalArgumentException("Illegal rhs for " + lastChar + lastOp);
                    status = U_ILLEGAL_ARGUMENT_ERROR;
                    return;
                }
                add(lastChar, lastChar);
                if (nestedPatDone) {
                    // If there was a character before the nested set,
                    // then we need to insert it in newPat before the
                    // pattern for the nested set.  This position was
                    // recorded in nestedPatStart.
                    UnicodeString s;
                    _appendToPat(s, lastChar, FALSE);
                    newPat.insert(nestedPatStart, s);
                } else {
                    _appendToPat(newPat, lastChar, FALSE);
                }
                lastChar = NONE;
            }
            switch (lastOp) {
            case HYPHEN:
                removeAll(*nestedSet);
                break;
            case INTERSECTION:
                retainAll(*nestedSet);
                break;
            case 0:
                addAll(*nestedSet);
                break;
            }

            // Get the pattern for the nested set, if we haven't done so
            // already.
            if (!nestedPatDone) {
                if (lastOp != 0) {
                    newPat.append(lastOp);
                }
                nestedSet->_toPattern(newPat, FALSE);
            }
            rebuildPattern = TRUE;

            lastOp = 0;

        } else if (!isLiteral && c == SET_CLOSE) {
            // Final closing delimiter.  This is one of 2 ways we
            // leave this loop if the pattern is well-formed.
            if (anchor > 2 || anchor == 1) {
                //throw new IllegalArgumentException("Syntax error near $" + pattern);
                status = U_ILLEGAL_ARGUMENT_ERROR;
                return;
            }
            if (anchor == 2) {
                rebuildPattern = TRUE;
                newPat.append((UChar)SymbolTable::SYMBOL_REF);
                add(TransliterationRule::ETHER);
            }
            mode = 4;
            break;
        } else if (lastOp == 0 && !isLiteral && (c == HYPHEN || c == INTERSECTION)) {
            // assert(c <= 0xFFFF);
            lastOp = (UChar) c;
        } else if (lastOp == HYPHEN) {
            if (lastChar >= c) {
                // Don't allow redundant (a-a) or empty (b-a) ranges;
                // these are most likely typos.
                //throw new IllegalArgumentException("Invalid range " + lastChar +
                //                                       '-' + c);
                status = U_ILLEGAL_ARGUMENT_ERROR;
                return;
            }
            add(lastChar, c);
            _appendToPat(newPat, lastChar, FALSE);
            newPat.append(HYPHEN);
            _appendToPat(newPat, c, FALSE);
            lastOp = 0;
            lastChar = NONE;
        } else if (lastOp != 0) {
            // We have <set>&<char> or <char>&<char>
            // throw new IllegalArgumentException("Unquoted " + lastOp);
            status = U_ILLEGAL_ARGUMENT_ERROR;
            return;
        } else {
            if (lastChar != NONE) {
                // We have <char><char>
                add(lastChar, lastChar);
                _appendToPat(newPat, lastChar, FALSE);
            }
            lastChar = c;
            isLastLiteral = isLiteral;
        }
    }

    if (mode < 4) {
        // throw new IllegalArgumentException("Missing ']'");
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    // Treat a trailing '$' as indicating ETHER.  This code is only
    // executed if symbols == NULL; otherwise other code parses the
    // anchor.
    if (lastChar == (UChar)SymbolTable::SYMBOL_REF && !isLastLiteral) {
        rebuildPattern = TRUE;
        newPat.append(lastChar);
        add(TransliterationRule::ETHER);
    }

    else if (lastChar != NONE) {
        add(lastChar, lastChar);
        _appendToPat(newPat, lastChar, FALSE);
    }

    // Handle unprocessed stuff preceding the closing ']'
    if (lastOp == HYPHEN) {
        // Trailing '-' is treated as literal
        add(lastOp, lastOp);
        newPat.append(HYPHEN);
    } else if (lastOp == INTERSECTION) {
        // throw new IllegalArgumentException("Unquoted trailing " + lastOp);
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    if (mode == 4) {
        newPat.append(SET_CLOSE);
    }

    /**
     * If we saw a '^' after the initial '[' of this pattern, then perform
     * the complement.  (Inversion after '[:' is handled elsewhere.)
     */
    if (invert) {
        complement();
    }

    pos.setIndex(i);

    // Use the rebuilt pattern (newPat) only if necessary.  Prefer the
    // generated pattern.
    if (rebuildPattern) {
        rebuiltPat.append(newPat);
    } else {
        _generatePattern(rebuiltPat, FALSE);
    }
}

//----------------------------------------------------------------
// Implementation: Utility methods
//----------------------------------------------------------------

void UnicodeSet::ensureCapacity(int32_t newLen) {
    if (newLen <= capacity) return;
    capacity = newLen + GROW_EXTRA;
    UChar32* temp = new UChar32[capacity];
    uprv_memcpy(temp, list, len*sizeof(UChar32));
    delete[] list;
    list = temp;
}

void UnicodeSet::ensureBufferCapacity(int32_t newLen) {
    if (buffer != NULL && newLen <= bufferCapacity) return;
    delete[] buffer;
    bufferCapacity = newLen + GROW_EXTRA;
    buffer = new UChar32[bufferCapacity];
}

/**
 * Swap list and buffer.
 */
void UnicodeSet::swapBuffers(void) {
    // swap list and buffer
    UChar32* temp = list;
    list = buffer;
    buffer = temp;

    int32_t c = capacity;
    capacity = bufferCapacity;
    bufferCapacity = c;
}

//----------------------------------------------------------------
// Implementation: Fundamental operators
//----------------------------------------------------------------

static inline UChar32 max(UChar32 a, UChar32 b) {
    return (a > b) ? a : b;
}

// polarity = 0, 3 is normal: x xor y
// polarity = 1, 2: x xor ~y == x === y

void UnicodeSet::exclusiveOr(const UChar32* other, int32_t otherLen, int8_t polarity) {
    ensureBufferCapacity(len + otherLen);
    int32_t i = 0, j = 0, k = 0;
    UChar32 a = list[i++];
    UChar32 b;
    if (polarity == 1 || polarity == 2) {
        b = UNICODESET_LOW;
        if (other[j] == UNICODESET_LOW) { // skip base if already LOW
            ++j;
            b = other[j];
        }
    } else {
        b = other[j++];
    }
    // simplest of all the routines
    // sort the values, discarding identicals!
    for (;;) {
        if (a < b) {
            buffer[k++] = a;
            a = list[i++];
        } else if (b < a) {
            buffer[k++] = b;
            b = other[j++];
        } else if (a != UNICODESET_HIGH) { // at this point, a == b
            // discard both values!
            a = list[i++];
            b = other[j++];
        } else { // DONE!
            buffer[k++] = UNICODESET_HIGH;
            len = k;
            break;
        }
    }
    swapBuffers();
    pat.truncate(0);
}

// polarity = 0 is normal: x union y
// polarity = 2: x union ~y
// polarity = 1: ~x union y
// polarity = 3: ~x union ~y

void UnicodeSet::add(const UChar32* other, int32_t otherLen, int8_t polarity) {
    ensureBufferCapacity(len + otherLen);
    int32_t i = 0, j = 0, k = 0;
    UChar32 a = list[i++];
    UChar32 b = other[j++];
    // change from xor is that we have to check overlapping pairs
    // polarity bit 1 means a is second, bit 2 means b is.
    for (;;) {
        switch (polarity) {
          case 0: // both first; take lower if unequal
            if (a < b) { // take a
                // Back up over overlapping ranges in buffer[]
                if (k > 0 && a <= buffer[k-1]) {
                    // Pick latter end value in buffer[] vs. list[]
                    a = max(list[i], buffer[--k]);
                } else {
                    // No overlap
                    buffer[k++] = a;
                    a = list[i];
                }
                i++; // Common if/else code factored out
                polarity ^= 1;
            } else if (b < a) { // take b
                if (k > 0 && b <= buffer[k-1]) {
                    b = max(other[j], buffer[--k]);
                } else {
                    buffer[k++] = b;
                    b = other[j];
                }
                j++;
                polarity ^= 2;
            } else { // a == b, take a, drop b
                if (a == UNICODESET_HIGH) goto loop_end;
                // This is symmetrical; it doesn't matter if
                // we backtrack with a or b. - liu
                if (k > 0 && a <= buffer[k-1]) {
                    a = max(list[i], buffer[--k]);
                } else {
                    // No overlap
                    buffer[k++] = a;
                    a = list[i];
                }
                i++;
                polarity ^= 1;
                b = other[j++];
                polarity ^= 2;
            }
            break;
          case 3: // both second; take higher if unequal, and drop other
            if (b <= a) { // take a
                if (a == UNICODESET_HIGH) goto loop_end;
                buffer[k++] = a;
            } else { // take b
                if (b == UNICODESET_HIGH) goto loop_end;
                buffer[k++] = b;
            }
            a = list[i++];
            polarity ^= 1;   // factored common code
            b = other[j++];
            polarity ^= 2;
            break;
          case 1: // a second, b first; if b < a, overlap
            if (a < b) { // no overlap, take a
                buffer[k++] = a; a = list[i++]; polarity ^= 1;
            } else if (b < a) { // OVERLAP, drop b
                b = other[j++];
                polarity ^= 2;
            } else { // a == b, drop both!
                if (a == UNICODESET_HIGH) goto loop_end;
                a = list[i++];
                polarity ^= 1;
                b = other[j++];
                polarity ^= 2;
            }
            break;
          case 2: // a first, b second; if a < b, overlap
            if (b < a) { // no overlap, take b
                buffer[k++] = b;
                b = other[j++];
                polarity ^= 2;
            } else  if (a < b) { // OVERLAP, drop a
                a = list[i++];
                polarity ^= 1;
            } else { // a == b, drop both!
                if (a == UNICODESET_HIGH) goto loop_end;
                a = list[i++];
                polarity ^= 1;
                b = other[j++];
                polarity ^= 2;
            }
            break;
        }
    }
 loop_end:
    buffer[k++] = UNICODESET_HIGH;    // terminate
    len = k;
    swapBuffers();
    pat.truncate(0);
}

// polarity = 0 is normal: x intersect y
// polarity = 2: x intersect ~y == set-minus
// polarity = 1: ~x intersect y
// polarity = 3: ~x intersect ~y

void UnicodeSet::retain(const UChar32* other, int32_t otherLen, int8_t polarity) {
    ensureBufferCapacity(len + otherLen);
    int32_t i = 0, j = 0, k = 0;
    UChar32 a = list[i++];
    UChar32 b = other[j++];
    // change from xor is that we have to check overlapping pairs
    // polarity bit 1 means a is second, bit 2 means b is.
    for (;;) {
        switch (polarity) {
          case 0: // both first; drop the smaller
            if (a < b) { // drop a
                a = list[i++];
                polarity ^= 1;
            } else if (b < a) { // drop b
                b = other[j++];
                polarity ^= 2;
            } else { // a == b, take one, drop other
                if (a == UNICODESET_HIGH) goto loop_end;
                buffer[k++] = a;
                a = list[i++];
                polarity ^= 1;
                b = other[j++];
                polarity ^= 2;
            }
            break;
          case 3: // both second; take lower if unequal
            if (a < b) { // take a
                buffer[k++] = a;
                a = list[i++];
                polarity ^= 1;
            } else if (b < a) { // take b
                buffer[k++] = b;
                b = other[j++];
                polarity ^= 2;
            } else { // a == b, take one, drop other
                if (a == UNICODESET_HIGH) goto loop_end;
                buffer[k++] = a;
                a = list[i++];
                polarity ^= 1;
                b = other[j++];
                polarity ^= 2;
            }
            break;
          case 1: // a second, b first;
            if (a < b) { // NO OVERLAP, drop a
                a = list[i++];
                polarity ^= 1;
            } else if (b < a) { // OVERLAP, take b
                buffer[k++] = b;
                b = other[j++];
                polarity ^= 2;
            } else { // a == b, drop both!
                if (a == UNICODESET_HIGH) goto loop_end;
                a = list[i++];
                polarity ^= 1;
                b = other[j++];
                polarity ^= 2;
            }
            break;
          case 2: // a first, b second; if a < b, overlap
            if (b < a) { // no overlap, drop b
                b = other[j++];
                polarity ^= 2;
            } else  if (a < b) { // OVERLAP, take a
                buffer[k++] = a;
                a = list[i++];
                polarity ^= 1;
            } else { // a == b, drop both!
                if (a == UNICODESET_HIGH) goto loop_end;
                a = list[i++];
                polarity ^= 1;
                b = other[j++];
                polarity ^= 2;
            }
            break;
        }
    }
 loop_end:
    buffer[k++] = UNICODESET_HIGH;    // terminate
    len = k;
    swapBuffers();
    pat.truncate(0);
}

U_NAMESPACE_END

