/**
*******************************************************************************
* Copyright (C) 1996-2008, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*/
package com.ibm.icu.text;
 
import java.io.IOException;
import java.text.ParseException;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Arrays;
import java.util.Enumeration;

import com.ibm.icu.impl.TrieBuilder;
import com.ibm.icu.impl.IntTrieBuilder;
import com.ibm.icu.impl.TrieIterator;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.impl.UCharacterProperty;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UCharacterCategory;
import com.ibm.icu.impl.NormalizerImpl;
import com.ibm.icu.util.RangeValueIterator;
import com.ibm.icu.util.VersionInfo;

/**
* Class for building a collator from a list of collation rules.
* This class is uses CollationRuleParser
* @author Syn Wee Quek
* @since release 2.2, June 11 2002
*/
final class CollationParsedRuleBuilder
{     
    // package private constructors ------------------------------------------

    /**
     * Constructor
     * @param rules collation rules
     * @exception ParseException thrown when argument rules have an invalid 
     *            syntax 
     */
    CollationParsedRuleBuilder(String rules) throws ParseException
    {
        m_parser_ = new CollationRuleParser(rules);
        m_parser_.assembleTokenList();
        m_utilColEIter_ = RuleBasedCollator.UCA_.getCollationElementIterator(
                                         "");
    }
    
    // package private inner classes -----------------------------------------
    
    /** 
     * Inverse UCA wrapper
     */
    static class InverseUCA 
    {
        // package private constructor ---------------------------------------
        
        InverseUCA() 
        {
        }
        
        // package private data member ---------------------------------------
        
        /**
         * Array list of characters
         */
        int m_table_[];
        /**
         * Array list of continuation characters
         */
        char m_continuations_[];
        
        /**
         * UCA version of inverse UCA table
         */
        VersionInfo m_UCA_version_;
        
        // package private method --------------------------------------------
        
        /**
     * Returns the previous inverse ces of the argument ces
     * @param ce ce to test
     * @param contce continuation ce to test
     * @param strength collation strength
     * @param prevresult an array to store the return results previous 
         *                   inverse ce and previous inverse continuation ce
         * @return result of the inverse ce 
     */
    final int getInversePrevCE(int ce, int contce, int strength, 
                   int prevresult[]) 
    {
        int result = findInverseCE(ce, contce);
        
        if (result < 0) {
        prevresult[0] = CollationElementIterator.NULLORDER;
        return -1;
        }
        
        ce &= STRENGTH_MASK_[strength];
        contce &= STRENGTH_MASK_[strength];
        
            prevresult[0] = ce;
        prevresult[1] = contce;
        
        while ((prevresult[0]  & STRENGTH_MASK_[strength]) == ce 
           && (prevresult[1]  & STRENGTH_MASK_[strength])== contce
           && result > 0) { 
                        // this condition should prevent falling off the edge of the 
                        // world 
                // here, we end up in a singularity - zero
                prevresult[0] = m_table_[3 * (-- result)];
                prevresult[1] = m_table_[3 * result + 1];
           }
           return result;
        }
        
        final int getCEStrengthDifference(int CE, int contCE, 
                int prevCE, int prevContCE) {
            int strength = Collator.TERTIARY;
            while(
            ((prevCE & STRENGTH_MASK_[strength]) != (CE & STRENGTH_MASK_[strength]) 
            || (prevContCE & STRENGTH_MASK_[strength]) != (contCE & STRENGTH_MASK_[strength]))
            && (strength != 0)) {
                strength--;
            }
            return strength;                
        }

        private int compareCEs(int source0, int source1, int target0, int target1) {
            int s1 = source0, s2, t1 = target0, t2;
            if(RuleBasedCollator.isContinuation(source1)) {
                s2 = source1;
            } else {
                s2 = 0;
            }
            if(RuleBasedCollator.isContinuation(target1)) {
                t2 = target1;
            } else {
                t2 = 0;
            }
            
            int s = 0, t = 0;
            if(s1 == t1 && s2 == t2) {
                return 0;
            }
            s = (s1 & 0xFFFF0000)|((s2 & 0xFFFF0000)>>16); 
            t = (t1 & 0xFFFF0000)|((t2 & 0xFFFF0000)>>16);
            if(s == t) {
                s = (s1 & 0x0000FF00) | (s2 & 0x0000FF00)>>8;
                t = (t1 & 0x0000FF00) | (t2 & 0x0000FF00)>>8;
                if(s == t) {
                    s = (s1 & 0x000000FF)<<8 | (s2 & 0x000000FF);
                    t = (t1 & 0x000000FF)<<8 | (t2 & 0x000000FF);
                    return Utility.compareUnsigned(s, t);
                } else { 
                    return Utility.compareUnsigned(s, t);
                }
            } else {
                return Utility.compareUnsigned(s, t);                
            }
        }
        
        /**
         * Finding the inverse CE of the argument CEs
         * @param ce CE to be tested
         * @param contce continuation CE
         * @return inverse CE
         */
        int findInverseCE(int ce, int contce) 
        {
            int bottom = 0;
            int top = m_table_.length / 3;
            int result = 0;
            
            while (bottom < top - 1) {
                result = (top + bottom) >> 1;
                int first = m_table_[3 * result];
                int second = m_table_[3 * result + 1];
                int comparison = compareCEs(first, second, ce, contce);
                if (comparison > 0) {
                    top = result;
                } 
                else if (comparison < 0) {
                    bottom = result;
                } 
                else { 
                    break;
                }
            }
            
            return result;
        }
    
    /**
     * Getting gap offsets in the inverse UCA
     * @param listheader parsed token lists
     * @exception Exception thrown when error occurs while finding the 
     *            collation gaps
     */
    void getInverseGapPositions(CollationRuleParser.TokenListHeader 
                    listheader)
        throws Exception 
    {
        // reset all the gaps
        CollationRuleParser.Token token = listheader.m_first_;
        int tokenstrength = token.m_strength_;
    
        for (int i = 0; i < 3; i ++) {
        listheader.m_gapsHi_[3 * i] = 0;
        listheader.m_gapsHi_[3 * i + 1] = 0;
        listheader.m_gapsHi_[3 * i + 2] = 0;
        listheader.m_gapsLo_[3 * i] = 0;
        listheader.m_gapsLo_[3 * i + 1] = 0;
        listheader.m_gapsLo_[3 * i + 2] = 0;
        listheader.m_numStr_[i] = 0;
        listheader.m_fStrToken_[i] = null;
        listheader.m_lStrToken_[i] = null;
        listheader.m_pos_[i] = -1;
        }
    
        if ((listheader.m_baseCE_ >>> 24) 
                >= RuleBasedCollator.UCA_CONSTANTS_.PRIMARY_IMPLICIT_MIN_
        && (listheader.m_baseCE_ >>> 24)
                <= RuleBasedCollator.UCA_CONSTANTS_.PRIMARY_IMPLICIT_MAX_) 
        { 
                // implicits -
            listheader.m_pos_[0] = 0;
            int t1 = listheader.m_baseCE_;
            int t2 = listheader.m_baseContCE_;
            listheader.m_gapsLo_[0] = mergeCE(t1, t2, 
                                                  Collator.PRIMARY);
            listheader.m_gapsLo_[1] = mergeCE(t1, t2, 
                                                  Collator.SECONDARY);
            listheader.m_gapsLo_[2] = mergeCE(t1, t2, 
                                                  Collator.TERTIARY);
            int primaryCE = t1 & RuleBasedCollator.CE_PRIMARY_MASK_ | (t2 & RuleBasedCollator.CE_PRIMARY_MASK_) >>> 16;
            primaryCE = RuleBasedCollator.impCEGen_.getImplicitFromRaw(RuleBasedCollator.impCEGen_.getRawFromImplicit(primaryCE)+1);

            t1 = primaryCE & RuleBasedCollator.CE_PRIMARY_MASK_ | 0x0505;
            t2 = (primaryCE << 16) & RuleBasedCollator.CE_PRIMARY_MASK_ | RuleBasedCollator.CE_CONTINUATION_MARKER_;
                
            //                if (listheader.m_baseCE_ < 0xEF000000) {
            //                    // first implicits have three byte primaries, with a gap of
            //                    // one so we esentially need to add 2 to the top byte in 
            //                    // listheader.m_baseContCE_
            //                    t2 += 0x02000000;
            //                } 
            //                else {
            //                    // second implicits have four byte primaries, with a gap of
            //                    // IMPLICIT_LAST2_MULTIPLIER_
            //                    // Now, this guy is not really accessible here, so until we 
            //                    // find a better way to pass it around, assume that the gap is 1
            //                    t2 += 0x00020000;
            //                }
            listheader.m_gapsHi_[0] = mergeCE(t1, t2, 
                                                  Collator.PRIMARY);
            listheader.m_gapsHi_[1] = mergeCE(t1, t2, 
                                                  Collator.SECONDARY);
            listheader.m_gapsHi_[2] = mergeCE(t1, t2, 
                                                  Collator.TERTIARY);
        } 
        else if (listheader.m_indirect_ == true 
                     && listheader.m_nextCE_ != 0) {
        listheader.m_pos_[0] = 0;
        int t1 = listheader.m_baseCE_;
        int t2 = listheader.m_baseContCE_;
        listheader.m_gapsLo_[0] = mergeCE(t1, t2, 
                          Collator.PRIMARY);
        listheader.m_gapsLo_[1] = mergeCE(t1, t2, 
                          Collator.SECONDARY);
        listheader.m_gapsLo_[2] = mergeCE(t1, t2, 
                          Collator.TERTIARY);
        t1 = listheader.m_nextCE_;
        t2 = listheader.m_nextContCE_;
        listheader.m_gapsHi_[0] = mergeCE(t1, t2, 
                          Collator.PRIMARY);
        listheader.m_gapsHi_[1] = mergeCE(t1, t2, 
                          Collator.SECONDARY);
        listheader.m_gapsHi_[2] = mergeCE(t1, t2, 
                          Collator.TERTIARY);
        } 
        else {
        while (true) {
            if (tokenstrength < CE_BASIC_STRENGTH_LIMIT_) {
            listheader.m_pos_[tokenstrength] 
                = getInverseNext(listheader, 
                         tokenstrength);
            if (listheader.m_pos_[tokenstrength] >= 0) {
                listheader.m_fStrToken_[tokenstrength] = token;
            } 
            else { 
                            // The CE must be implicit, since it's not in the 
                            // table 
                // Error
                throw new Exception("Internal program error");
            }
            }
            
            while (token != null && token.m_strength_ >= tokenstrength) 
            {
                if (tokenstrength < CE_BASIC_STRENGTH_LIMIT_) {
                listheader.m_lStrToken_[tokenstrength] = token;
                }
                token = token.m_next_;
            }
            if (tokenstrength < CE_BASIC_STRENGTH_LIMIT_ - 1) {
            // check if previous interval is the same and merge the 
            // intervals if it is so
            if (listheader.m_pos_[tokenstrength] 
                == listheader.m_pos_[tokenstrength + 1]) {
                listheader.m_fStrToken_[tokenstrength] 
                = listheader.m_fStrToken_[tokenstrength 
                             + 1];
                listheader.m_fStrToken_[tokenstrength + 1] = null;
                listheader.m_lStrToken_[tokenstrength + 1] = null;
                listheader.m_pos_[tokenstrength + 1] = -1;
            }
            }
            if (token != null) {
            tokenstrength = token.m_strength_;
            } 
            else {
            break;
            }
        }
        for (int st = 0; st < 3; st ++) {
            int pos = listheader.m_pos_[st];
            if (pos >= 0) {
            int t1 = m_table_[3 * pos];
            int t2 = m_table_[3 * pos + 1];
            listheader.m_gapsHi_[3 * st] = mergeCE(t1, t2, 
                                   Collator.PRIMARY);
            listheader.m_gapsHi_[3 * st + 1] = mergeCE(t1, t2, 
                                   Collator.SECONDARY);
            listheader.m_gapsHi_[3 * st + 2] = (t1 & 0x3f) << 24 
                | (t2 & 0x3f) << 16;
            //pos --;
            //t1 = m_table_[3 * pos];
            //t2 = m_table_[3 * pos + 1];
            t1 = listheader.m_baseCE_;
            t2 = listheader.m_baseContCE_;
            
            listheader.m_gapsLo_[3 * st] = mergeCE(t1, t2, 
                                   Collator.PRIMARY);
            listheader.m_gapsLo_[3 * st + 1] = mergeCE(t1, t2, 
                                   Collator.SECONDARY);
            listheader.m_gapsLo_[3 * st + 2] = (t1 & 0x3f) << 24 
                | (t2 & 0x3f) << 16;
            }
        }
        }
        }
        
    /**
     * Gets the next CE in the inverse table
     * @param listheader token list header
     * @param strength collation strength
     * @return next ce
     */
    private final int getInverseNext(CollationRuleParser.TokenListHeader 
                     listheader, 
                     int strength) 
    {
        int ce = listheader.m_baseCE_;
        int secondce = listheader.m_baseContCE_; 
        int result = findInverseCE(ce, secondce);
            
        if (result < 0) {
        return -1;
        }
            
        ce &= STRENGTH_MASK_[strength];
        secondce &= STRENGTH_MASK_[strength];
        
        int nextce = ce;
        int nextcontce = secondce;
        
        while((nextce & STRENGTH_MASK_[strength]) == ce 
          && (nextcontce  & STRENGTH_MASK_[strength]) == secondce) {
        nextce = m_table_[3 * (++ result)];
        nextcontce = m_table_[3 * result + 1];
        }
            
        listheader.m_nextCE_ = nextce;
        listheader.m_nextContCE_ = nextcontce;
        
        return result;
    }
    }

    // package private data members ------------------------------------------
    
    /**
     * Inverse UCA, instantiate only when required
     */
    static final InverseUCA INVERSE_UCA_; 
    
    /**
     * UCA and Inverse UCA version do not match
     */
    private static final String INV_UCA_VERSION_MISMATCH_ =
    "UCA versions of UCA and inverse UCA should match";
           
    /**
     * UCA and Inverse UCA version do not match
     */
    private static final String UCA_NOT_INSTANTIATED_ =
    "UCA is not instantiated!";
    
    /**
     * Initializing the inverse UCA
     */
    static {
        InverseUCA temp = null;
        try {
        temp = CollatorReader.getInverseUCA();
    } catch (IOException e) {
    }
        /*
      try
      {
      String invdat = "/com/ibm/icu/impl/data/invuca.icu";
      InputStream i = CollationParsedRuleBuilder.class.getResourceAsStream(invdat);
      BufferedInputStream b = new BufferedInputStream(i, 110000);
      INVERSE_UCA_ = CollatorReader.readInverseUCA(b);
      b.close();
      i.close();
      }
      catch (Exception e)
      {
      e.printStackTrace();
      throw new RuntimeException(e.getMessage());
      }
        */
        
        if(temp != null && RuleBasedCollator.UCA_ != null) {
            if(!temp.m_UCA_version_.equals(RuleBasedCollator.UCA_.m_UCA_version_)) {
                throw new RuntimeException(INV_UCA_VERSION_MISMATCH_);
            }
        } else {
            throw new RuntimeException(UCA_NOT_INSTANTIATED_);
        }
        
        INVERSE_UCA_ = temp;
    }
    
    // package private methods -----------------------------------------------
    
    /**
     * Parse and sets the collation rules in the argument collator
     * @param collator to set
     * @exception Exception thrown when internal program error occurs
     */
    void setRules(RuleBasedCollator collator) throws Exception
    {
        if (m_parser_.m_resultLength_ > 0 || m_parser_.m_removeSet_ != null) { 
        // we have a set of rules, let's make something of it 
        assembleTailoringTable(collator);
    } 
    else { // no rules, but no error either must be only options
        // We will init the collator from UCA   
        collator.setWithUCATables();
    }
        // And set only the options
        m_parser_.setDefaultOptionsInCollator(collator);
    }
    
    private void copyRangeFromUCA(BuildTable t, int start, int end) {
        int u = 0;
        for (u = start; u <= end; u ++) {
            // if ((CE = ucmpe32_get(t.m_mapping, u)) == UCOL_NOT_FOUND
            int CE = t.m_mapping_.getValue(u);
            if (CE == CE_NOT_FOUND_ 
                // this test is for contractions that are missing the starting 
                // element. Looks like latin-1 should be done before 
                // assembling the table, even if it results in more false 
                // closure elements
                || (isContractionTableElement(CE) 
            && getCE(t.m_contractions_, CE, 0) == CE_NOT_FOUND_)) {
                //m_utilElement_.m_uchars_ = str.toString();
                m_utilElement_.m_uchars_ = UCharacter.toString(u);
                m_utilElement_.m_cPoints_ = m_utilElement_.m_uchars_;
                m_utilElement_.m_prefix_ = 0;
                m_utilElement_.m_CELength_ = 0;
                m_utilElement_.m_prefixChars_ = null;
                m_utilColEIter_.setText(m_utilElement_.m_uchars_);
                while (CE != CollationElementIterator.NULLORDER) {
                    CE = m_utilColEIter_.next();
                    if (CE != CollationElementIterator.NULLORDER) {
                        m_utilElement_.m_CEs_[m_utilElement_.m_CELength_ ++] 
                = CE;
                    }
                }
                addAnElement(t, m_utilElement_);
            }
        }
    }
            
    /**
     * 2.  Eliminate the negative lists by doing the following for each 
     * non-null negative list: 
     * o   if previousCE(baseCE, strongestN) != some ListHeader X's baseCE, 
     * create new ListHeader X 
     * o   reverse the list, add to the end of X's positive list. Reset the 
     * strength of the first item you add, based on the stronger strength 
     * levels of the two lists. 
     * 
     * 3.  For each ListHeader with a non-null positive list: 
     * o   Find all character strings with CEs between the baseCE and the 
     * next/previous CE, at the strength of the first token. Add these to the 
     * tailoring. 
     *     ? That is, if UCA has ...  x <<< X << x' <<< X' < y ..., and the 
     *       tailoring has & x < z... 
     *     ? Then we change the tailoring to & x  <<< X << x' <<< X' < z ... 
     * 
     * It is possible that this part should be done even while constructing list
     * The problem is that it is unknown what is going to be the strongest 
     * weight.
     * So we might as well do it here
     * o   Allocate CEs for each token in the list, based on the total number N 
     * of the largest level difference, and the gap G between baseCE and nextCE 
     * at that level. The relation * between the last item and nextCE is the 
     * same as the strongest strength. 
     * o   Example: baseCE < a << b <<< q << c < d < e * nextCE(X,1) 
     *     ? There are 3 primary items: a, d, e. Fit them into the primary gap. 
     *     Then fit b and c into the secondary gap between a and d, then fit q 
     *     into the tertiary gap between b and c. 
     * o   Example: baseCE << b <<< q << c * nextCE(X,2) 
     *     ? There are 2 secondary items: b, c. Fit them into the secondary gap. 
     *       Then fit q into the tertiary gap between b and c. 
     * o   When incrementing primary values, we will not cross high byte 
     *     boundaries except where there is only a single-byte primary. That is 
     *     to ensure that the script reordering will continue to work. 
     * @param collator the rule based collator to update
     * @exception Exception thrown when internal program error occurs
     */
    void assembleTailoringTable(RuleBasedCollator collator) throws Exception
    {
        
    for (int i = 0; i < m_parser_.m_resultLength_; i ++) {
        // now we need to generate the CEs  
        // We stuff the initial value in the buffers, and increase the 
            // appropriate buffer according to strength
            if  (m_parser_.m_listHeader_[i].m_first_ != null) { 
                // if there are any elements
                // due to the way parser works, subsequent tailorings
                // may remove all the elements from a sequence, therefore
                // leaving an empty tailoring sequence.
        initBuffers(m_parser_.m_listHeader_[i]);
            }
    }
        
        if (m_parser_.m_variableTop_ != null) { 
            // stuff the variable top value
        m_parser_.m_options_.m_variableTopValue_ 
        = m_parser_.m_variableTop_.m_CE_[0] >>> 16;
        // remove it from the list
        if (m_parser_.m_variableTop_.m_listHeader_.m_first_ 
                == m_parser_.m_variableTop_) { // first in list
        m_parser_.m_variableTop_.m_listHeader_.m_first_ 
            = m_parser_.m_variableTop_.m_next_;
        }
        if (m_parser_.m_variableTop_.m_listHeader_.m_last_ 
        == m_parser_.m_variableTop_) { 
                // first in list
        m_parser_.m_variableTop_.m_listHeader_.m_last_ 
            = m_parser_.m_variableTop_.m_previous_;    
        }
        if (m_parser_.m_variableTop_.m_next_ != null) {
        m_parser_.m_variableTop_.m_next_.m_previous_ 
            = m_parser_.m_variableTop_.m_previous_;
        }
        if (m_parser_.m_variableTop_.m_previous_ != null) {
        m_parser_.m_variableTop_.m_previous_.m_next_ 
            = m_parser_.m_variableTop_.m_next_;
        }
    }
        
    BuildTable t = new BuildTable(m_parser_);
        
        // After this, we have assigned CE values to all regular CEs now we 
    // will go through list once more and resolve expansions, make 
    // UCAElements structs and add them to table               
    for (int i = 0; i < m_parser_.m_resultLength_; i ++) {
        // now we need to generate the CEs 
        // We stuff the initial value in the buffers, and increase the 
        // appropriate buffer according to strength                                                          */
        createElements(t, m_parser_.m_listHeader_[i]);
    }
        
        m_utilElement_.clear();
        StringBuffer str = new StringBuffer();
        
    // add latin-1 stuff
        copyRangeFromUCA(t, 0, 0xFF);
    
        // add stuff for copying 
        if(m_parser_.m_copySet_ != null) {
            int i = 0;
            for(i = 0; i < m_parser_.m_copySet_.getRangeCount(); i++) {
                copyRangeFromUCA(t, m_parser_.m_copySet_.getRangeStart(i), 
                                 m_parser_.m_copySet_.getRangeEnd(i));
            }
        }
        
        // copy contractions from the UCA - this is felt mostly for cyrillic
    char conts[] = RuleBasedCollator.UCA_CONTRACTIONS_;
        int offset = 0;
    while (conts[offset] != 0) {
        // tailoredCE = ucmpe32_get(t.m_mapping, *conts);
        int tailoredCE = t.m_mapping_.getValue(conts[offset]);
        Elements prefixElm =  null;
        if (tailoredCE != CE_NOT_FOUND_) {         
        boolean needToAdd = true;
        if (isContractionTableElement(tailoredCE)) {
                    if (isTailored(t.m_contractions_, tailoredCE, 
                                   conts, offset + 1) == true) {
            needToAdd = false;
            }
        }
        if (!needToAdd && isPrefix(tailoredCE) && conts[offset+1]==0) {
            // pre-context character in UCA
            // The format for pre-context character is
            // conts[0]: baseCP  conts[1]:0  conts[2]:pre-context CP
            Elements elm = new Elements();
            elm.m_cPoints_=m_utilElement_.m_uchars_;
            elm.m_CELength_=0;
            elm.m_uchars_= UCharacter.toString(conts[offset]);
            elm.m_prefixChars_=UCharacter.toString(conts[offset+2]);
            elm.m_prefix_=0; // TODO(claireho) : confirm!
            prefixElm =  (Elements)t.m_prefixLookup_.get(elm);
            if ((prefixElm== null) ||
                (prefixElm.m_prefixChars_.charAt(0)!= conts[offset+2])) {
                needToAdd = true;
            }
        }
                if(m_parser_.m_removeSet_ != null && m_parser_.m_removeSet_.contains(conts[offset])) {
                    needToAdd = false;
                }

                
                if (needToAdd == true) { 
                    // we need to add if this contraction is not tailored.
                    if (conts[offset+1]!=0) { // not precontext 
                        m_utilElement_.m_prefix_ = 0;
                        m_utilElement_.m_prefixChars_ = null;
                        m_utilElement_.m_cPoints_ = m_utilElement_.m_uchars_;
                        str.delete(0, str.length());
                        str.append(conts[offset]);
                        str.append(conts[offset + 1]);
                        if (conts[offset + 2] != 0) {
                            str.append(conts[offset + 2]);
                        } 
                        m_utilElement_.m_uchars_ = str.toString();
                        m_utilElement_.m_CELength_ = 0;
                        m_utilColEIter_.setText(m_utilElement_.m_uchars_);
                    }
                    else {  // add a pre-context element
                        int preKeyLen=0;
                        str.delete(0, str.length());  // clean up
                        m_utilElement_.m_cPoints_ = UCharacter.toString(conts[offset]);
                        m_utilElement_.m_CELength_ = 0;
                        m_utilElement_.m_uchars_ = UCharacter.toString(conts[offset]);
                        m_utilElement_.m_prefixChars_ = UCharacter.toString(conts[offset+2]);
                        if (prefixElm==null) {
                            m_utilElement_.m_prefix_=0;
                        }
                        else { // TODO (claireho): confirm!
                            m_utilElement_.m_prefix_= m_utilElement_.m_prefix_; 
                            // m_utilElement_.m_prefix_= prefixElm.m_prefix_;
                        }
                        m_utilColEIter_.setText(m_utilElement_.m_prefixChars_);
                        while (m_utilColEIter_.next()!=CollationElementIterator.NULLORDER) { 
                            // count number of keys for pre-context char.
                            preKeyLen++;
                        }
                        str.append(conts[offset+2]);
                        str.append(conts[offset]);
                        m_utilColEIter_.setText(str.toString());
                        // Skip the keys for prefix character, then copy the rest to el.
                        while ((preKeyLen-->0) && 
                                m_utilColEIter_.next()!= CollationElementIterator.NULLORDER) {
                            continue;
                        }
                                
                    }
                    while (true) {
                        int CE = m_utilColEIter_.next();
                        if (CE != CollationElementIterator.NULLORDER) {
                            m_utilElement_.m_CEs_[m_utilElement_.m_CELength_++] = CE;
                        }
                        else {
                            break;
                        }
                    }
                    addAnElement(t, m_utilElement_);
                }
        } else if(m_parser_.m_removeSet_ != null && m_parser_.m_removeSet_.contains(conts[offset])) {
                copyRangeFromUCA(t, conts[offset], conts[offset]);
            }
            
        offset += 3;
    }
        
        // Add completely ignorable elements
        processUCACompleteIgnorables(t);
        
        // canonical closure 
        canonicalClosure(t);
  
    // still need to produce compatibility closure
    assembleTable(t, collator);  
    }
    
    // private inner classes -------------------------------------------------
    
    private static class CEGenerator 
    {
        // package private data members --------------------------------------
        
    WeightRange m_ranges_[];
    int m_rangesLength_;
    int m_byteSize_; 
        int m_start_; 
        int m_limit_;
    int m_maxCount_;
    int m_count_;
    int m_current_;
    int m_fLow_; // forbidden Low 
    int m_fHigh_; // forbidden High 
        
        // package private constructor ---------------------------------------
        
        CEGenerator() 
        {
            m_ranges_ = new WeightRange[7];      
            for (int i = 6; i >= 0; i --) {
                m_ranges_[i] = new WeightRange();
            }
        }
    }

    private static class WeightRange implements Comparable
    {
        // public methods ----------------------------------------------------
        
        /**
         * Compares this object with target
         * @param target object to compare with
         * @return 0 if equals, 1 if this is > target, -1 otherwise
         */
        public int compareTo(Object target) 
        {
            if (this == target) {
                return 0;
            }
            int tstart = ((WeightRange)target).m_start_;   
            if (m_start_ == tstart) {
                return 0;
            }
            if (m_start_ > tstart) {
                return 1;
            }
            return -1;
        }
        
        /**
         * Initialize 
         */
        public void clear()
        {
            m_start_ = 0;
            m_end_ = 0;
            m_length_ = 0; 
            m_count_ = 0;
            m_length2_ = 0;
            m_count2_ = 0;
        }
        
        // package private data members --------------------------------------
        
    int m_start_;
        int m_end_;
    int m_length_; 
        int m_count_;
    int m_length2_;
    int m_count2_;
        
        // package private constructor ---------------------------------------
        
        WeightRange()
        {
            clear();
        }
        
        /**
         * Copy constructor.
         * Cloneable is troublesome, needs to check for exception
         * @param source to clone
         */
        WeightRange(WeightRange source)
        {
            m_start_ = source.m_start_;
            m_end_ = source.m_end_;
            m_length_ = source.m_length_; 
            m_count_ = source.m_count_;
            m_length2_ = source.m_length2_;
            m_count2_ = source.m_count2_;
        }
    }
    
    private static class MaxJamoExpansionTable
    {
    // package private data members --------------------------------------
        
    Vector m_endExpansionCE_;
    // vector of booleans
    Vector m_isV_;
    byte m_maxLSize_;
    byte m_maxVSize_;
    byte m_maxTSize_;
        
    // package private constructor ---------------------------------------
        
    MaxJamoExpansionTable()
    {
        m_endExpansionCE_ = new Vector();
        m_isV_ = new Vector();
        m_endExpansionCE_.add(new Integer(0));
        m_isV_.add(Boolean.FALSE);
            m_maxLSize_ = 1;
            m_maxVSize_ = 1;
            m_maxTSize_ = 1;
    }
        
        MaxJamoExpansionTable(MaxJamoExpansionTable table)
        {
            m_endExpansionCE_ = (Vector)table.m_endExpansionCE_.clone();
            m_isV_ = (Vector)table.m_isV_.clone();
            m_maxLSize_ = table.m_maxLSize_;
            m_maxVSize_ = table.m_maxVSize_;
            m_maxTSize_ = table.m_maxTSize_;
        }
    }
    
    private static class MaxExpansionTable 
    {
    // package private constructor --------------------------------------
        
    MaxExpansionTable() 
    {
        m_endExpansionCE_ = new Vector();
        m_expansionCESize_ = new Vector();
        m_endExpansionCE_.add(new Integer(0));
        m_expansionCESize_.add(new Byte((byte)0));
    }
        
        MaxExpansionTable(MaxExpansionTable table) 
        {
            m_endExpansionCE_ = (Vector)table.m_endExpansionCE_.clone();
            m_expansionCESize_ = (Vector)table.m_expansionCESize_.clone();
        }
        
    // package private data member --------------------------------------
        
    Vector m_endExpansionCE_;
    Vector m_expansionCESize_;
    }
    
    private static class BasicContractionTable 
    {
    // package private constructors -------------------------------------
        
    BasicContractionTable()
    {
        m_CEs_ = new Vector();
        m_codePoints_ = new StringBuffer();
    }
        
    // package private data members -------------------------------------
        
    StringBuffer m_codePoints_;
    Vector m_CEs_;
    }
    
    private static class ContractionTable 
    {
    // package private constructor --------------------------------------
        
    /**
     * Builds a contraction table
     * @param mapping
     */
    ContractionTable(IntTrieBuilder mapping) 
    {
        m_mapping_ = mapping;
        m_elements_ = new Vector();
        m_CEs_ = new Vector();
        m_codePoints_ = new StringBuffer();
        m_offsets_ = new Vector();
        m_currentTag_ = CE_NOT_FOUND_TAG_;
    }
        
        /**
         * Copies a contraction table.
         * Not all data will be copied into their own object.
         * @param table
         */
        ContractionTable(ContractionTable table) 
        {
            m_mapping_ = table.m_mapping_;
            m_elements_ = (Vector)table.m_elements_.clone();
            m_codePoints_ = new StringBuffer(table.m_codePoints_.toString());
            m_CEs_ = (Vector)table.m_CEs_.clone();
            m_offsets_ = (Vector)table.m_offsets_.clone();
            m_currentTag_ = table.m_currentTag_;
        }
    
    // package private data members ------------------------------------
        
    /**
     * Vector of BasicContractionTable
     */
        Vector m_elements_;
        IntTrieBuilder m_mapping_;
        StringBuffer m_codePoints_;
    Vector m_CEs_;
    Vector m_offsets_;
    int m_currentTag_;
    }
    
    /**
     * Private class for combining mark table.
     * The table is indexed by the class value(0-255).
     */
    private static class CombinClassTable {
        /**
         * accumulated numbers of combining marks.
         */
        int[] index =  new int[256]; 
        
        /**
         * code point array for combining marks.
         */
        char[] cPoints; 
        
        /**
         * size of cPoints.
         */
        int    size;
        
        // constructor
        CombinClassTable() {
            cPoints = null;
            size = 0;
            pos = 0;
            curClass=1;
        }
        
        /**
         * Copy the combining mark table from ccc and index in compact
         * way.
         * 
         * @param cps : code point array
         * @param size : size of ccc
         * @param index : index of combining classes(0-255)
         */
        void generate(char[] cps, int numOfCM, int[] ccIndex) {
            int count =0;
            
            cPoints = new char[numOfCM];
            for (int i=0; i<256; i++) {
                for (int j=0; j<ccIndex[i]; j++) {
                    cPoints[count++] = cps[(i<<8)+j];
                }
                index[i] = count;
            }
            size = count;
        }
        
        /**
         * Get first CM(combining mark) with the combining class value cClass.
         * @param cClass : combining class value.
         * @return combining mark codepoint or 0 if no combining make with class value cClass
         */
        char GetFirstCM(int cClass) {
            curClass=cClass;
            if (cPoints==null || cClass==0 || index[cClass]==index[cClass-1]) {
                return 0;
            }
            pos =1;
            return cPoints[index[cClass-1]];
        }
        
        /**
         * Get next CM(combining mark) with the combining class value cClass.
         * Return combining mark codepoint or 0 if no next CM.
         */
        char GetNextCM() {
            if (cPoints==null || index[curClass]==(index[curClass-1]+pos))  {
                return 0;
            }
            return cPoints[index[curClass-1] + (pos++)];
        }
        
        // private data members
        int pos;
        int curClass;
    }

    private static final class BuildTable implements TrieBuilder.DataManipulate
    {
    // package private methods ------------------------------------------
        
        /**
     * For construction of the Trie tables.
     * Has to be labeled public
     * @param cp
     * @param offset
     * @return data offset or 0 
     */
    public int getFoldedValue(int cp, int offset)
    {
        int limit = cp + 0x400;
        while (cp < limit) {
        int value = m_mapping_.getValue(cp);
        boolean inBlockZero = m_mapping_.isInZeroBlock(cp);
        int tag = getCETag(value);
        if (inBlockZero == true) {
            cp += TrieBuilder.DATA_BLOCK_LENGTH;
        } 
        else if (!(isSpecial(value) && (tag == CE_IMPLICIT_TAG_ 
                        || tag == CE_NOT_FOUND_TAG_))) {
                    // These are values that are starting in either UCA 
                    // (IMPLICIT_TAG) or in the tailorings (NOT_FOUND_TAG). 
                    // Presence of these tags means that there is nothing in 
                    // this position and that it should be skipped.
            return RuleBasedCollator.CE_SPECIAL_FLAG_ 
            | (CE_SURROGATE_TAG_ << 24) | offset;
        } 
        else {
            ++ cp;
        }
        }
        return 0;
    }
    
    // package private constructor --------------------------------------
        
    /**
     * Returns a table
     */
    BuildTable(CollationRuleParser parser) 
    {
        m_collator_ = new RuleBasedCollator();
        m_collator_.setWithUCAData();
        MaxExpansionTable maxet = new MaxExpansionTable();
        MaxJamoExpansionTable maxjet = new MaxJamoExpansionTable();
        m_options_ = parser.m_options_;
        m_expansions_ = new Vector();
        // Do your own mallocs for the structure, array and have linear 
        // Latin 1
            int trieinitialvalue = RuleBasedCollator.CE_SPECIAL_FLAG_
        | (CE_NOT_FOUND_TAG_ << 24);
        // temporary fix for jb3822, 0x100000 -> 30000
        m_mapping_ = new IntTrieBuilder(null, 0x30000, trieinitialvalue, 
                                            trieinitialvalue, true); 
        m_prefixLookup_ = new Hashtable();
        // uhash_open(prefixLookupHash, prefixLookupComp);
        m_contractions_ = new ContractionTable(m_mapping_);
        // copy UCA's maxexpansion and merge as we go along
        m_maxExpansions_ = maxet;
        // adding an extra initial value for easier manipulation 
        for (int i = 0; 
         i < RuleBasedCollator.UCA_.m_expansionEndCE_.length; i ++) {
        maxet.m_endExpansionCE_.add(new Integer(
                            RuleBasedCollator.UCA_.m_expansionEndCE_[i]));
        maxet.m_expansionCESize_.add(new Byte(
                              RuleBasedCollator.UCA_.m_expansionEndCEMaxSize_[i]));
        }
        m_maxJamoExpansions_ = maxjet;
        
        m_unsafeCP_ = new byte[UNSAFECP_TABLE_SIZE_];
        m_contrEndCP_ = new byte[UNSAFECP_TABLE_SIZE_];
        Arrays.fill(m_unsafeCP_, (byte)0);
        Arrays.fill(m_contrEndCP_, (byte)0);
    }
    
        /**
         * Duplicating a BuildTable.
         * Not all data will be duplicated into their own object.
         * @param table to clone
         */
        BuildTable(BuildTable table) 
        {
            m_collator_ = table.m_collator_;
            m_mapping_ = new IntTrieBuilder(table.m_mapping_);
            m_expansions_ = (Vector)table.m_expansions_.clone();
            m_contractions_ = new ContractionTable(table.m_contractions_);
            m_contractions_.m_mapping_ = m_mapping_;
            m_options_ = table.m_options_;
            m_maxExpansions_ = new MaxExpansionTable(table.m_maxExpansions_);
            m_maxJamoExpansions_ 
        = new MaxJamoExpansionTable(table.m_maxJamoExpansions_);
            m_unsafeCP_ = new byte[table.m_unsafeCP_.length];
            System.arraycopy(table.m_unsafeCP_, 0, m_unsafeCP_, 0,
                             m_unsafeCP_.length);
            m_contrEndCP_ = new byte[table.m_contrEndCP_.length];
            System.arraycopy(table.m_contrEndCP_, 0, m_contrEndCP_, 0,
                             m_contrEndCP_.length);
        }
        
    // package private data members -------------------------------------
        
    RuleBasedCollator m_collator_;
        IntTrieBuilder m_mapping_; 
        Vector m_expansions_; 
        ContractionTable m_contractions_;
    // UCATableHeader image;
    CollationRuleParser.OptionSet m_options_;
    MaxExpansionTable m_maxExpansions_;
    MaxJamoExpansionTable m_maxJamoExpansions_;
    byte m_unsafeCP_[];
    byte m_contrEndCP_[];
    Hashtable m_prefixLookup_;
    CombinClassTable cmLookup = null;
    } 
    
    private static class Elements
    {
    // package private data members -------------------------------------
        
    String m_prefixChars_;
    int m_prefix_;
    String m_uchars_;
    /**
     * Working string
     */
    String m_cPoints_;    
    /**
     * Offset to the working string
     */
    int m_cPointsOffset_;
    /** 
     * These are collation elements - there could be more than one - in 
     * case of expansion 
     */    
    int m_CEs_[];      
        int m_CELength_;
    /** 
     * This is the value element maps in original table   
     */
    int m_mapCE_;         
    int m_sizePrim_[];
    int m_sizeSec_[];
    int m_sizeTer_[];
    boolean m_variableTop_;
    boolean m_caseBit_;
        
    // package private constructors -------------------------------------
        
    /**
     * Package private constructor
     */
    Elements()
    {
        m_sizePrim_ = new int[128];    
        m_sizeSec_ = new int[128];    
        m_sizeTer_ = new int[128];    
            m_CEs_ = new int[256];
            m_CELength_ = 0;
    }

        /**
     * Package private constructor
     */
    Elements(Elements element)
    {
            m_prefixChars_ = element.m_prefixChars_;
            m_prefix_ = element.m_prefix_;
            m_uchars_ = element.m_uchars_;
            m_cPoints_ = element.m_cPoints_;    
            m_cPointsOffset_ = element.m_cPointsOffset_;    
            m_CEs_ = element.m_CEs_;
            m_CELength_ = element.m_CELength_;
            m_mapCE_ = element.m_mapCE_;
        m_sizePrim_ = element.m_sizePrim_;
        m_sizeSec_ = element.m_sizeSec_;
        m_sizeTer_ = element.m_sizeTer_;
        m_variableTop_ = element.m_variableTop_;
        m_caseBit_ = element.m_caseBit_;
    }

        // package private methods -------------------------------------------
        
        /**
         * Initializing the elements
         */
        public void clear()
        {
            m_prefixChars_ = null;
            m_prefix_ = 0;
            m_uchars_ = null;
            m_cPoints_ = null;    
            m_cPointsOffset_ = 0;  
            m_CELength_ = 0;
            m_mapCE_ = 0;
            Arrays.fill(m_sizePrim_, 0);
            Arrays.fill(m_sizeSec_, 0);
            Arrays.fill(m_sizeTer_, 0);
            m_variableTop_ = false;
            m_caseBit_ = false;
        }

        
        /**
         * Hashcode calculation for token
         * @return the hashcode
         */
        public int hashCode()
        {
        String str = m_cPoints_.substring(m_cPointsOffset_);
        return str.hashCode();
    }
        
    /**
     * Equals calculation
     * @param target object to compare
     * @return true if target is the same as this object
     */
    public boolean equals(Object target)
    {
        if (target == this) {
        return true;
        }
        if (target instanceof Elements) {
        Elements t = (Elements)target;
        int size = m_cPoints_.length() - m_cPointsOffset_;
        if (size == t.m_cPoints_.length() - t.m_cPointsOffset_) {
            return t.m_cPoints_.regionMatches(t.m_cPointsOffset_, 
                              m_cPoints_, 
                              m_cPointsOffset_, size);
        }
            }
            return false;
    }
    }

    // private data member ---------------------------------------------------
    
    /**
     * Maximum strength used in CE building
     */
    private static final int CE_BASIC_STRENGTH_LIMIT_ = 3;
    /**
     * Maximum collation strength
     */
    private static final int CE_STRENGTH_LIMIT_ = 16;
    /**
     * Strength mask array, used in inverse UCA
     */
    private static final int STRENGTH_MASK_[] = {0xFFFF0000, 0xFFFFFF00, 
                                                 0xFFFFFFFF};
    /**
     * CE tag for not found
     */
    private static final int CE_NOT_FOUND_ = 0xF0000000;
    /**
     * CE tag for not found
     */
    private static final int CE_NOT_FOUND_TAG_ = 0;
    /**
     * This code point results in an expansion 
     */
    private static final int CE_EXPANSION_TAG_ = 1;
    /** 
     * Start of a contraction 
     */
    private static final int CE_CONTRACTION_TAG_ = 2;
    /* 
     * Thai character - do the reordering 
     */
    //private static final int CE_THAI_TAG_ = 3;            
    /* 
     * Charset processing, not yet implemented
     */
    //private static final int CE_CHARSET_TAG_ = 4;         
    /** 
     * Lead surrogate that is tailored and doesn't start a contraction 
     */
    private static final int CE_SURROGATE_TAG_ = 5;
    /* 
     * AC00-D7AF
     */
    //private static final int CE_HANGUL_SYLLABLE_TAG_ = 6;
    /* 
     * D800-DBFF
     */
    //private static final int CE_LEAD_SURROGATE_TAG_ = 7;
    /* 
     * DC00-DFFF
     */
    //private static final int CE_TRAIL_SURROGATE_TAG_ = 8; 
    /*
     * 0x3400-0x4DB5, 0x4E00-0x9FA5, 0xF900-0xFA2D
     */    
    //private static final int CE_CJK_IMPLICIT_TAG_ = 9;
    private static final int CE_IMPLICIT_TAG_ = 10;
    private static final int CE_SPEC_PROC_TAG_ = 11;
    /** 
     * This is a three byte primary with starting secondaries and tertiaries.
     * It fits in a single 32 bit CE and is used instead of expansion to save
     * space without affecting the performance (hopefully) 
     */
    private static final int CE_LONG_PRIMARY_TAG_ = 12;  
    /** 
     * Unsafe UChar hash table table size. Size is 32 bytes for 1 bit for each 
     * latin 1 char + some power of two for hashing the rest of the chars. 
     * Size in bytes                               
     */
    private static final int UNSAFECP_TABLE_SIZE_ = 1056;
    /** 
     * Mask value down to "some power of two" -1. Number of bits, not num of 
     * bytes.       
     */
    private static final int UNSAFECP_TABLE_MASK_ = 0x1fff;
    /**
     * Case values
     */
    private static final int UPPER_CASE_ = 0x80;
    private static final int MIXED_CASE_ = 0x40;
    private static final int LOWER_CASE_ = 0x00;
    /*
     * Initial table size
     */
    //private static final int INIT_TABLE_SIZE_ = 1028;
    /*
     * Header size, copied from ICU4C, to be changed when that value changes
     */
    //private static final int HEADER_SIZE_ = 0xC4;
    /**
     * Contraction table new element indicator
     */
    private static final int CONTRACTION_TABLE_NEW_ELEMENT_ = 0xFFFFFF;
    /**
     * Parser for the rules
     */
    private CollationRuleParser m_parser_;
    /**
     * Utility UCA collation element iterator
     */
    private CollationElementIterator m_utilColEIter_;
    /**
     * Utility data members
     */
    private CEGenerator m_utilGens_[] = {new CEGenerator(), new CEGenerator(),
                                         new CEGenerator()};
    private int m_utilCEBuffer_[] = new int[CE_BASIC_STRENGTH_LIMIT_];
    private int m_utilIntBuffer_[] = new int[CE_STRENGTH_LIMIT_];
    private Elements m_utilElement_ = new Elements();
    private Elements m_utilElement2_ = new Elements();
    private CollationRuleParser.Token m_utilToken_ 
    = new CollationRuleParser.Token();
    private int m_utilCountBuffer_[] = new int[6];     
    private long m_utilLongBuffer_[] = new long[5];
    private WeightRange m_utilLowerWeightRange_[] = 
    {new WeightRange(), new WeightRange(), 
     new WeightRange(), new WeightRange(), 
     new WeightRange()}; 
    private WeightRange m_utilUpperWeightRange_[] = 
    {new WeightRange(), new WeightRange(), 
     new WeightRange(), new WeightRange(), 
     new WeightRange()}; 
    private WeightRange m_utilWeightRange_ = new WeightRange();
    private char m_utilCharBuffer_[] = new char[256];
    private CanonicalIterator m_utilCanIter_ = new CanonicalIterator("");
    private StringBuffer m_utilStringBuffer_ = new StringBuffer("");
    // Flag indicating a combining marks table is required or not.
    private static boolean buildCMTabFlag = false;
    
    
    // private methods -------------------------------------------------------
    
    /**
     * @param listheader parsed rule tokens
     * @exception Exception thrown when internal error occurs
     */
    private void initBuffers(CollationRuleParser.TokenListHeader listheader) 
    throws Exception
    {
        CollationRuleParser.Token token = listheader.m_last_;
        Arrays.fill(m_utilIntBuffer_, 0, CE_STRENGTH_LIMIT_, 0);
        
    token.m_toInsert_ = 1;
    m_utilIntBuffer_[token.m_strength_] = 1;
    while (token.m_previous_ != null) {
        if (token.m_previous_.m_strength_ < token.m_strength_) { 
                // going up
        m_utilIntBuffer_[token.m_strength_] = 0;
        m_utilIntBuffer_[token.m_previous_.m_strength_] ++;
        } 
            else if (token.m_previous_.m_strength_ > token.m_strength_) { 
                // going down
        m_utilIntBuffer_[token.m_previous_.m_strength_] = 1;
        } 
            else {
        m_utilIntBuffer_[token.m_strength_] ++;
        }
        token = token.m_previous_;
        token.m_toInsert_ = m_utilIntBuffer_[token.m_strength_];
    } 
        
    token.m_toInsert_ = m_utilIntBuffer_[token.m_strength_];
    INVERSE_UCA_.getInverseGapPositions(listheader);
        
    token = listheader.m_first_;
    int fstrength = Collator.IDENTICAL;
    int initstrength = Collator.IDENTICAL;
        
    m_utilCEBuffer_[Collator.PRIMARY] = mergeCE(listheader.m_baseCE_, 
                            listheader.m_baseContCE_,
                            Collator.PRIMARY);
    m_utilCEBuffer_[Collator.SECONDARY] = mergeCE(listheader.m_baseCE_, 
                              listheader.m_baseContCE_,
                              Collator.SECONDARY);
    m_utilCEBuffer_[Collator.TERTIARY] = mergeCE(listheader.m_baseCE_, 
                             listheader.m_baseContCE_,
                             Collator.TERTIARY);
    while (token != null) {
        fstrength = token.m_strength_;
        if (fstrength < initstrength) {
        initstrength = fstrength;
        if (listheader.m_pos_[fstrength] == -1) {
            while (listheader.m_pos_[fstrength] == -1 && fstrength > 0) 
            {
                fstrength--;
            }
            if (listheader.m_pos_[fstrength] == -1) {
            throw new Exception("Internal program error");
            }
        }
        if (initstrength == Collator.TERTIARY) { 
                    // starting with tertiary
            m_utilCEBuffer_[Collator.PRIMARY] 
            = listheader.m_gapsLo_[fstrength * 3];
            m_utilCEBuffer_[Collator.SECONDARY] 
            = listheader.m_gapsLo_[fstrength * 3 + 1];
            m_utilCEBuffer_[Collator.TERTIARY] = getCEGenerator(
                                    m_utilGens_[Collator.TERTIARY], 
                                    listheader.m_gapsLo_, 
                                    listheader.m_gapsHi_, 
                                    token, fstrength); 
        } 
                else if (initstrength == Collator.SECONDARY) { 
                    // secondaries
            m_utilCEBuffer_[Collator.PRIMARY] 
            = listheader.m_gapsLo_[fstrength * 3];
            m_utilCEBuffer_[Collator.SECONDARY] 
            = getCEGenerator(
                                         m_utilGens_[Collator.SECONDARY], 
                                         listheader.m_gapsLo_, 
                                         listheader.m_gapsHi_, 
                                         token, fstrength);
            m_utilCEBuffer_[Collator.TERTIARY] 
            = getSimpleCEGenerator(
                           m_utilGens_[Collator.TERTIARY], 
                           token, Collator.TERTIARY);
        } 
                else { 
                    // primaries 
            m_utilCEBuffer_[Collator.PRIMARY] 
            = getCEGenerator(
                     m_utilGens_[Collator.PRIMARY], 
                     listheader.m_gapsLo_, 
                     listheader.m_gapsHi_, 
                     token, fstrength);
            m_utilCEBuffer_[Collator.SECONDARY] 
            = getSimpleCEGenerator(
                                               m_utilGens_[Collator.SECONDARY], 
                                               token, Collator.SECONDARY);
            m_utilCEBuffer_[Collator.TERTIARY] 
            = getSimpleCEGenerator(
                                               m_utilGens_[Collator.TERTIARY], 
                                               token, Collator.TERTIARY);
        }
        } 
            else {
        if (token.m_strength_ == Collator.TERTIARY) {
            m_utilCEBuffer_[Collator.TERTIARY] 
            = getNextGenerated(m_utilGens_[Collator.TERTIARY]);
        } 
                else if (token.m_strength_ == Collator.SECONDARY) {
            m_utilCEBuffer_[Collator.SECONDARY] 
            = getNextGenerated(m_utilGens_[Collator.SECONDARY]);
            m_utilCEBuffer_[Collator.TERTIARY] 
            = getSimpleCEGenerator(
                           m_utilGens_[Collator.TERTIARY], 
                           token, Collator.TERTIARY);
        } 
                else if (token.m_strength_ == Collator.PRIMARY) {
            m_utilCEBuffer_[Collator.PRIMARY] 
            = getNextGenerated(
                       m_utilGens_[Collator.PRIMARY]);
            m_utilCEBuffer_[Collator.SECONDARY] 
            = getSimpleCEGenerator(
                           m_utilGens_[Collator.SECONDARY], 
                           token, Collator.SECONDARY);
            m_utilCEBuffer_[Collator.TERTIARY] 
            = getSimpleCEGenerator(
                           m_utilGens_[Collator.TERTIARY], 
                           token, Collator.TERTIARY);
        }
        }
        doCE(m_utilCEBuffer_, token);
        token = token.m_next_;
    }
    }

    /**
     * Get the next generated ce
     * @param g ce generator
     * @return next generated ce 
     */
    private int getNextGenerated(CEGenerator g) 
    {
        g.m_current_ = nextWeight(g);
        return g.m_current_;
    }

    /**
     * @param g CEGenerator
     * @param token rule token
     * @param strength 
     * @return ce generator
     * @exception Exception thrown when internal error occurs
     */
    private int getSimpleCEGenerator(CEGenerator g, 
                                     CollationRuleParser.Token token, 
                                     int strength) throws Exception
    {
        int high, low, count = 1;
        int maxbyte = (strength == Collator.TERTIARY) ? 0x3F : 0xFF;

    if (strength == Collator.SECONDARY) {
        low = RuleBasedCollator.COMMON_TOP_2_ << 24;
        high = 0xFFFFFFFF;
        count = 0xFF - RuleBasedCollator.COMMON_TOP_2_;
    } 
        else {
        low = RuleBasedCollator.BYTE_COMMON_ << 24; //0x05000000;
        high = 0x40000000;
        count = 0x40 - RuleBasedCollator.BYTE_COMMON_;
    }
    
    if (token.m_next_ != null && token.m_next_.m_strength_ == strength) {
        count = token.m_next_.m_toInsert_;
    } 
    
    g.m_rangesLength_ = allocateWeights(low, high, count, maxbyte, 
                                            g.m_ranges_);
    g.m_current_ = RuleBasedCollator.BYTE_COMMON_ << 24;
    
    if (g.m_rangesLength_ == 0) {
        throw new Exception("Internal program error");
    }
    return g.m_current_;
    }

    /**
     * Combines 2 ce into one with respect to the argument strength
     * @param ce1 first ce
     * @param ce2 second ce
     * @param strength strength to use
     * @return combined ce
     */
    private static int mergeCE(int ce1, int ce2, int strength) 
    {
        int mask = RuleBasedCollator.CE_TERTIARY_MASK_;
        if (strength == Collator.SECONDARY) {
            mask = RuleBasedCollator.CE_SECONDARY_MASK_;
        }
        else if (strength == Collator.PRIMARY) {
            mask = RuleBasedCollator.CE_PRIMARY_MASK_;
        }
        ce1 &= mask;
        ce2 &= mask;
        switch (strength) 
        {
            case Collator.PRIMARY:
                return ce1 | ce2 >>> 16;
            case Collator.SECONDARY:
                return ce1 << 16 | ce2 << 8;
            default:
                return ce1 << 24 | ce2 << 16;
        }
    }
    
    /**
     * @param g CEGenerator
     * @param lows low gap array
     * @param highs high gap array
     * @param token rule token
     * @param fstrength 
     * @exception Exception thrown when internal error occurs
     */
    private int getCEGenerator(CEGenerator g, int lows[], int highs[], 
                               CollationRuleParser.Token token, int fstrength) 
    throws Exception
    {
    int strength = token.m_strength_;
    int low = lows[fstrength * 3 + strength];
    int high = highs[fstrength * 3 + strength];
    int maxbyte = 0;
    if(strength == Collator.TERTIARY) {
        maxbyte = 0x3F;
    } else if(strength == Collator.PRIMARY) {
        maxbyte = 0xFE;
    } else {
        maxbyte = 0xFF;
    }
    
    int count = token.m_toInsert_;
    
    if (Utility.compareUnsigned(low, high) >= 0 
            && strength > Collator.PRIMARY) {
        int s = strength;
        while (true) {
        s --;
        if (lows[fstrength * 3 + s] != highs[fstrength * 3 + s]) {
            if (strength == Collator.SECONDARY) {
                if (low < (RuleBasedCollator.COMMON_TOP_2_ << 24)) {
                    // Override if low range is less than UCOL_COMMON_TOP2. 
                    low = RuleBasedCollator.COMMON_TOP_2_ << 24;
                }
                high = 0xFFFFFFFF;
            } 
            else {
                if ( low < RuleBasedCollator.COMMON_BOTTOM_3<<24 ) { 
                    // Override if low range is less than UCOL_COMMON_BOT3. 
                    low = RuleBasedCollator.COMMON_BOTTOM_3 <<24;
                }   
                high = 0x40000000;
            }
            break;
        }
        if (s < 0) {
            throw new Exception("Internal program error");
        }
        }
    } 
    if (low == 0) {
        low = 0x01000000;
    }
    if (strength == Collator.SECONDARY) { // similar as simple 
        if (Utility.compareUnsigned(low, 
                    RuleBasedCollator.COMMON_BOTTOM_2_ << 24) >= 0
                && Utility.compareUnsigned(low, 
                       RuleBasedCollator.COMMON_TOP_2_ << 24) < 0) {
        low = RuleBasedCollator.COMMON_TOP_2_ << 24;
            }
        if (Utility.compareUnsigned(high, 
                    RuleBasedCollator.COMMON_BOTTOM_2_ << 24) > 0 
                && Utility.compareUnsigned(high, 
                       RuleBasedCollator.COMMON_TOP_2_ << 24) < 0) {
        high = RuleBasedCollator.COMMON_TOP_2_ << 24;
        } 
        if (Utility.compareUnsigned(low, 
                    RuleBasedCollator.COMMON_BOTTOM_2_ << 24) < 0) {
        g.m_rangesLength_ = allocateWeights(
                            RuleBasedCollator.BYTE_UNSHIFTED_MIN_ << 24, 
                            high, count, maxbyte, g.m_ranges_);
        g.m_current_ = nextWeight(g);
        //g.m_current_ = RuleBasedCollator.COMMON_BOTTOM_2_ << 24;
        return g.m_current_;
        }
    } 
    
    g.m_rangesLength_ = allocateWeights(low, high, count, maxbyte, 
                                            g.m_ranges_);
    if (g.m_rangesLength_ == 0) {
        throw new Exception("Internal program error");
    }
    g.m_current_ = nextWeight(g);
    return g.m_current_;
    }

    /**
     * @param ceparts list of collation elements parts
     * @param token rule token
     * @exception Exception thrown when forming case bits for expansions fails
     */
    private void doCE(int ceparts[], CollationRuleParser.Token token) 
    throws Exception
    {
        // this one makes the table and stuff
    // int noofbytes[] = new int[3];
    for (int i = 0; i < 3; i ++) {
        // noofbytes[i] = countBytes(ceparts[i]);
            m_utilIntBuffer_[i] = countBytes(ceparts[i]);
    }
    
    // Here we have to pack CEs from parts
    int cei = 0;
    int value = 0;
    
    while ((cei << 1) < m_utilIntBuffer_[0] || cei < m_utilIntBuffer_[1] 
               || cei < m_utilIntBuffer_[2]) {
        if (cei > 0) {
        value = RuleBasedCollator.CE_CONTINUATION_MARKER_;
        } else {
        value = 0;
        }
        
        if ((cei << 1) < m_utilIntBuffer_[0]) {
        value |= ((ceparts[0] >> (32 - ((cei + 1) << 4))) & 0xFFFF) 
                      << 16;
        }
        if (cei < m_utilIntBuffer_[1]) {
        value |= ((ceparts[1] >> (32 - ((cei + 1) << 3))) & 0xFF) << 8;
        }
            
        if (cei < m_utilIntBuffer_[2]) {
        value |= ((ceparts[2] >> (32 - ((cei+1) << 3))) & 0x3F);
        }
        token.m_CE_[cei] = value;
        cei ++;
    }
    if (cei == 0) { // totally ignorable
        token.m_CELength_ = 1;
        token.m_CE_[0] = 0;
    } 
    else { // there is at least something
        token.m_CELength_ = cei;
    }
          
    // Case bits handling for expansion
    if(token.m_CE_[0] != 0) { // case bits should be set only for non-ignorables
        int startoftokenrule = token.m_source_ & 0xFF;
        if ((token.m_source_ >>> 24) > 1) {
            // Do it manually
            int length = token.m_source_ >>> 24;
            String tokenstr = token.m_rules_.substring(startoftokenrule, 
                                   startoftokenrule + length);
            token.m_CE_[0] |= getCaseBits(tokenstr);
        } 
        else {
            // Copy it from the UCA
            int caseCE 
            = getFirstCE(token.m_rules_.charAt(startoftokenrule));
            token.m_CE_[0] |= (caseCE & 0xC0);
        }
    }
    }

    /**
     * Count the number of non-zero bytes used in the ce
     * @param ce 
     * @return number of non-zero bytes used in ce
     */
    private static final int countBytes(int ce)   
    {                               
    int mask = 0xFFFFFFFF;   
    int result = 0;              
    while (mask != 0) {            
        if ((ce & mask) != 0) { 
        result ++;            
        }                           
        mask >>>= 8;                 
    }   
        return result;                          
    }
    
    /**
     * We are ready to create collation elements
     * @param t build table to insert
     * @param lh rule token list header
     */
    private void createElements(BuildTable t, 
                CollationRuleParser.TokenListHeader lh)
    {
    CollationRuleParser.Token tok = lh.m_first_;
    m_utilElement_.clear();
    while (tok != null) {
        // first, check if there are any expansions
        // if there are expansions, we need to do a little bit more 
        // processing since parts of expansion can be tailored, while 
        // others are not
        if (tok.m_expansion_ != 0) {
        int len = tok.m_expansion_ >>> 24;
        int currentSequenceLen = len;
        int expOffset = tok.m_expansion_ & 0x00FFFFFF;
        m_utilToken_.m_source_ = currentSequenceLen | expOffset;
        m_utilToken_.m_rules_ = m_parser_.m_source_;
    
        while (len > 0) {
            currentSequenceLen = len;
            while (currentSequenceLen > 0) {
            m_utilToken_.m_source_ = (currentSequenceLen << 24) 
                | expOffset;
            CollationRuleParser.Token expt = 
                (CollationRuleParser.Token)
                m_parser_.m_hashTable_.get(m_utilToken_);
            if (expt != null 
                && expt.m_strength_ 
                != CollationRuleParser.TOKEN_RESET_) { 
                // expansion is tailored
                int noOfCEsToCopy = expt.m_CELength_;
                for (int j = 0; j < noOfCEsToCopy; j ++) {
                tok.m_expCE_[tok.m_expCELength_ + j] 
                    = expt.m_CE_[j];
                }
                tok.m_expCELength_ += noOfCEsToCopy;
                // never try to add codepoints and CEs.
                // For some odd reason, it won't work.
                expOffset += currentSequenceLen; //noOfCEsToCopy;
                len -= currentSequenceLen; //noOfCEsToCopy;
                break;
            } 
            else {
                currentSequenceLen --;
            }
            }
            if (currentSequenceLen == 0) { 
            // couldn't find any tailored subsequence, will have to 
            // get one from UCA. first, get the UChars from the 
            // rules then pick CEs out until there is no more and 
            // stuff them into expansion
            m_utilColEIter_.setText(m_parser_.m_source_.substring(
                                          expOffset, expOffset + 1));
            while (true) {
                int order = m_utilColEIter_.next();
                if (order == CollationElementIterator.NULLORDER) {
                break;
                }
                tok.m_expCE_[tok.m_expCELength_ ++] = order;
            }
            expOffset ++;
            len --;
            }
        }
        } 
        else {
        tok.m_expCELength_ = 0;
        }
    
        // set the ucaelement with obtained values
            m_utilElement_.m_CELength_ = tok.m_CELength_ + tok.m_expCELength_;
            
        // copy CEs
        System.arraycopy(tok.m_CE_, 0, m_utilElement_.m_CEs_, 0, 
                             tok.m_CELength_);
        System.arraycopy(tok.m_expCE_, 0, m_utilElement_.m_CEs_, 
                             tok.m_CELength_, tok.m_expCELength_);
    
        // copy UChars 
        // We kept prefix and source kind of together, as it is a kind of a 
        // contraction. 
        // However, now we have to slice the prefix off the main thing - 
        m_utilElement_.m_prefix_ = 0;// el.m_prefixChars_;
        m_utilElement_.m_cPointsOffset_ = 0; //el.m_uchars_;
        if (tok.m_prefix_ != 0) { 
        // we will just copy the prefix here, and adjust accordingly in 
        // the addPrefix function in ucol_elm. The reason is that we 
        // need to add both composed AND decomposed elements to the 
        // unsafe table.
        int size = tok.m_prefix_ >> 24;
        int offset = tok.m_prefix_ & 0x00FFFFFF;
        m_utilElement_.m_prefixChars_ 
            = m_parser_.m_source_.substring(offset, offset + size);
        size = (tok.m_source_ >> 24) - (tok.m_prefix_ >> 24); 
        offset = (tok.m_source_ & 0x00FFFFFF) + (tok.m_prefix_ >> 24);
        m_utilElement_.m_uchars_ 
            = m_parser_.m_source_.substring(offset, offset + size);
        } 
        else {
        m_utilElement_.m_prefixChars_ = null;
        int offset = tok.m_source_ & 0x00FFFFFF;
        int size = tok.m_source_ >>> 24;
        m_utilElement_.m_uchars_ = m_parser_.m_source_.substring(offset, 
                                     offset + size);
        }
        m_utilElement_.m_cPoints_ = m_utilElement_.m_uchars_;
        
        boolean containCombinMarks = false;
        for (int i = 0; i < m_utilElement_.m_cPoints_.length() 
             - m_utilElement_.m_cPointsOffset_; i ++) {
        if (isJamo(m_utilElement_.m_cPoints_.charAt(i))) {
            t.m_collator_.m_isJamoSpecial_ = true;
            break;
        }
        if ( !buildCMTabFlag ) {
            // check combining class
            char fcd = NormalizerImpl.getFCD16(m_utilElement_.m_cPoints_.charAt(i));
            if ( (fcd & 0xff) == 0 ) {
                // reset flag when current char is not combining mark.
                containCombinMarks = false;  
            }
            else {
                containCombinMarks = true;
            }
        }
        }
        
        if ( !buildCMTabFlag && containCombinMarks ) {
            buildCMTabFlag = true;
        }
            
            /***
    
            // Case bits handling 
            m_utilElement_.m_CEs_[0] &= 0xFFFFFF3F; 
        // Clean the case bits field
            if (m_utilElement_.m_cPoints_.length() 
                - m_utilElement_.m_cPointsOffset_ > 1) {
        // Do it manually
        m_utilElement_.m_CEs_[0] 
        |= getCaseBits(m_utilElement_.m_cPoints_);
            } 
            else {
        // Copy it from the UCA
        int caseCE = getFirstCE(m_utilElement_.m_cPoints_.charAt(0));
        m_utilElement_.m_CEs_[0] |= (caseCE & 0xC0);
            }
    
            ***/
        // and then, add it
        addAnElement(t, m_utilElement_);
        tok = tok.m_next_;
    }   
    }
    
    /**
     * Testing if the string argument has case
     * @param src string
     * @return the case for this char array
     * @exception Exception thrown when internal program error occurs
     */
    private final int getCaseBits(String src) throws Exception
    {
    int uCount = 0; 
    int lCount = 0;
    src = Normalizer.decompose(src, true);
    m_utilColEIter_.setText(src);
    for (int i = 0; i < src.length(); i++) {
        m_utilColEIter_.setText(src.substring(i, i + 1));
        int order = m_utilColEIter_.next();
        if (RuleBasedCollator.isContinuation(order)) {
        throw new Exception("Internal program error");
        }
        if ((order & RuleBasedCollator.CE_CASE_BIT_MASK_)
        == UPPER_CASE_) {
        uCount ++;
        } 
        else {
        char ch = src.charAt(i);
        if (UCharacter.isLowerCase(ch)) {
            lCount ++;
        } 
        else {
            if (toSmallKana(ch) == ch && toLargeKana(ch) != ch) {
            lCount ++;
            }
        }
        }
    }
        
    if (uCount != 0 && lCount != 0) {
        return MIXED_CASE_;
    } 
    else if (uCount != 0) {
        return UPPER_CASE_;
    } 
    else {
        return LOWER_CASE_;
    }
    }
    
    /**
     * Converts a char to the uppercase Kana
     * @param ch character to convert
     * @return the converted Kana character
     */
    private static final char toLargeKana(char ch) 
    {
    if (0x3042 < ch && ch < 0x30ef) { // Kana range 
        switch (ch - 0x3000) {
        case 0x41: 
        case 0x43: 
        case 0x45: 
        case 0x47: 
        case 0x49: 
        case 0x63: 
        case 0x83: 
        case 0x85: 
        case 0x8E:
        case 0xA1: 
        case 0xA3: 
        case 0xA5: 
        case 0xA7: 
        case 0xA9: 
        case 0xC3: 
        case 0xE3: 
        case 0xE5: 
        case 0xEE:
        ch ++;
        break;
        case 0xF5:
        ch = 0x30AB;
        break;
        case 0xF6:
        ch = 0x30B1;
        break;
        }
    }
    return ch;
    }
    
    /**
     * Converts a char to the lowercase Kana
     * @param ch character to convert
     * @return the converted Kana character
     */
    private static final char toSmallKana(char ch) 
    {
    if (0x3042 < ch && ch < 0x30ef) { // Kana range
        switch (ch - 0x3000) {
        case 0x42: 
        case 0x44: 
        case 0x46: 
        case 0x48: 
        case 0x4A: 
        case 0x64: 
        case 0x84: 
        case 0x86: 
        case 0x8F:
        case 0xA2: 
        case 0xA4: 
        case 0xA6: 
        case 0xA8: 
        case 0xAA: 
        case 0xC4: 
        case 0xE4: 
        case 0xE6: 
        case 0xEF:
        ch --;
        break;
        case 0xAB:
        ch = 0x30F5;
        break;
        case 0xB1:
        ch = 0x30F6;
        break;
        }
    }
    return ch;
    }

    /**
     * This should be connected to special Jamo handling.
     */
    private int getFirstCE(char ch) 
    {
        m_utilColEIter_.setText(UCharacter.toString(ch));
    return m_utilColEIter_.next();
    }
    
    /** 
     * This adds a read element, while testing for existence 
     * @param t build table
     * @param element 
     * @return ce
     */
    private int addAnElement(BuildTable t, Elements element) 
    {
        Vector expansions = t.m_expansions_;
        element.m_mapCE_ = 0;
        
        if (element.m_CELength_ == 1) {
            element.m_mapCE_ = element.m_CEs_[0];

        } else {     
        // unfortunately, it looks like we have to look for a long primary 
        // here since in canonical closure we are going to hit some long 
        // primaries from the first phase, and they will come back as 
        // continuations/expansions destroying the effect of the previous 
        // opitimization. A long primary is a three byte primary with 
        // starting secondaries and tertiaries. It can appear in long runs 
        // of only primary differences (like east Asian tailorings) also, 
        // it should not be an expansion, as expansions would break with 
        // this
        if (element.m_CELength_ == 2 // a two CE expansion 
        && RuleBasedCollator.isContinuation(element.m_CEs_[1]) 
        && (element.m_CEs_[1] 
            & (~(0xFF << 24 | RuleBasedCollator.CE_CONTINUATION_MARKER_))) 
        == 0 // that has only primaries in continuation
        && (((element.m_CEs_[0] >> 8) & 0xFF) 
            == RuleBasedCollator.BYTE_COMMON_) 
        // a common secondary
        && ((element.m_CEs_[0] & 0xFF) 
            == RuleBasedCollator.BYTE_COMMON_) // and a common tertiary
        ) {
        element.m_mapCE_ = RuleBasedCollator.CE_SPECIAL_FLAG_ 
            // a long primary special
            | (CE_LONG_PRIMARY_TAG_ << 24) 
            // first and second byte of primary
            | ((element.m_CEs_[0] >> 8) & 0xFFFF00) 
            // third byte of primary
            | ((element.m_CEs_[1] >> 24) & 0xFF);   
        } 
        else {
                // omitting expansion offset in builder
                // (HEADER_SIZE_ >> 2)
        int expansion = RuleBasedCollator.CE_SPECIAL_FLAG_ 
            | (CE_EXPANSION_TAG_ 
               << RuleBasedCollator.CE_TAG_SHIFT_) 
            | (addExpansion(expansions, element.m_CEs_[0])
               << 4) & 0xFFFFF0;
    
        for (int i = 1; i < element.m_CELength_; i ++) {
            addExpansion(expansions, element.m_CEs_[i]);
        }
        if (element.m_CELength_ <= 0xF) {
            expansion |= element.m_CELength_;
        } 
        else {
            addExpansion(expansions, 0);
        }
        element.m_mapCE_ = expansion;
        setMaxExpansion(element.m_CEs_[element.m_CELength_ - 1],
                (byte)element.m_CELength_, 
                t.m_maxExpansions_);
        if (isJamo(element.m_cPoints_.charAt(0))){
            t.m_collator_.m_isJamoSpecial_ = true;
            setMaxJamoExpansion(element.m_cPoints_.charAt(0),
                    element.m_CEs_[element.m_CELength_ 
                              - 1],
                    (byte)element.m_CELength_,
                    t.m_maxJamoExpansions_);
        }
        }
    }
        
        // We treat digits differently - they are "uber special" and should be
        // processed differently if numeric collation is on. 
        int uniChar = 0;
        if ((element.m_uchars_.length() == 2) 
            && UTF16.isLeadSurrogate(element.m_uchars_.charAt(0))) {
            uniChar = UCharacterProperty.getRawSupplementary(
                                 element.m_uchars_.charAt(0), 
                                 element.m_uchars_.charAt(1));      
        } 
        else if (element.m_uchars_.length() == 1) {
            uniChar = element.m_uchars_.charAt(0);
        }
        
        // Here, we either have one normal CE OR mapCE is set. Therefore, we 
        // stuff only one element to the expansion buffer. When we encounter a 
        // digit and we don't do numeric collation, we will just pick the CE 
        // we have and break out of case (see ucol.cpp ucol_prv_getSpecialCE 
        // && ucol_prv_getSpecialPrevCE). If we picked a special, further 
        // processing will occur. If it's a simple CE, we'll return due
        // to how the loop is constructed.
        if (uniChar != 0 && UCharacter.isDigit(uniChar)) {
            // prepare the element
            int expansion = RuleBasedCollator.CE_SPECIAL_FLAG_ 
        | (CollationElementIterator.CE_DIGIT_TAG_
           << RuleBasedCollator.CE_TAG_SHIFT_) | 1; 
            if (element.m_mapCE_ != 0) { 
                // if there is an expansion, we'll pick it here
                expansion |= (addExpansion(expansions, element.m_mapCE_) << 4);
            } 
            else {
                expansion |= (addExpansion(expansions, element.m_CEs_[0]) << 4);
            }
            element.m_mapCE_ = expansion;
        }
    
    // here we want to add the prefix structure.
    // I will try to process it as a reverse contraction, if possible.
    // prefix buffer is already reversed.
    
    if (element.m_prefixChars_ != null &&
            element.m_prefixChars_.length() - element.m_prefix_ > 0) {
        // We keep the seen prefix starter elements in a hashtable we need 
            // it to be able to distinguish between the simple codepoints and 
            // prefix starters. Also, we need to use it for canonical closure.
        m_utilElement2_.m_caseBit_ = element.m_caseBit_;
            m_utilElement2_.m_CELength_ = element.m_CELength_;
            m_utilElement2_.m_CEs_ = element.m_CEs_;
            m_utilElement2_.m_mapCE_ = element.m_mapCE_;
            //m_utilElement2_.m_prefixChars_ = element.m_prefixChars_;
            m_utilElement2_.m_sizePrim_ = element.m_sizePrim_;
            m_utilElement2_.m_sizeSec_ = element.m_sizeSec_;
            m_utilElement2_.m_sizeTer_ = element.m_sizeTer_;
            m_utilElement2_.m_variableTop_ = element.m_variableTop_;
            m_utilElement2_.m_prefix_ = element.m_prefix_;
            m_utilElement2_.m_prefixChars_ = Normalizer.compose(element.m_prefixChars_, false);
            m_utilElement2_.m_uchars_ = element.m_uchars_;
            m_utilElement2_.m_cPoints_ = element.m_cPoints_;
            m_utilElement2_.m_cPointsOffset_ = 0;
            
        if (t.m_prefixLookup_ != null) {
        Elements uCE = (Elements)t.m_prefixLookup_.get(element);
        if (uCE != null) { 
                    // there is already a set of code points here
            element.m_mapCE_ = addPrefix(t, uCE.m_mapCE_, element);
        } 
                else { // no code points, so this spot is clean
            element.m_mapCE_ = addPrefix(t, CE_NOT_FOUND_, element);
            uCE = new Elements(element);
            uCE.m_cPoints_ = uCE.m_uchars_;
            t.m_prefixLookup_.put(uCE, uCE);
        }
        if (m_utilElement2_.m_prefixChars_.length() 
            != element.m_prefixChars_.length() - element.m_prefix_
                    || !m_utilElement2_.m_prefixChars_.regionMatches(0,
                                     element.m_prefixChars_, element.m_prefix_,
                                     m_utilElement2_.m_prefixChars_.length())) {
            // do it!
                    m_utilElement2_.m_mapCE_ = addPrefix(t, element.m_mapCE_, 
                                                         m_utilElement2_);
        }
        }
    }
    
    // We need to use the canonical iterator here
    // the way we do it is to generate the canonically equivalent strings 
    // for the contraction and then add the sequences that pass FCD check
    if (element.m_cPoints_.length() - element.m_cPointsOffset_ > 1 
        && !(element.m_cPoints_.length() - element.m_cPointsOffset_ == 2 
         && UTF16.isLeadSurrogate(element.m_cPoints_.charAt(0)) 
         && UTF16.isTrailSurrogate(element.m_cPoints_.charAt(1)))) { 
            // this is a contraction, we should check whether a composed form 
            // should also be included
        m_utilCanIter_.setSource(element.m_cPoints_);
        String source = m_utilCanIter_.next();
        while (source != null && source.length() > 0) {
        if (Normalizer.quickCheck(source, Normalizer.FCD,0) 
                    != Normalizer.NO) {
            element.m_uchars_ = source;
            element.m_cPoints_ = element.m_uchars_;
            finalizeAddition(t, element);
        }
        source = m_utilCanIter_.next();
        }
        
        return element.m_mapCE_;
    } 
        else {
        return finalizeAddition(t, element);  
    }
    }
    
    /**
     * Adds an expansion ce to the expansion vector
     * @param expansions vector to add to
     * @param value of the expansion
     * @return the current position of the new element
     */
    private static final int addExpansion(Vector expansions, int value) 
    {
    expansions.add(new Integer(value));
    return expansions.size() - 1;
    }
    
    /**
     * Looks for the maximum length of all expansion sequences ending with the 
     * same collation element. The size required for maxexpansion and maxsize 
     * is returned if the arrays are too small.
     * @param endexpansion the last expansion collation element to be added
     * @param expansionsize size of the expansion
     * @param maxexpansion data structure to store the maximum expansion data.
     * @returns size of the maxexpansion and maxsize used.
     */
    private static int setMaxExpansion(int endexpansion, byte expansionsize,
                       MaxExpansionTable maxexpansion)
    {
    int start = 0;
    int limit = maxexpansion.m_endExpansionCE_.size();
        long unsigned = (long)endexpansion;
        unsigned &= 0xFFFFFFFFl;
    
    // using binary search to determine if last expansion element is 
    // already in the array 
    int result = -1;
    while (start < limit - 1) {                                                
        int mid = start + ((limit - start) >> 1);                                    
            long unsignedce = ((Integer)maxexpansion.m_endExpansionCE_.get(
                                       mid)).intValue(); 
            unsignedce &= 0xFFFFFFFFl;
        if (unsigned <= unsignedce) {                                                   
        limit = mid;                                                           
        }                                                                        
        else {                                                                   
        start = mid;                                                           
        }                                                                        
    } 
          
    if (((Integer)maxexpansion.m_endExpansionCE_.get(start)).intValue() 
        == endexpansion) {                                                     
        result = start;  
    }                                                                          
    else if (((Integer)maxexpansion.m_endExpansionCE_.get(limit)).intValue() 
         == endexpansion) {                                                     
        result = limit;      
    }                                            
    if (result > -1) {
        // found the ce in expansion, we'll just modify the size if it 
        // is smaller
        Object currentsize = maxexpansion.m_expansionCESize_.get(result);
        if (((Byte)currentsize).byteValue() < expansionsize) {
        maxexpansion.m_expansionCESize_.set(result, 
                            new Byte(expansionsize));
        }
    }
    else {
        // we'll need to squeeze the value into the array. initial 
        // implementation. shifting the subarray down by 1
        maxexpansion.m_endExpansionCE_.insertElementAt(
                                                   new Integer(endexpansion),
                                                   start + 1);
        maxexpansion.m_expansionCESize_.insertElementAt(
                                new Byte(expansionsize),
                                start + 1);
    }
    return maxexpansion.m_endExpansionCE_.size();
    }
    
    /**
     * Sets the maximum length of all jamo expansion sequences ending with the 
     * same collation element. The size required for maxexpansion and maxsize 
     * is returned if the arrays are too small.
     * @param ch the jamo codepoint
     * @param endexpansion the last expansion collation element to be added
     * @param expansionsize size of the expansion
     * @param maxexpansion data structure to store the maximum expansion data.
     * @returns size of the maxexpansion and maxsize used.
     */
    private static int setMaxJamoExpansion(char ch, int endexpansion,
                       byte expansionsize,
                       MaxJamoExpansionTable maxexpansion)
    {
    boolean isV = true;
    if (ch >= 0x1100 && ch <= 0x1112) {
        // determines L for Jamo, doesn't need to store this since it is 
        // never at the end of a expansion
        if (maxexpansion.m_maxLSize_ < expansionsize) {
        maxexpansion.m_maxLSize_ = expansionsize;
        }
        return maxexpansion.m_endExpansionCE_.size();
    }
    
    if (ch >= 0x1161 && ch <= 0x1175) {
        // determines V for Jamo
        if (maxexpansion.m_maxVSize_ < expansionsize) {
        maxexpansion.m_maxVSize_ = expansionsize;
        }
    }
    
    if (ch >= 0x11A8 && ch <= 0x11C2) {
        isV = false;
        // determines T for Jamo
        if (maxexpansion.m_maxTSize_ < expansionsize) {
        maxexpansion.m_maxTSize_ = expansionsize;
        }
    }

        int pos = maxexpansion.m_endExpansionCE_.size();    
    while (pos > 0) {
        pos --;
        if (((Integer)maxexpansion.m_endExpansionCE_.get(pos)).intValue() 
        == endexpansion) {
        return maxexpansion.m_endExpansionCE_.size();
        }
    }
    maxexpansion.m_endExpansionCE_.add(new Integer(endexpansion));
    maxexpansion.m_isV_.add(isV ? Boolean.TRUE : Boolean.FALSE);
          
    return maxexpansion.m_endExpansionCE_.size();
    }
    
    /**
     * Adds a prefix to the table
     * @param t build table to update
     * @param CE collation element to add
     * @param element rule element to add
     * @return modified ce
     */
    private int addPrefix(BuildTable t, int CE, Elements element) 
    {
    // currently the longest prefix we're supporting in Japanese is two 
    // characters long. Although this table could quite easily mimic 
    // complete contraction stuff there is no good reason to make a general 
    // solution, as it would require some error prone messing.
    ContractionTable contractions = t.m_contractions_;
    String oldCP = element.m_cPoints_;
    int oldCPOffset = element.m_cPointsOffset_;
        
    contractions.m_currentTag_ = CE_SPEC_PROC_TAG_;
    // here, we will normalize & add prefix to the table.
    int size = element.m_prefixChars_.length() - element.m_prefix_;
    for (int j = 1; j < size; j ++) {   
        // First add NFD prefix chars to unsafe CP hash table 
        // Unless it is a trail surrogate, which is handled algoritmically 
        // and shouldn't take up space in the table.
        char ch = element.m_prefixChars_.charAt(j + element.m_prefix_);
        if (!UTF16.isTrailSurrogate(ch)) {
        unsafeCPSet(t.m_unsafeCP_, ch);
        }
    }
        
    // StringBuffer reversed = new StringBuffer();
        m_utilStringBuffer_.delete(0, m_utilStringBuffer_.length());
    for (int j = 0; j < size; j ++) { 
        // prefixes are going to be looked up backwards
        // therefore, we will promptly reverse the prefix buffer...
        int offset = element.m_prefixChars_.length() - j - 1;
        m_utilStringBuffer_.append(element.m_prefixChars_.charAt(offset));
    }
    element.m_prefixChars_ = m_utilStringBuffer_.toString();
    element.m_prefix_ = 0;
    
    // the first codepoint is also unsafe, as it forms a 'contraction' with 
    // the prefix
    if (!UTF16.isTrailSurrogate(element.m_cPoints_.charAt(0))) {
        unsafeCPSet(t.m_unsafeCP_, element.m_cPoints_.charAt(0));
    }
        
    element.m_cPoints_ = element.m_prefixChars_;
    element.m_cPointsOffset_ = element.m_prefix_;
    
    // Add the last char of the contraction to the contraction-end hash 
    // table. unless it is a trail surrogate, which is handled 
    // algorithmically and shouldn't be in the table
    if (!UTF16.isTrailSurrogate(
                    element.m_cPoints_.charAt(element.m_cPoints_.length() - 1))) {
        ContrEndCPSet(t.m_contrEndCP_, element.m_cPoints_.charAt(
                                     element.m_cPoints_.length() - 1));
    }
    // First we need to check if contractions starts with a surrogate
    // int cp = UTF16.charAt(element.m_cPoints_, element.m_cPointsOffset_);
    
    // If there are any Jamos in the contraction, we should turn on special 
    // processing for Jamos
    if (isJamo(element.m_prefixChars_.charAt(element.m_prefix_))) {
        t.m_collator_.m_isJamoSpecial_ = true;
    }
    // then we need to deal with it 
    // we could aready have something in table - or we might not 
    if (!isPrefix(CE)) { 
        // if it wasn't contraction, we wouldn't end up here
        int firstContractionOffset = addContraction(contractions, 
                            CONTRACTION_TABLE_NEW_ELEMENT_, 
                            (char)0, CE);
        int newCE = processContraction(contractions, element, 
                       CE_NOT_FOUND_);
        addContraction(contractions, firstContractionOffset, 
                           element.m_prefixChars_.charAt(element.m_prefix_), 
                           newCE);
        addContraction(contractions, firstContractionOffset, (char)0xFFFF, 
                           CE);
        CE = constructSpecialCE(CE_SPEC_PROC_TAG_, firstContractionOffset);
    } 
    else { 
        // we are adding to existing contraction 
        // there were already some elements in the table, so we need to add 
        // a new contraction 
        // Two things can happen here: either the codepoint is already in 
        // the table, or it is not
        char ch = element.m_prefixChars_.charAt(element.m_prefix_);
        int position = findCP(contractions, CE, ch);
        if (position > 0) {       
        // if it is we just continue down the chain 
        int eCE = getCE(contractions, CE, position);
        int newCE = processContraction(contractions, element, eCE);
        setContraction(contractions, CE, position, ch, newCE);
        } 
        else {                  
        // if it isn't, we will have to create a new sequence 
        processContraction(contractions, element, CE_NOT_FOUND_);
        insertContraction(contractions, CE, ch, element.m_mapCE_);
        }
    }
    
    element.m_cPoints_ = oldCP;
    element.m_cPointsOffset_ = oldCPOffset;
    
    return CE;
    }
    
    /**
     * Checks if the argument ce is a contraction
     * @param CE collation element
     * @return true if argument ce is a contraction
     */
    private static final boolean isContraction(int CE) 
    {
    return isSpecial(CE) && (getCETag(CE) == CE_CONTRACTION_TAG_);
    }
    
    /**
     * Checks if the argument ce has a prefix
     * @param CE collation element
     * @return true if argument ce has a prefix
     */
    private static final boolean isPrefix(int CE) 
    {
    return isSpecial(CE) && (getCETag(CE) == CE_SPEC_PROC_TAG_);
    }
    
    /**
     * Checks if the argument ce is special
     * @param CE collation element
     * @return true if argument ce is special
     */
    private static final boolean isSpecial(int CE) 
    {
    return (CE & RuleBasedCollator.CE_SPECIAL_FLAG_) == 0xF0000000;
    }
    
    /**
     * Checks if the argument ce has a prefix
     * @param CE collation element
     * @return true if argument ce has a prefix
     */
    private static final int getCETag(int CE) 
    {
    return (CE & RuleBasedCollator.CE_TAG_MASK_) >>> 
        RuleBasedCollator.CE_TAG_SHIFT_;
    }
    
    /**
     * Gets the ce at position in contraction table
     * @param table contraction table
     * @param position offset to the contraction table
     * @return ce
     */
    private static final int getCE(ContractionTable table, int element, 
                   int position) 
    {
    element &= 0xFFFFFF;
        BasicContractionTable tbl = getBasicContractionTable(table, element);
        
        if (tbl == null) {
            return CE_NOT_FOUND_;
        }
    if (position > tbl.m_CEs_.size() || position == -1) {
        return CE_NOT_FOUND_;
    } 
    else {
        return ((Integer)tbl.m_CEs_.get(position)).intValue();
    }
    }
    
    /**
     * Sets the unsafe character
     * @param table unsafe table
     * @param c character to be added
     */
    private static final void unsafeCPSet(byte table[], char c) 
    {
    int hash = c;
    if (hash >= (UNSAFECP_TABLE_SIZE_ << 3)) {
        if (hash >= 0xd800 && hash <= 0xf8ff) {
        // Part of a surrogate, or in private use area. 
        // These don't go in the table                            
        return;
        }
        hash = (hash & UNSAFECP_TABLE_MASK_) + 256;
    }
    table[hash >> 3] |= (1 << (hash & 7));
    }
    
    /**
     * Sets the contraction end character
     * @param table contraction end table
     * @param c character to be added
     */
    private static final void ContrEndCPSet(byte table[], char c) 
    {
    int hash = c;
    if (hash >= (UNSAFECP_TABLE_SIZE_ << 3)) {
        hash = (hash & UNSAFECP_TABLE_MASK_) + 256;
    }
    table[hash >> 3] |= (1 << (hash & 7));
    }
    
    /** 
     * Adds more contractions in table. If element is non existant, it creates 
     * on. Returns element handle 
     * @param table contraction table
     * @param element offset to the contraction table
     * @param codePoint codepoint to add
     * @param value
     * @return collation element
     */
    private static int addContraction(ContractionTable table, int element, 
                                      char codePoint, int value) 
    {
    BasicContractionTable tbl = getBasicContractionTable(table, element);
    if (tbl == null) {
        tbl = addAContractionElement(table);
        element = table.m_elements_.size() - 1;
    } 
    
    tbl.m_CEs_.add(new Integer(value));
    tbl.m_codePoints_.append(codePoint);
    return constructSpecialCE(table.m_currentTag_, element);
    }

    /**
     * Adds a contraction element to the table
     * @param table contraction table to update
     * @return contraction 
     */
    private static BasicContractionTable addAContractionElement(
                                ContractionTable table) 
    {
    BasicContractionTable result = new BasicContractionTable();
    table.m_elements_.add(result);
    return result;
    }

    /**
     * Constructs a special ce
     * @param tag special tag
     * @param CE collation element 
     * @return a contraction ce
     */
    private static final int constructSpecialCE(int tag, int CE) 
    {
    return RuleBasedCollator.CE_SPECIAL_FLAG_ 
        | (tag << RuleBasedCollator.CE_TAG_SHIFT_) | (CE & 0xFFFFFF);
    }
    
    /**
     * Sets and inserts the element that has a contraction
     * @param contractions contraction table 
     * @param element contracting element
     * @param existingCE
     * @return contraction ce
     */
    private static int processContraction(ContractionTable contractions, 
                      Elements element, 
                      int existingCE) 
    {
    int firstContractionOffset = 0;
    // end of recursion 
    if (element.m_cPoints_.length() - element.m_cPointsOffset_ == 1) {
        if (isContractionTableElement(existingCE) 
        && getCETag(existingCE) == contractions.m_currentTag_) {
        changeContraction(contractions, existingCE, (char)0, 
                  element.m_mapCE_);
        changeContraction(contractions, existingCE, (char)0xFFFF,
                                  element.m_mapCE_);
        return existingCE;
        } 
        else {
        // can't do just that. existingCe might be a contraction, 
        // meaning that we need to do another step
        return element.m_mapCE_; 
        }
    }
    
    // this recursion currently feeds on the only element we have... 
    // We will have to copy it in order to accomodate for both backward 
    // and forward cycles
    // we encountered either an empty space or a non-contraction element 
    // this means we are constructing a new contraction sequence 
    element.m_cPointsOffset_ ++;
    if (!isContractionTableElement(existingCE)) { 
        // if it wasn't contraction, we wouldn't end up here
        firstContractionOffset = addContraction(contractions, 
                            CONTRACTION_TABLE_NEW_ELEMENT_, 
                            (char)0, existingCE);
        int newCE = processContraction(contractions, element, 
                       CE_NOT_FOUND_);
        addContraction(contractions, firstContractionOffset, 
               element.m_cPoints_.charAt(element.m_cPointsOffset_), 
               newCE);
        addContraction(contractions, firstContractionOffset, 
               (char)0xFFFF, existingCE);
        existingCE = constructSpecialCE(contractions.m_currentTag_, 
                        firstContractionOffset);
    } 
    else { 
        // we are adding to existing contraction
        // there were already some elements in the table, so we need to add 
        // a new contraction 
        // Two things can happen here: either the codepoint is already in 
        // the table, or it is not
        int position = findCP(contractions, existingCE, 
                  element.m_cPoints_.charAt(element.m_cPointsOffset_));
        if (position > 0) {       
        // if it is we just continue down the chain 
        int eCE = getCE(contractions, existingCE, position);
        int newCE = processContraction(contractions, element, eCE);
        setContraction(contractions, existingCE, position, 
                           element.m_cPoints_.charAt(element.m_cPointsOffset_), 
                   newCE);
        } 
        else {  
        // if it isn't, we will have to create a new sequence 
        int newCE = processContraction(contractions, element, 
                           CE_NOT_FOUND_);
        insertContraction(contractions, existingCE, 
                  element.m_cPoints_.charAt(element.m_cPointsOffset_), 
                  newCE);
        }
    }
    element.m_cPointsOffset_ --;
    return existingCE;
    }
    
    /**
     * Checks if CE belongs to the contraction table
     * @param CE collation element to test
     * @return true if CE belongs to the contraction table
     */
    private static final boolean isContractionTableElement(int CE) 
    { 
    return isSpecial(CE) 
        && (getCETag(CE) == CE_CONTRACTION_TAG_
        || getCETag(CE) == CE_SPEC_PROC_TAG_);
    }
    
    /**
     * Gets the codepoint 
     * @param table contraction table
     * @param element offset to the contraction element in the table
     * @param codePoint code point to look for
     * @return the offset to the code point
     */
    private static int findCP(ContractionTable table, int element, 
                  char codePoint) 
    {
    BasicContractionTable tbl = getBasicContractionTable(table, element);
    if (tbl == null) {
        return -1;
    }
    
    int position = 0;
    while (codePoint > tbl.m_codePoints_.charAt(position)) {
        position ++;
        if (position > tbl.m_codePoints_.length()) {
        return -1;
        }
    }
    if (codePoint == tbl.m_codePoints_.charAt(position)) {
        return position;
    } 
    else {
        return -1;
    }
    }

    /**
     * Gets the contraction element out of the contraction table
     * @param table contraction table
     * @param offset to the element in the contraction table
     * @return basic contraction element at offset in the contraction table
     */
    private static final BasicContractionTable getBasicContractionTable(
                                    ContractionTable table,
                                    int offset) 
    {
        offset &= 0xFFFFFF;
        if (offset == 0xFFFFFF) {
        return null;
        }
    return (BasicContractionTable)table.m_elements_.get(offset);
    }
    
    /**
     * Changes the contraction element
     * @param table contraction table
     * @param element offset to the element in the contraction table
     * @param codePoint codepoint 
     * @param newCE new collation element
     * @return basic contraction element at offset in the contraction table
     */
    private static final int changeContraction(ContractionTable table, 
                                               int element, char codePoint, 
                                               int newCE) 
    {
    BasicContractionTable tbl = getBasicContractionTable(table, element);    
    if (tbl == null) {
        return 0;
    }
    int position = 0;
    while (codePoint > tbl.m_codePoints_.charAt(position)) {
        position ++;
        if (position > tbl.m_codePoints_.length()) {
        return CE_NOT_FOUND_;
        }
    }
    if (codePoint == tbl.m_codePoints_.charAt(position)) {
        tbl.m_CEs_.set(position, new Integer(newCE));
        return element & 0xFFFFFF;
    } 
    else {
        return CE_NOT_FOUND_;
    }
    }
    
    /** 
     * Sets a part of contraction sequence in table. If element is non 
     * existant, it creates on. Returns element handle.
     * @param table contraction table
     * @param element offset to the contraction table
     * @param offset
     * @param codePoint contraction character
     * @param value ce value
     * @return new contraction ce
     */
    private static final int setContraction(ContractionTable table, 
                                            int element, int offset, 
                                            char codePoint, int value) 
    {
        element &= 0xFFFFFF;
    BasicContractionTable tbl = getBasicContractionTable(table, element);    
    if (tbl == null) {
        tbl = addAContractionElement(table);
        element = table.m_elements_.size() - 1;
    }
    
    tbl.m_CEs_.set(offset, new Integer(value));
    tbl.m_codePoints_.setCharAt(offset, codePoint);
    return constructSpecialCE(table.m_currentTag_, element);
    }
    
    /** 
     * Inserts a part of contraction sequence in table. Sequences behind the 
     * offset are moved back. If element is non existent, it creates on. 
     * @param table contraction
     * @param element offset to the table contraction
     * @param codePoint code point
     * @param value collation element value
     * @return contraction collation element
     */
    private static final int insertContraction(ContractionTable table, 
                                               int element, char codePoint, 
                                               int value) 
    {
    element &= 0xFFFFFF;
    BasicContractionTable tbl = getBasicContractionTable(table, element);
    if (tbl == null) {
        tbl = addAContractionElement(table);
        element = table.m_elements_.size() - 1;
    }
    
    int offset = 0;
    while (tbl.m_codePoints_.charAt(offset) < codePoint 
           && offset < tbl.m_codePoints_.length()) {
        offset ++;
    }
    
    tbl.m_CEs_.insertElementAt(new Integer(value), offset);
    tbl.m_codePoints_.insert(offset, codePoint);
    
    return constructSpecialCE(table.m_currentTag_, element);
    }
    
    /**
     * Finalize addition
     * @param t build table
     * @param element to add
     */
    private final static int finalizeAddition(BuildTable t, Elements element) 
    {
    int CE = CE_NOT_FOUND_;
        // This should add a completely ignorable element to the  
        // unsafe table, so that backward iteration will skip 
        // over it when treating contractions. 
        if (element.m_mapCE_ == 0) { 
            for (int i = 0; i < element.m_cPoints_.length(); i ++) { 
                char ch = element.m_cPoints_.charAt(i);
                if (!UTF16.isTrailSurrogate(ch)) { 
                    unsafeCPSet(t.m_unsafeCP_, ch); 
                } 
            } 
        } 

    if (element.m_cPoints_.length() - element.m_cPointsOffset_ > 1) { 
        // we're adding a contraction
        int cp = UTF16.charAt(element.m_cPoints_, element.m_cPointsOffset_);
        CE = t.m_mapping_.getValue(cp);
        CE = addContraction(t, CE, element);
    } 
    else { 
        // easy case
        CE = t.m_mapping_.getValue(element.m_cPoints_.charAt(
                                 element.m_cPointsOffset_));
        
        if (CE != CE_NOT_FOUND_) {
        if(isContractionTableElement(CE)) { 
            // adding a non contraction element (thai, expansion, 
            // single) to already existing contraction 
            if (!isPrefix(element.m_mapCE_)) { 
            // we cannot reenter prefix elements - as we are going 
            // to create a dead loop
            // Only expansions and regular CEs can go here... 
            // Contractions will never happen in this place
            setContraction(t.m_contractions_, CE, 0, (char)0, 
                       element.m_mapCE_);
            // This loop has to change the CE at the end of 
            // contraction REDO!
            changeLastCE(t.m_contractions_, CE, element.m_mapCE_);
            }
        } 
        else {
            t.m_mapping_.setValue(element.m_cPoints_.charAt(
                                    element.m_cPointsOffset_), 
                      element.m_mapCE_);
            if (element.m_prefixChars_ != null && 
                element.m_prefixChars_.length()>0 &&
                getCETag(CE) != CE_IMPLICIT_TAG_) {
                // Add CE for standalone precontext char. 
                Elements origElem = new Elements();
                origElem.m_prefixChars_ =  null;
                origElem.m_uchars_ = element.m_cPoints_;
                origElem.m_cPoints_ = origElem.m_uchars_;
                origElem.m_CEs_[0] = CE;
                origElem.m_mapCE_ = CE;
                origElem.m_CELength_ = 1;
                finalizeAddition(t, origElem);
            }
        }
        } 
        else {
        t.m_mapping_.setValue(element.m_cPoints_.charAt(
                                element.m_cPointsOffset_), 
                                      element.m_mapCE_);
        }
    }
    return CE;
    }
    
    /** 
     * Note regarding surrogate handling: We are interested only in the single
     * or leading surrogates in a contraction. If a surrogate is somewhere else
     * in the contraction, it is going to be handled as a pair of code units,
     * as it doesn't affect the performance AND handling surrogates specially
     * would complicate code way too much.
     */
    private static int addContraction(BuildTable t, int CE, Elements element) 
    {
    ContractionTable contractions = t.m_contractions_;
    contractions.m_currentTag_ = CE_CONTRACTION_TAG_;
    
    // First we need to check if contractions starts with a surrogate
    int cp = UTF16.charAt(element.m_cPoints_, 0);
    int cpsize = 1;
    if (UCharacter.isSupplementary(cp)) {
        cpsize = 2;
    }
    if (cpsize < element.m_cPoints_.length()) { 
        // This is a real contraction, if there are other characters after 
        // the first
        int size = element.m_cPoints_.length() - element.m_cPointsOffset_;
        for (int j = 1; j < size; j ++) {   
        // First add contraction chars to unsafe CP hash table 
        // Unless it is a trail surrogate, which is handled 
        // algoritmically and shouldn't take up space in the table.
        if (!UTF16.isTrailSurrogate(element.m_cPoints_.charAt(
                                      element.m_cPointsOffset_ + j))) {
            unsafeCPSet(t.m_unsafeCP_, 
                element.m_cPoints_.charAt(
                              element.m_cPointsOffset_ + j));
        }
        }
        // Add the last char of the contraction to the contraction-end 
        // hash table. unless it is a trail surrogate, which is handled 
        // algorithmically and shouldn't be in the table
        if (!UTF16.isTrailSurrogate(element.m_cPoints_.charAt(
                                  element.m_cPoints_.length() -1))) {
        ContrEndCPSet(t.m_contrEndCP_, 
                  element.m_cPoints_.charAt(
                            element.m_cPoints_.length() -1));
        }
    
        // If there are any Jamos in the contraction, we should turn on 
        // special processing for Jamos
        if (isJamo(element.m_cPoints_.charAt(element.m_cPointsOffset_))) {
        t.m_collator_.m_isJamoSpecial_ = true;
        }
        // then we need to deal with it 
        // we could aready have something in table - or we might not 
        element.m_cPointsOffset_ += cpsize;
        if (!isContraction(CE)) { 
        // if it wasn't contraction, we wouldn't end up here
        int firstContractionOffset = addContraction(contractions, 
                                CONTRACTION_TABLE_NEW_ELEMENT_, (char)0, CE);
        int newCE = processContraction(contractions, element, 
                           CE_NOT_FOUND_);
        addContraction(contractions, firstContractionOffset, 
                   element.m_cPoints_.charAt(element.m_cPointsOffset_), 
                   newCE);
        addContraction(contractions, firstContractionOffset, 
                               (char)0xFFFF, CE);
        CE = constructSpecialCE(CE_CONTRACTION_TAG_, 
                    firstContractionOffset);
        } 
        else { 
        // we are adding to existing contraction 
        // there were already some elements in the table, so we need to 
        // add a new contraction
        // Two things can happen here: either the codepoint is already 
        // in the table, or it is not 
        int position = findCP(contractions, CE, 
                      element.m_cPoints_.charAt(element.m_cPointsOffset_));
        if (position > 0) {       
            // if it is we just continue down the chain
            int eCE = getCE(contractions, CE, position);
            int newCE = processContraction(contractions, element, eCE);
            setContraction(contractions, CE, position, 
                   element.m_cPoints_.charAt(element.m_cPointsOffset_), 
                   newCE);
        } 
        else {                  
            // if it isn't, we will have to create a new sequence 
            int newCE = processContraction(contractions, element, 
                           CE_NOT_FOUND_);
            insertContraction(contractions, CE, 
                      element.m_cPoints_.charAt(element.m_cPointsOffset_), 
                                      newCE);
        }
        }
        element.m_cPointsOffset_ -= cpsize;
        t.m_mapping_.setValue(cp, CE);
    } 
    else if (!isContraction(CE)) { 
        // this is just a surrogate, and there is no contraction 
        t.m_mapping_.setValue(cp, element.m_mapCE_);
    } 
    else { 
        // fill out the first stage of the contraction with the surrogate 
        // CE 
        changeContraction(contractions, CE, (char)0, element.m_mapCE_);
        changeContraction(contractions, CE, (char)0xFFFF, element.m_mapCE_);
    }
    return CE;
    }
    
    /** 
     * this is for adding non contractions 
     * @param table contraction table
     * @param element offset to the contraction table
     * @param value collation element value
     * @return new collation element 
     */
    private static final int changeLastCE(ContractionTable table, int element, 
                                          int value) 
    {
    BasicContractionTable tbl = getBasicContractionTable(table, element);
    if (tbl == null) {
        return 0;
    }
    
    tbl.m_CEs_.set(tbl.m_CEs_.size() - 1, new Integer(value));
    return constructSpecialCE(table.m_currentTag_, element & 0xFFFFFF);
    }
    
    /**
     * Given a set of ranges calculated by allocWeights(), iterate through the 
     * weights. Sets the next weight in cegenerator.m_current_.
     * @param cegenerator object that contains ranges weight range array and
     *        its rangeCount
     * @return the next weight
     */
    private static int nextWeight(CEGenerator cegenerator) 
    {
        if (cegenerator.m_rangesLength_ > 0) {
            // get maxByte from the .count field
            int maxByte = cegenerator.m_ranges_[0].m_count_;
            // get the next weight 
            int weight = cegenerator.m_ranges_[0].m_start_;
            if (weight == cegenerator.m_ranges_[0].m_end_) {
                // this range is finished, remove it and move the following 
                // ones up 
                cegenerator.m_rangesLength_ --;
                if (cegenerator.m_rangesLength_ > 0) {
                    System.arraycopy(cegenerator.m_ranges_, 1, 
                                     cegenerator.m_ranges_, 0, 
                                     cegenerator.m_rangesLength_);
                    cegenerator.m_ranges_[0].m_count_ = maxByte; 
                    // keep maxByte in ranges[0]
                }
            } 
            else {
                // increment the weight for the next value
                cegenerator.m_ranges_[0].m_start_ 
            = incWeight(weight, cegenerator.m_ranges_[0].m_length2_, 
                maxByte);
            }
            return weight;
        }
        return -1;
    }
    
    /**
     * Increment the collation weight
     * @param weight to increment
     * @param length
     * @param maxByte
     * @return new incremented weight
     */
    private static final int incWeight(int weight, int length, int maxByte) 
    {
        while (true) {
            int b = getWeightByte(weight, length);
            if (b < maxByte) {
                return setWeightByte(weight, length, b + 1);
            } 
            else {
                // roll over, set this byte to BYTE_FIRST_TAILORED_ and 
                // increment the previous one
                weight = setWeightByte(weight, length, 
                                       RuleBasedCollator.BYTE_FIRST_TAILORED_);
                -- length;
            }
        }
    }
    
    /**
     * Gets the weight byte
     * @param weight
     * @param index
     * @return byte
     */
    private static final int getWeightByte(int weight, int index) 
    {
        return (weight >> ((4 - index) << 3)) & 0xff;
    }
    
    /**
     * Set the weight byte in table
     * @param weight 
     * @param index
     * @param b byte
     */
    private static final int setWeightByte(int weight, int index, int b) 
    {
        index <<= 3;
        // 0xffffffff except a 00 "hole" for the index-th byte
        int mask = 0xffffffff >>> index;
        index = 32 - index;
        mask |= 0xffffff00 << index;
        return (weight & mask) | (b << index);
    }
    
    /**
     * Call getWeightRanges and then determine heuristically which ranges to 
     * use for a given number of weights between (excluding) two limits
     * @param lowerLimit
     * @param upperLimit
     * @param n
     * @param maxByte
     * @param ranges
     * @return
     */
    private int allocateWeights(int lowerLimit, int upperLimit, int n,
                                int maxByte, WeightRange ranges[]) 
    {
        // number of usable byte values 3..maxByte
        int countBytes = maxByte - RuleBasedCollator.BYTE_FIRST_TAILORED_ + 1;
        // [0] unused, [5] to make index checks unnecessary, m_utilCountBuffer_
        // countBytes to the power of index, m_utilLongBuffer_ for unsignedness
        // gcc requires explicit initialization 
        m_utilLongBuffer_[0] = 1;
        m_utilLongBuffer_[1] = countBytes;
        m_utilLongBuffer_[2] = m_utilLongBuffer_[1] * countBytes;
        m_utilLongBuffer_[3] = m_utilLongBuffer_[2] * countBytes;
        m_utilLongBuffer_[4] = m_utilLongBuffer_[3] * countBytes;
        int rangeCount = getWeightRanges(lowerLimit, upperLimit, maxByte, 
                                         countBytes, ranges);
        if (rangeCount <= 0) {
            return 0;
        }
        // what is the maximum number of weights with these ranges?
        long maxCount = 0;
        for (int i = 0; i < rangeCount; ++ i) {
            maxCount += (long)ranges[i].m_count_ 
        * m_utilLongBuffer_[4 - ranges[i].m_length_];
        }
        if (maxCount < n) {
            return 0;
        }
        // set the length2 and count2 fields
        for (int i = 0; i < rangeCount; ++ i) {
            ranges[i].m_length2_ = ranges[i].m_length_;
            ranges[i].m_count2_ = ranges[i].m_count_;
        }
        // try until we find suitably large ranges
        while (true) {
            // get the smallest number of bytes in a range
            int minLength = ranges[0].m_length2_;
            // sum up the number of elements that fit into ranges of each byte 
            // length
            Arrays.fill(m_utilCountBuffer_, 0);
            for (int i = 0; i < rangeCount; ++ i) {
                m_utilCountBuffer_[ranges[i].m_length2_] += ranges[i].m_count2_;
            }
            // now try to allocate n elements in the available short ranges 
            if (n <= m_utilCountBuffer_[minLength] 
        + m_utilCountBuffer_[minLength + 1]) {
                // trivial cases, use the first few ranges
                maxCount = 0;
                rangeCount = 0;
                do {
                    maxCount += ranges[rangeCount].m_count2_;
                    ++ rangeCount;
                } while (n > maxCount);
                break;
            } 
            else if (n <= ranges[0].m_count2_ * countBytes) {
                // easy case, just make this one range large enough by 
                // lengthening it once more, possibly split it
                rangeCount = 1;
                // calculate how to split the range between maxLength-1 
                // (count1) and maxLength (count2) 
                long power_1 
            = m_utilLongBuffer_[minLength - ranges[0].m_length_];
                long power = power_1 * countBytes;
                int count2 = (int)((n + power - 1) / power);
                int count1 = ranges[0].m_count_ - count2;
                // split the range
                if (count1 < 1) {
                    // lengthen the entire range to maxLength 
                    lengthenRange(ranges, 0, maxByte, countBytes);
                } 
                else {
                    // really split the range
                    // create a new range with the end and initial and current 
                    // length of the old one
                    rangeCount = 2;
                    ranges[1].m_end_ = ranges[0].m_end_;
                    ranges[1].m_length_ = ranges[0].m_length_;
                    ranges[1].m_length2_ = minLength;
                    // set the end of the first range according to count1
                    int i = ranges[0].m_length_;
                    int b = getWeightByte(ranges[0].m_start_, i) + count1 - 1;
                    // ranges[0].count and count1 may be >countBytes from 
                    // merging adjacent ranges; b > maxByte is possible
                    if (b <= maxByte) {
                        ranges[0].m_end_ = setWeightByte(ranges[0].m_start_, i, 
                                                         b);
                    } 
                    else {
                        ranges[0].m_end_ = setWeightByte(
                             incWeight(ranges[0].m_start_, i - 1, 
                                   maxByte), 
                             i, b - countBytes);
                    }
                    // set the bytes in the end weight at length + 1..length2 
                    // to maxByte
                    b = (maxByte << 24) | (maxByte << 16) | (maxByte << 8)
                        | maxByte; // this used to be 0xffffffff 
                    ranges[0].m_end_ = truncateWeight(ranges[0].m_end_, i) 
            | (b >>> (i << 3)) 
            & (b << ((4 - minLength) << 3));
                    // set the start of the second range to immediately follow 
                    // the end of the first one
                    ranges[1].m_start_ = incWeight(ranges[0].m_end_, minLength, 
                                                   maxByte);
                    // set the count values (informational)
                    ranges[0].m_count_ = count1;
                    ranges[1].m_count_ = count2;
    
                    ranges[0].m_count2_ = (int)(count1 * power_1);
                    // will be *countBytes when lengthened 
                    ranges[1].m_count2_ = (int)(count2 * power_1); 
    
                    // lengthen the second range to maxLength
                    lengthenRange(ranges, 1, maxByte, countBytes);
                }
                break;
            }
            // no good match, lengthen all minLength ranges and iterate 
            for (int i=0; ranges[i].m_length2_ == minLength; ++ i) {
                lengthenRange(ranges, i, maxByte, countBytes);
            }
        }
    
        if (rangeCount > 1) {
            // sort the ranges by weight values 
            Arrays.sort(ranges, 0, rangeCount);
        }
    
        // set maxByte in ranges[0] for ucol_nextWeight()
        ranges[0].m_count_ = maxByte;
    
        return rangeCount;
    }
    
    /**
     * Updates the range length
     * @param range weight range array
     * @param offset to weight range array
     * @param maxByte
     * @param countBytes
     * @return new length
     */
    private static final int lengthenRange(WeightRange range[], int offset, 
                                           int maxByte, int countBytes) 
    {
        int length = range[offset].m_length2_ + 1;
        range[offset].m_start_ = setWeightTrail(range[offset].m_start_, length, 
                        RuleBasedCollator.BYTE_FIRST_TAILORED_);
        range[offset].m_end_ = setWeightTrail(range[offset].m_end_, length, 
                                              maxByte);
        range[offset].m_count2_ *= countBytes;
        range[offset].m_length2_ = length;
        return length;
    }
    
    /**
     * Gets the weight 
     * @param weight
     * @param length
     * @param trail
     * @return new weight
     */
    private static final int setWeightTrail(int weight, int length, int trail) 
    {
        length = (4 - length) << 3;
        return (weight & (0xffffff00 << length)) | (trail << length);
    }
    
    /**
     * take two CE weights and calculate the
     * possible ranges of weights between the two limits, excluding them
     * for weights with up to 4 bytes there are up to 2*4-1=7 ranges
     * @param lowerLimit
     * @param upperLimit
     * @param maxByte
     * @param countBytes
     * @param ranges
     * @return weight ranges
     */
    private int getWeightRanges(int lowerLimit, int upperLimit, int maxByte, 
                                int countBytes, WeightRange ranges[]) 
    {
        // assume that both lowerLimit & upperLimit are not 0 
        // get the lengths of the limits 
        int lowerLength = lengthOfWeight(lowerLimit);
        int upperLength = lengthOfWeight(upperLimit);
        if (Utility.compareUnsigned(lowerLimit, upperLimit) >= 0) {
            return 0;
        }
        // check that neither is a prefix of the other
        if (lowerLength < upperLength) {
            if (lowerLimit == truncateWeight(upperLimit, lowerLength)) {
                return 0;
            }
        }
        // if the upper limit is a prefix of the lower limit then the earlier 
        // test lowerLimit >= upperLimit has caught it
        // reset local variables
        // With the limit lengths of 1..4, there are up to 7 ranges for 
        // allocation:
        // range     minimum length
        // lower[4]  4
        // lower[3]  3
        // lower[2]  2
        // middle    1
        // upper[2]  2
        // upper[3]  3
        // upper[4]  4
        // We are now going to calculate up to 7 ranges.
        // Some of them will typically overlap, so we will then have to merge 
        // and eliminate ranges.
        
        // We have to clean cruft from previous invocations
        // before doing anything. C++ already does that
        for(int length = 0; length < 5; length++) {
            m_utilLowerWeightRange_[length].clear();
            m_utilUpperWeightRange_[length].clear();
        }
        m_utilWeightRange_.clear();
        
        int weight = lowerLimit;
        for (int length = lowerLength; length >= 2; -- length) {
            m_utilLowerWeightRange_[length].clear();
            int trail = getWeightByte(weight, length);
            if (trail < maxByte) {
                m_utilLowerWeightRange_[length].m_start_ 
            = incWeightTrail(weight, length);
                m_utilLowerWeightRange_[length].m_end_ 
            = setWeightTrail(weight, length, maxByte);
                m_utilLowerWeightRange_[length].m_length_ = length;
                m_utilLowerWeightRange_[length].m_count_ = maxByte - trail;
            }
            weight = truncateWeight(weight, length - 1);
        }
        m_utilWeightRange_.m_start_ = incWeightTrail(weight, 1);
    
        weight = upperLimit;
        // [0] and [1] are not used - this simplifies indexing, 
        // m_utilUpperWeightRange_
        
        for (int length = upperLength; length >= 2; length --) {
            int trail = getWeightByte(weight, length);
            if (trail > RuleBasedCollator.BYTE_FIRST_TAILORED_) {
                m_utilUpperWeightRange_[length].m_start_ 
            = setWeightTrail(weight, length, 
                     RuleBasedCollator.BYTE_FIRST_TAILORED_);
                m_utilUpperWeightRange_[length].m_end_ 
            = decWeightTrail(weight, length);
                m_utilUpperWeightRange_[length].m_length_ = length;
                m_utilUpperWeightRange_[length].m_count_ = trail
            - RuleBasedCollator.BYTE_FIRST_TAILORED_;
            }
            weight = truncateWeight(weight, length - 1);
        }
        m_utilWeightRange_.m_end_ = decWeightTrail(weight, 1);
    
        // set the middle range
        m_utilWeightRange_.m_length_ = 1;
        if (Utility.compareUnsigned(m_utilWeightRange_.m_end_, m_utilWeightRange_.m_start_) >= 0) {
        //if (m_utilWeightRange_.m_end_ >= m_utilWeightRange_.m_start_) {
            m_utilWeightRange_.m_count_ 
        = ((m_utilWeightRange_.m_end_ - m_utilWeightRange_.m_start_) 
           >>> 24) + 1;
        } 
        else {
            // eliminate overlaps
            // remove the middle range
            m_utilWeightRange_.m_count_ = 0;
            // reduce or remove the lower ranges that go beyond upperLimit
            for (int length = 4; length >= 2; -- length) {
                if (m_utilLowerWeightRange_[length].m_count_ > 0 
                    && m_utilUpperWeightRange_[length].m_count_ > 0) {
                    int start = m_utilUpperWeightRange_[length].m_start_;
                    int end = m_utilLowerWeightRange_[length].m_end_;
                    if (end >= start || incWeight(end, length, maxByte) 
            == start) {
                        // lower and upper ranges collide or are directly 
                        // adjacent: merge these two and remove all shorter 
                        // ranges
                        start = m_utilLowerWeightRange_[length].m_start_;
                        end = m_utilLowerWeightRange_[length].m_end_ 
                            = m_utilUpperWeightRange_[length].m_end_;
                        // merging directly adjacent ranges needs to subtract 
                        // the 0/1 gaps in between;
                        // it may result in a range with count>countBytes
                        m_utilLowerWeightRange_[length].m_count_ 
                = getWeightByte(end, length)
                - getWeightByte(start, length) + 1 
                + countBytes * (getWeightByte(end, length - 1)
                        - getWeightByte(start, 
                                length - 1));
                        m_utilUpperWeightRange_[length].m_count_ = 0;
                        while (-- length >= 2) {
                            m_utilLowerWeightRange_[length].m_count_ 
                                = m_utilUpperWeightRange_[length].m_count_ = 0;
                        }
                        break;
                    }
                }
            }
        }
    
        // copy the ranges, shortest first, into the result array 
        int rangeCount = 0;
        if (m_utilWeightRange_.m_count_ > 0) {
            ranges[0] = new WeightRange(m_utilWeightRange_);
            rangeCount = 1;
        }
        for (int length = 2; length <= 4; ++ length) {
            // copy upper first so that later the middle range is more likely 
            // the first one to use
            if (m_utilUpperWeightRange_[length].m_count_ > 0) {
                ranges[rangeCount] 
            = new WeightRange(m_utilUpperWeightRange_[length]);
                ++ rangeCount;
            }
            if (m_utilLowerWeightRange_[length].m_count_ > 0) {
                ranges[rangeCount] 
            = new WeightRange(m_utilLowerWeightRange_[length]);
                ++ rangeCount;
            }
        }
        return rangeCount;
    }
    
    /**
     * Truncates the weight with length
     * @param weight
     * @param length
     * @return truncated weight
     */
    private static final int truncateWeight(int weight, int length) 
    {
        return weight & (0xffffffff << ((4 - length) << 3));
    }
    
    /**
     * Length of the weight
     * @param weight
     * @return length of the weight
     */
    private static final int lengthOfWeight(int weight) 
    {
        if ((weight & 0xffffff) == 0) {
            return 1;
        } 
        else if ((weight & 0xffff) == 0) {
            return 2;
        } 
        else if ((weight & 0xff) == 0) {
            return 3;
        } 
        return 4;
    }
    
    /**
     * Increment the weight trail
     * @param weight 
     * @param length
     * @return new weight
     */
    private static final int incWeightTrail(int weight, int length) 
    {
        return weight + (1 << ((4-length) << 3));
    }

    /**
     * Decrement the weight trail
     * @param weight 
     * @param length
     * @return new weight
     */
    private static int decWeightTrail(int weight, int length) 
    {
        return weight - (1 << ((4 - length) << 3));
    }
    
    /**
     * Gets the codepoint 
     * @param tbl contraction table
     * @param codePoint code point to look for
     * @return the offset to the code point
     */
    private static int findCP(BasicContractionTable tbl, char codePoint) 
    {
        int position = 0;
        while (codePoint > tbl.m_codePoints_.charAt(position)) {
            position ++;
            if (position > tbl.m_codePoints_.length()) {
                return -1;
            }
        }
        if (codePoint == tbl.m_codePoints_.charAt(position)) {
            return position;
        } 
        else {
            return -1;
        }
    }

    /**
     * Finds a contraction ce
     * @param table
     * @param element
     * @param ch
     * @return ce
     */
    private static int findCE(ContractionTable table, int element, char ch) 
    {
        if (table == null) {
            return CE_NOT_FOUND_;
        }
        BasicContractionTable tbl = getBasicContractionTable(table, element);
        if (tbl == null) {
            return CE_NOT_FOUND_;
        }
        int position = findCP(tbl, ch);
        if (position > tbl.m_CEs_.size() || position < 0) {
            return CE_NOT_FOUND_;
        } 
        return ((Integer)tbl.m_CEs_.get(position)).intValue();
    }    
    
    /**
     * Checks if the string is tailored in the contraction
     * @param table contraction table
     * @param element 
     * @param array character array to check
     * @param offset array offset
     * @return true if it is tailored
     */
    private static boolean isTailored(ContractionTable table, int element, 
                                      char array[], int offset) 
    {
        while (array[offset] != 0) {
            element = findCE(table, element, array[offset]);
            if (element == CE_NOT_FOUND_) {
                return false;
            }
            if (!isContractionTableElement(element)) {
                return true;
            }
            offset ++;
        }
        if (getCE(table, element, 0) != CE_NOT_FOUND_) {
            return true;
        } 
        else {
            return false; 
        }
    }
    
    /**
     * Assemble RuleBasedCollator
     * @param t build table
     * @param collator to update
     */
    private void assembleTable(BuildTable t, RuleBasedCollator collator) 
    {
        IntTrieBuilder mapping = t.m_mapping_;
        Vector expansions = t.m_expansions_;
        ContractionTable contractions = t.m_contractions_;
        MaxExpansionTable maxexpansion = t.m_maxExpansions_;
        
        // contraction offset has to be in since we are building on the 
        // UCA contractions 
        // int beforeContractions = (HEADER_SIZE_ 
        //                         + paddedsize(expansions.size() << 2)) >>> 1;
        collator.m_contractionOffset_ = 0;
        int contractionsSize = constructTable(contractions);
        
        // the following operation depends on the trie data. Therefore, we have 
        // to do it before the trie is compacted 
        // sets jamo expansions
        getMaxExpansionJamo(mapping, maxexpansion, t.m_maxJamoExpansions_,
                            collator.m_isJamoSpecial_);
        
        // TODO: LATIN1 array is now in the utrie - it should be removed from 
        // the calculation
        setAttributes(collator, t.m_options_);
        // copy expansions
        int size = expansions.size();
        collator.m_expansion_ = new int[size];
        for (int i = 0; i < size; i ++) {
            collator.m_expansion_[i] = ((Integer)expansions.get(i)).intValue();
        }
        // contractions block 
        if (contractionsSize != 0) {
            // copy contraction index 
            collator.m_contractionIndex_ = new char[contractionsSize];
            contractions.m_codePoints_.getChars(0, contractionsSize, 
                                                collator.m_contractionIndex_, 
                                                0);
            // copy contraction collation elements
            collator.m_contractionCE_ = new int[contractionsSize];
            for (int i = 0; i < contractionsSize; i ++) {
                collator.m_contractionCE_[i] = ((Integer)
                        contractions.m_CEs_.get(i)).intValue();
            }
        }
        // copy mapping table
        collator.m_trie_ = mapping.serialize(t, 
                         RuleBasedCollator.DataManipulate.getInstance());
        // copy max expansion table
        // not copying the first element which is a dummy
        // to be in synch with icu4c's builder, we continue to use the 
        // expansion offset
        // omitting expansion offset in builder
        collator.m_expansionOffset_ = 0; 
        size = maxexpansion.m_endExpansionCE_.size();
        collator.m_expansionEndCE_ = new int[size - 1];
        for (int i = 1; i < size; i ++) {
            collator.m_expansionEndCE_[i - 1] = ((Integer)
                         maxexpansion.m_endExpansionCE_.get(i)).intValue();
        }
        collator.m_expansionEndCEMaxSize_ = new byte[size - 1];
        for (int i = 1; i < size; i ++) {
            collator.m_expansionEndCEMaxSize_[i - 1] 
        = ((Byte)maxexpansion.m_expansionCESize_.get(i)).byteValue();
        }
        // Unsafe chars table.  Finish it off, then copy it.
        unsafeCPAddCCNZ(t);
        // Or in unsafebits from UCA, making a combined table.
        for (int i = 0; i < UNSAFECP_TABLE_SIZE_; i ++) {    
        t.m_unsafeCP_[i] |= RuleBasedCollator.UCA_.m_unsafe_[i];
        }
        collator.m_unsafe_ = t.m_unsafeCP_;
    
        // Finish building Contraction Ending chars hash table and then copy it 
        // out.
        // Or in unsafebits from UCA, making a combined table
        for (int i = 0; i < UNSAFECP_TABLE_SIZE_; i ++) {    
        t.m_contrEndCP_[i] |= RuleBasedCollator.UCA_.m_contractionEnd_[i];
        }
        collator.m_contractionEnd_ = t.m_contrEndCP_;
    }
    
    /**
     * Sets this collator to use the all options and tables in UCA. 
     * @param collator which attribute is to be set 
     * @param option to set with
     */
    private static final void setAttributes(RuleBasedCollator collator,
                        CollationRuleParser.OptionSet option)
    {
        collator.latinOneFailed_ = true;
        collator.m_caseFirst_ = option.m_caseFirst_;
        collator.setDecomposition(option.m_decomposition_);
        collator.setAlternateHandlingShifted(
                         option.m_isAlternateHandlingShifted_);
        collator.setCaseLevel(option.m_isCaseLevel_);
        collator.setFrenchCollation(option.m_isFrenchCollation_);
        collator.m_isHiragana4_ = option.m_isHiragana4_;
        collator.setStrength(option.m_strength_);
        collator.m_variableTopValue_ = option.m_variableTopValue_;    
        collator.latinOneFailed_ = false;
    }
    
    /**
     * Constructing the contraction table
     * @param table contraction table
     * @return 
     */
    private int constructTable(ContractionTable table) 
    {
        // See how much memory we need 
        int tsize = table.m_elements_.size();
        if (tsize == 0) {
            return 0;
        }
        table.m_offsets_.clear();
        int position = 0;
        for (int i = 0; i < tsize; i ++) {
            table.m_offsets_.add(new Integer(position));
            position += ((BasicContractionTable)
             table.m_elements_.get(i)).m_CEs_.size();
        }
        table.m_CEs_.clear();
        table.m_codePoints_.delete(0, table.m_codePoints_.length());
        // Now stuff the things in
        StringBuffer cpPointer = table.m_codePoints_;
        Vector CEPointer = table.m_CEs_;
        for (int i = 0; i < tsize; i ++) {
            BasicContractionTable bct = (BasicContractionTable)
        table.m_elements_.get(i);
            int size = bct.m_CEs_.size();
            char ccMax = 0;
            char ccMin = 255;
            int offset = CEPointer.size();
            CEPointer.add(bct.m_CEs_.get(0));
            for (int j = 1; j < size; j ++) {
                char ch = bct.m_codePoints_.charAt(j);
                char cc = (char)(UCharacter.getCombiningClass(ch) & 0xFF);
                if (cc > ccMax) {
                    ccMax = cc;
                }
                if (cc < ccMin) {
                    ccMin = cc;
                }
                cpPointer.append(ch);
                CEPointer.add(bct.m_CEs_.get(j));
            }
            cpPointer.insert(offset, 
                             (char)(((ccMin == ccMax) ? 1 : 0 << 8) | ccMax));
            for (int j = 0; j < size; j ++) {
                if (isContractionTableElement(((Integer)
                           CEPointer.get(offset + j)).intValue())) {
                    int ce = ((Integer)CEPointer.get(offset + j)).intValue();
                    CEPointer.set(offset + j, 
                  new Integer(constructSpecialCE(getCETag(ce), 
                                 ((Integer)table.m_offsets_.get(
                                                getContractionOffset(ce))).intValue())));
                }
            }
        }
    
        for (int i = 0; i <= 0x10FFFF; i ++) {
            int CE = table.m_mapping_.getValue(i);
            if (isContractionTableElement(CE)) {
                CE = constructSpecialCE(getCETag(CE), 
                                        ((Integer)table.m_offsets_.get(
                                       getContractionOffset(CE))).intValue());
                table.m_mapping_.setValue(i, CE);
            }
        }
        return position;
    }
    
    /**
     * Get contraction offset
     * @param ce collation element 
     * @return contraction offset
     */
    private static final int getContractionOffset(int ce)
    {
        return ce & 0xFFFFFF;
    }
    
    /**
     * Gets the maximum Jamo expansion
     * @param mapping trie table
     * @param maxexpansion maximum expansion table
     * @param maxjamoexpansion maximum jamo expansion table
     * @param jamospecial is jamo special?
     */
    private static void getMaxExpansionJamo(IntTrieBuilder mapping, 
                                            MaxExpansionTable maxexpansion,
                                            MaxJamoExpansionTable 
                        maxjamoexpansion,
                                            boolean jamospecial)
    {
        int VBASE  = 0x1161;
        int TBASE  = 0x11A8;
        int VCOUNT = 21;
        int TCOUNT = 28;
        int v = VBASE + VCOUNT - 1;
        int t = TBASE + TCOUNT - 1;
        
        while (v >= VBASE) {
            int ce = mapping.getValue(v);
            if ((ce & RuleBasedCollator.CE_SPECIAL_FLAG_) 
        != RuleBasedCollator.CE_SPECIAL_FLAG_) {
                setMaxExpansion(ce, (byte)2, maxexpansion);
            }
            v --;
        }
        
        while (t >= TBASE)
        {
        int ce = mapping.getValue(t);
        if ((ce & RuleBasedCollator.CE_SPECIAL_FLAG_) 
            != RuleBasedCollator.CE_SPECIAL_FLAG_) {
            setMaxExpansion(ce, (byte)3, maxexpansion);
        }
        t --;
        }
        // According to the docs, 99% of the time, the Jamo will not be special 
        if (jamospecial) {
            // gets the max expansion in all unicode characters
            int count = maxjamoexpansion.m_endExpansionCE_.size();
            byte maxTSize = (byte)(maxjamoexpansion.m_maxLSize_ + 
                                   maxjamoexpansion.m_maxVSize_ +
                                   maxjamoexpansion.m_maxTSize_);
            byte maxVSize = (byte)(maxjamoexpansion.m_maxLSize_ + 
                                   maxjamoexpansion.m_maxVSize_);
        
            while (count > 0) {
                count --;
                if (((Boolean)maxjamoexpansion.m_isV_.get(count)).booleanValue()
            == true) {
                    setMaxExpansion(((Integer)
                     maxjamoexpansion.m_endExpansionCE_.get(count)).intValue(), 
                    maxVSize, maxexpansion);
                }
                else {
                    setMaxExpansion(((Integer)
                     maxjamoexpansion.m_endExpansionCE_.get(count)).intValue(), 
                    maxTSize, maxexpansion);
                }
            }
        }
    }
    
    /**  
     * To the UnsafeCP hash table, add all chars with combining class != 0     
     * @param t build table
     */
    private static final void unsafeCPAddCCNZ(BuildTable t) 
    {
        boolean buildCMTable = ( buildCMTabFlag & (t.cmLookup==null) );
        char[]  cm = null;  // combining mark array
        int[]   index= new int[256];
        int     count=0;

        if (buildCMTable) {
            cm = new char[0x10000];
        }
        for (char c = 0; c < 0xffff; c ++) {
            char fcd = NormalizerImpl.getFCD16(c);
            if (fcd >= 0x100 || // if the leading combining class(c) > 0 ||
                (UTF16.isLeadSurrogate(c) && fcd != 0)) {
                // c is a leading surrogate with some FCD data
                unsafeCPSet(t.m_unsafeCP_, c);
                if ( buildCMTable && (fcd!=0)) {
                    int cc = (fcd& 0xff);
                    int pos = (cc<<8)+index[cc];
                    cm[pos] = c;
                    index[cc]++;
                    count++;
                }
            }
        }
    
        if (t.m_prefixLookup_ != null) {
            Enumeration els = t.m_prefixLookup_.elements();
            while (els.hasMoreElements()) {
                Elements e = (Elements)els.nextElement();
                // codepoints here are in the NFD form. We need to add the
                // first code point of the NFC form to unsafe, because 
                // strcoll needs to backup over them.
                // weiv: This is wrong! See the comment above.
                //String decomp = Normalizer.decompose(e.m_cPoints_, true);
                //unsafeCPSet(t.m_unsafeCP_, decomp.charAt(0));
                // it should be:
                String comp = Normalizer.compose(e.m_cPoints_, false);
                unsafeCPSet(t.m_unsafeCP_, comp.charAt(0));
            } 
        }
        
        if (buildCMTable) {
            t.cmLookup = new CombinClassTable();
            t.cmLookup.generate(cm, count, index);
        }
    }
    
    /**
     * Create closure
     * @param t build table
     * @param collator RuleBasedCollator
     * @param colEl collation element iterator
     * @param start 
     * @param limit
     * @param type character type
     * @return 
     */
    private boolean enumCategoryRangeClosureCategory(BuildTable t, 
                             RuleBasedCollator collator, 
                             CollationElementIterator colEl, 
                             int start, int limit, int type) 
    {
        if (type != UCharacterCategory.UNASSIGNED 
            && type != UCharacterCategory.PRIVATE_USE) { 
            // if the range is assigned - we might ommit more categories later
            
            for (int u32 = start; u32 < limit; u32 ++) {
                int noOfDec = NormalizerImpl.getDecomposition(u32, false,
                                                              m_utilCharBuffer_, 
                                                              0, 256);
                if (noOfDec > 0) {
                    // if we're positive, that means there is no decomposition
                    String comp = UCharacter.toString(u32);
                    String decomp = new String(m_utilCharBuffer_, 0, noOfDec);
                    if (!collator.equals(comp, decomp)) {
                        m_utilElement_.m_cPoints_ = decomp;
                        m_utilElement_.m_prefix_ = 0;
                        Elements prefix 
                = (Elements)t.m_prefixLookup_.get(m_utilElement_);
                        if (prefix == null) {
                            m_utilElement_.m_cPoints_ = comp;
                            m_utilElement_.m_prefix_ = 0;
                            m_utilElement_.m_prefixChars_ = null;
                            colEl.setText(decomp);
                            int ce = colEl.next();
                            m_utilElement_.m_CELength_ = 0;
                            while (ce != CollationElementIterator.NULLORDER) {
                                m_utilElement_.m_CEs_[
                              m_utilElement_.m_CELength_ ++] 
                    = ce;
                                ce = colEl.next();
                            }
                        } 
                        else {
                            m_utilElement_.m_cPoints_ = comp;
                            m_utilElement_.m_prefix_ = 0;
                            m_utilElement_.m_prefixChars_ = null;
                            m_utilElement_.m_CELength_ = 1;
                            m_utilElement_.m_CEs_[0] = prefix.m_mapCE_;
                            // This character uses a prefix. We have to add it 
                            // to the unsafe table, as it decomposed form is 
                            // already in. In Japanese, this happens for \u309e 
                            // & \u30fe
                            // Since unsafeCPSet is static in ucol_elm, we are 
                            // going to wrap it up in the unsafeCPAddCCNZ 
                            // function
                        }
                        addAnElement(t, m_utilElement_);
                    }
                }
            }
        }
        return true;
    }
    
    /**
     * Determine if a character is a Jamo
     * @param ch character to test
     * @return true if ch is a Jamo, false otherwise
     */
    private static final boolean isJamo(char ch)
    { 
    return (ch >= 0x1100 && ch <= 0x1112) 
        || (ch >= 0x1175 && ch <= 0x1161) 
        || (ch >= 0x11A8 && ch <= 0x11C2);
    }
    
    /**
     * Produces canonical closure
     */
    private void canonicalClosure(BuildTable t) 
    {
        BuildTable temp = new BuildTable(t);
        assembleTable(temp, temp.m_collator_);
        // produce canonical closure 
        CollationElementIterator coleiter 
        = temp.m_collator_.getCollationElementIterator("");
        RangeValueIterator typeiter = UCharacter.getTypeIterator();
        RangeValueIterator.Element element = new RangeValueIterator.Element();
        while (typeiter.next(element)) {
            enumCategoryRangeClosureCategory(t, temp.m_collator_, coleiter, 
                         element.start, element.limit, 
                         element.value);
        }
        
        t.cmLookup = temp.cmLookup;
        temp.cmLookup = null;
        
        for (int i = 0; i < m_parser_.m_resultLength_; i ++) {
            char baseChar, firstCM;
            // now we need to generate the CEs 
            // We stuff the initial value in the buffers, and increase the 
            // appropriate buffer according to strength                                                          */
            // createElements(t, m_parser_.m_listHeader_[i]);
            CollationRuleParser.Token tok = m_parser_.m_listHeader_[i].m_first_;
            m_utilElement_.clear();
            while ( tok!=null ) {
                m_utilElement_.m_prefix_ = 0;// el.m_prefixChars_;
                m_utilElement_.m_cPointsOffset_ = 0; //el.m_uchars_;
                if (tok.m_prefix_ != 0) { 
                // we will just copy the prefix here, and adjust accordingly in 
                // the addPrefix function in ucol_elm. The reason is that we 
                // need to add both composed AND decomposed elements to the 
                // unsafe table.
                int size = tok.m_prefix_ >> 24;
                int offset = tok.m_prefix_ & 0x00FFFFFF;
                m_utilElement_.m_prefixChars_ 
                    = m_parser_.m_source_.substring(offset, offset + size);
                size = (tok.m_source_ >> 24) - (tok.m_prefix_ >> 24); 
                offset = (tok.m_source_ & 0x00FFFFFF) + (tok.m_prefix_ >> 24);
                m_utilElement_.m_uchars_ 
                    = m_parser_.m_source_.substring(offset, offset + size);
                } 
                else {
                m_utilElement_.m_prefixChars_ = null;
                int offset = tok.m_source_ & 0x00FFFFFF;
                int size = tok.m_source_ >>> 24;
                m_utilElement_.m_uchars_ = m_parser_.m_source_.substring(offset, 
                                             offset + size);
                }
                m_utilElement_.m_cPoints_ = m_utilElement_.m_uchars_;
                
                baseChar = firstCM = 0;  //reset
                for (int j = 0; j < m_utilElement_.m_cPoints_.length() 
                     - m_utilElement_.m_cPointsOffset_; j ++) {

                    char fcd = NormalizerImpl.getFCD16(m_utilElement_.m_cPoints_.charAt(j));
                    if ( (fcd & 0xff) == 0 ) {
                        baseChar = m_utilElement_.m_cPoints_.charAt(j);
                    }
                    else {
                        if ( (baseChar!=0) && (firstCM==0) ) {
                            firstCM = m_utilElement_.m_cPoints_.charAt(j); // first combining mark
                        }
                    }
                }
                
                if ( (baseChar!=0) && (firstCM!=0)) {
                      addTailCanonicalClosures(t, temp.m_collator_, coleiter, baseChar, firstCM);
                }
                tok = tok.m_next_;
            }
        }
    }
    
    private void addTailCanonicalClosures(BuildTable t,
            RuleBasedCollator m_collator, 
            CollationElementIterator colEl,
            char baseChar, 
            char cMark) {
        if ( t.cmLookup == null ) {
            return;
        }
        CombinClassTable cmLookup = t.cmLookup;  
        int[] index = cmLookup.index;
        int cClass =  NormalizerImpl.getFCD16(cMark) & 0xff;
        int maxIndex=0;
        char[] precompCh = new char[256];  
        int[] precompClass = new int[256];
        int precompLen=0;
        Elements element = new Elements();
        
        if ( cClass>0 ) {
            maxIndex = index[cClass-1];
        }
        for (int i=0; i<maxIndex; i++) {
            StringBuffer decompBuf = new StringBuffer();
            decompBuf.append(baseChar).append(cmLookup.cPoints[i]);
            String comp = Normalizer.compose(decompBuf.toString(), false);
            if ( comp.length() == 1 ) {
                precompCh[precompLen] = comp.charAt(0);
                precompClass[precompLen] = 
                    (NormalizerImpl.getFCD16(cmLookup.cPoints[i]) & 0xff);
                precompLen++;
                StringBuffer decomp = new StringBuffer();
                for (int j=0; j < m_utilElement_.m_cPoints_.length(); j++) {
                    if ( m_utilElement_.m_cPoints_.charAt(j) == cMark ) {
                        decomp.append(cmLookup.cPoints[i]);
                    }
                    else {
                        decomp.append(m_utilElement_.m_cPoints_.charAt(j));
                    }
                }
                comp = Normalizer.compose(decomp.toString(), false);
                StringBuffer buf= new StringBuffer(comp);
                buf.append(cMark);
                decomp.append(cMark);
                comp = buf.toString();
                
                element.m_cPoints_ = decomp.toString();
                element.m_CELength_ = 0;
                element.m_prefix_ = 0;
                Elements prefix = (Elements)t.m_prefixLookup_.get(element);
                element.m_cPoints_ = comp;
                element.m_uchars_ = comp;
                
                if (prefix == null) {
                    element.m_prefix_ = 0;
                    element.m_prefixChars_ = null;
                    colEl.setText(decomp.toString());
                    int ce = colEl.next();
                    element.m_CELength_ = 0;
                    while (ce != CollationElementIterator.NULLORDER) {
                        element.m_CEs_[element.m_CELength_ ++] = ce;
                        ce = colEl.next();
                    }
                } 
                else {
                    element.m_cPoints_ = comp;
                    element.m_prefix_ = 0;
                    element.m_prefixChars_ = null;
                    element.m_CELength_ = 1;
                    element.m_CEs_[0] = prefix.m_mapCE_;
                }
                setMapCE(t, element);
                finalizeAddition(t, element);
                
                if (comp.length()>2) {
                    // This is a fix for tailoring contractions with accented
                    // character at the end of contraction string.
                    addFCD4AccentedContractions(t, colEl, comp, element);
                }
                if ( precompLen > 1 ) {
                    precompLen = addMultiCMontractions(t, colEl, element, precompCh, 
                                 precompClass, precompLen, cMark, i, decomp.toString());
                }
            }
        }
        
    }
    
    private void setMapCE(BuildTable t, Elements element) {
        Vector expansions = t.m_expansions_;
        element.m_mapCE_ = 0;
        
        if (element.m_CELength_ == 2 // a two CE expansion 
        && RuleBasedCollator.isContinuation(element.m_CEs_[1]) 
        && (element.m_CEs_[1] 
            & (~(0xFF << 24 | RuleBasedCollator.CE_CONTINUATION_MARKER_))) == 0 // that has only primaries in continuation
        && (((element.m_CEs_[0] >> 8) & 0xFF) == RuleBasedCollator.BYTE_COMMON_) 
        // a common secondary
        && ((element.m_CEs_[0] & 0xFF) == RuleBasedCollator.BYTE_COMMON_)) { // and a common tertiary
        
            element.m_mapCE_ = RuleBasedCollator.CE_SPECIAL_FLAG_ 
                // a long primary special
                | (CE_LONG_PRIMARY_TAG_ << 24) 
                // first and second byte of primary
                | ((element.m_CEs_[0] >> 8) & 0xFFFF00) 
                // third byte of primary
                | ((element.m_CEs_[1] >> 24) & 0xFF);   
        } 
        else {
                // omitting expansion offset in builder
                // (HEADER_SIZE_ >> 2)
            int expansion = RuleBasedCollator.CE_SPECIAL_FLAG_ 
                | (CE_EXPANSION_TAG_ << RuleBasedCollator.CE_TAG_SHIFT_) 
                | (addExpansion(expansions, element.m_CEs_[0]) << 4) & 0xFFFFF0;
    
            for (int i = 1; i < element.m_CELength_; i ++) {
                addExpansion(expansions, element.m_CEs_[i]);
            }
            if (element.m_CELength_ <= 0xF) {
                expansion |= element.m_CELength_;
            } 
            else {
                addExpansion(expansions, 0);
            }
            element.m_mapCE_ = expansion;
            setMaxExpansion(element.m_CEs_[element.m_CELength_ - 1],
                    (byte)element.m_CELength_, t.m_maxExpansions_);
        }
    }
    
    private int addMultiCMontractions(BuildTable t,
            CollationElementIterator colEl,
            Elements element,
            char[] precompCh,
            int[] precompClass,
            int maxComp,
            char cMark,
            int cmPos,
            String decomp) {
        
        CombinClassTable cmLookup = t.cmLookup;
        char[] combiningMarks = {cMark};
        int cMarkClass = (int)(UCharacter.getCombiningClass(cMark) & 0xFF);
        String comMark = new String(combiningMarks);
        int  noOfPrecomposedChs = maxComp; 
        
        for (int j=0; j<maxComp; j++) {
            int count = 0;
            StringBuffer temp;
           
            do {
                String newDecomp, comp;
                
                if ( count==0 ) { // Decompose the saved precomposed char.
                    newDecomp = Normalizer.decompose( new String(precompCh, j ,1), false);
                    temp = new StringBuffer(newDecomp);
                    temp.append(cmLookup.cPoints[cmPos]);
                    newDecomp = temp.toString();
                }
                else {
                    temp = new StringBuffer(decomp);
                    temp.append(precompCh[j]);
                    newDecomp = temp.toString();
                }
                comp = Normalizer.compose(newDecomp, false);
                if (comp.length()==1) {
                    temp.append(cMark);
                    element.m_cPoints_ = temp.toString();
                    element.m_CELength_ = 0;
                    element.m_prefix_ = 0;
                    Elements prefix = (Elements)t.m_prefixLookup_.get(element);
                    element.m_cPoints_ = comp+comMark;
                    if (prefix == null) {
                        element.m_prefix_ = 0;
                        element.m_prefixChars_ = null;
                        colEl.setText(temp.toString());
                        int ce = colEl.next();
                        element.m_CELength_ = 0;
                        while (ce != CollationElementIterator.NULLORDER) {
                            element.m_CEs_[element.m_CELength_ ++] = ce;
                            ce = colEl.next();
                        }
                    } 
                    else {
                        element.m_cPoints_ = comp;
                        element.m_prefix_ = 0;
                        element.m_prefixChars_ = null;
                        element.m_CELength_ = 1;
                        element.m_CEs_[0] = prefix.m_mapCE_;
                    }
                    setMapCE(t, element);
                    finalizeAddition(t, element);
                    precompCh[noOfPrecomposedChs] = comp.charAt(0);
                    precompClass[noOfPrecomposedChs] = cMarkClass;  
                    noOfPrecomposedChs++;
                }
            }while(++count<2 && (precompClass[j]==cMarkClass)); 
        }
        return noOfPrecomposedChs;
    }

    private void addFCD4AccentedContractions(BuildTable t, 
            CollationElementIterator colEl,
            String data,
            Elements element) {
        String decomp = Normalizer.decompose(data, false);
        String comp = Normalizer.compose(data, false);
        
        element.m_cPoints_ = decomp;
        element.m_CELength_ = 0;
        element.m_prefix_ = 0;
        Elements prefix = (Elements)t.m_prefixLookup_.get(element);
        if (prefix == null) {
            element.m_cPoints_ = comp;
            element.m_prefix_ = 0;
            element.m_prefixChars_ = null;
            element.m_CELength_ = 0;
            colEl.setText(decomp);
            int ce = colEl.next();
            element.m_CELength_ = 0;
            while (ce != CollationElementIterator.NULLORDER) {
                element.m_CEs_[element.m_CELength_ ++] = ce;
                ce = colEl.next();
            }
            addAnElement(t, element);
        } 
    }
    
    private void processUCACompleteIgnorables(BuildTable t) 
    {
        TrieIterator trieiterator 
        = new TrieIterator(RuleBasedCollator.UCA_.m_trie_);
        RangeValueIterator.Element element = new RangeValueIterator.Element();
        while (trieiterator.next(element)) {
            int start = element.start;
            int limit = element.limit;
            if (element.value == 0) {
                while (start < limit) {
                    int CE = t.m_mapping_.getValue(start);
                    if (CE == CE_NOT_FOUND_) {
                        m_utilElement_.m_prefix_ = 0;
                        m_utilElement_.m_uchars_ = UCharacter.toString(start);
                        m_utilElement_.m_cPoints_ = m_utilElement_.m_uchars_;
                        m_utilElement_.m_cPointsOffset_ = 0;
                        m_utilElement_.m_CELength_ = 1;
                        m_utilElement_.m_CEs_[0] = 0;
                        addAnElement(t, m_utilElement_);
                    }
                    start ++;
                }
            }
        }
    }
}
