/**
*******************************************************************************
* Copyright (C) 1996-2002, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/CollationParsedRuleBuilder.java,v $ 
* $Date: 2002/07/12 21:59:22 $ 
* $Revision: 1.2 $
*
*******************************************************************************
*/
package com.ibm.icu.text;
 
import java.io.InputStream;
import java.io.BufferedInputStream;
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.lang.UCharacter;
import com.ibm.icu.impl.NormalizerImpl;
import com.ibm.icu.util.RangeValueIterator;

/**
* 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
* @draft 2.2
*/
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_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_[];
        
        // 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;
		}
        
        /**
         * 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 = Utility.compareUnsigned(first, ce);
			    if (comparison > 0) {
			        top = result;
			    } 
                else if (comparison < 0) {
			        bottom = result;
			    } 
                else {
			        if (second > contce) {
			            top = result;
			        } 
                    else if (second < contce) {
			            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);
			    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];
		                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_; 
    
    /**
     * Initializing the inverse UCA
     */
    static {
        try
        {
            String invdat = "/com/ibm/icu/impl/data/invuca.dat";
            InputStream i = invdat.getClass().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());
        }
    }
    
    // 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) { 
		    // 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);
    }
    
    /**
     * 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
		    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]);
		}
		
		Elements el = new Elements();
        el.m_isThai_ = false;
		el.m_prefixChars_ = null;
		int ce[] = new int[256];
        StringBuffer str = new StringBuffer();
        
		// add latin-1 stuff
		for (char u = 0; u < 0x100; u ++) {
            // if ((CE = ucmpe32_get(t.m_mapping, u)) == UCOL_NOT_FOUND
            int CE = t.m_mapping_.getValue((int)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_)) {
                str.delete(0, str.length());
                str.append(u);
		        el.m_uchars_ = str.toString();
		        el.m_cPoints_ = el.m_uchars_;
		        el.m_prefix_ = 0;
                int ceoffset = 0;
                m_utilColEIter_.setText(el.m_uchars_);
		        while (CE != CollationElementIterator.NULLORDER) {
		            CE = m_utilColEIter_.next();
		            if (CE != CollationElementIterator.NULLORDER) {
		                ce[ceoffset ++] = CE;
		            }
		        }
                el.m_CEs_ = new int[ceoffset];
                System.arraycopy(ce, 0, el.m_CEs_, 0, ceoffset);
		        addAnElement(t, el);
		    }
		}
		
        // 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]);
		    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 == true) { 
                    // we need to add if this contraction is not tailored.
		            el.m_prefix_ = 0;
		            el.m_prefixChars_ = null;
		            el.m_cPoints_ = el.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]);
    		        } 
                    el.m_uchars_ = str.toString();
                    int ceoffset = 0;
                    m_utilColEIter_.setText(el.m_uchars_);
                    while (true) {
                        int CE = m_utilColEIter_.next();
                        if (CE != CollationElementIterator.NULLORDER) {
                            ce[ceoffset ++] = CE;
                        }
                        else {
                            break;
                        }
                    }
                    el.m_CEs_ = new int[ceoffset];
                    System.arraycopy(ce, 0, el.m_CEs_, 0, ceoffset);
		            addAnElement(t, el);
                }
		    }
		    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;
        }
        
        // 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()
        {
            m_start_ = 0;
            m_end_ = 0;
            m_length_ = 0; 
            m_count_ = 0;
            m_length2_ = 0;
            m_count2_ = 0;
        }
	};
	
	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(new Integer(0));
            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 buildtable
		 */
		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 static class BuildTable implements TrieBuilder.DataManipulate
	{
		// package private methods ------------------------------------------
		
		/**
		 * For construction of the Trie tables.
		 * Has to be labeled public
		 * @param table build table
		 * @param cp
		 * @param offset
		 * @return data offset or 0 
		 * @draft 2.2
		 */
		public final 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
		 * @return build 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
	        m_mapping_ = new IntTrieBuilder(null, 0x100000, 
	                                      RuleBasedCollator.CE_SPECIAL_FLAG_
                                          | (CE_NOT_FOUND_TAG_ << 24), 
	                                      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_;
	}; 
	
	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_[];      
	    /** 
	     * 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_;
	    boolean m_isThai_;
	    
		// package private constructors -------------------------------------
		
		/**
		 * Package private constructor
		 */
		Elements()
		{
			m_sizePrim_ = new int[128];	
		    m_sizeSec_ = new int[128];	
		    m_sizeTer_ = new int[128];	
		}

        /**
		 * 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_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_;
		    m_isThai_ = element.m_isThai_;
		}

        // package private methods -------------------------------------------
        
        /**
         * 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_;
    
    // private methods -------------------------------------------------------
    
    /**
     * @param listheader parsed rule tokens
     * @exception Exception thrown when internal error occurs
     */
    private void initBuffers(CollationRuleParser.TokenListHeader listheader) 
                                                            throws Exception
    {
        CEGenerator gens[] = {new CEGenerator(), new CEGenerator(),
                              new CEGenerator()};
		int ceparts[] = new int[CE_BASIC_STRENGTH_LIMIT_];
		CollationRuleParser.Token token = listheader.m_last_;
		int t[] = new int[CE_STRENGTH_LIMIT_];
		Arrays.fill(t, 0, CE_STRENGTH_LIMIT_, 0);
		
		token.m_toInsert_ = 1;
		t[token.m_strength_] = 1;
		
		while (token.m_previous_ != null) {
		    if (token.m_previous_.m_strength_ < token.m_strength_) { 
                // going up
		        t[token.m_strength_] = 0;
		        t[token.m_previous_.m_strength_] ++;
		    } 
            else if (token.m_previous_.m_strength_ > token.m_strength_) { 
                // going down
		        t[token.m_previous_.m_strength_] = 1;
		    } 
            else {
		        t[token.m_strength_] ++;
		    }
		    token = token.m_previous_;
		    token.m_toInsert_ = t[token.m_strength_];
		} 
		
		token.m_toInsert_ = t[token.m_strength_];
		INVERSE_UCA_.getInverseGapPositions(listheader);
		
		token = listheader.m_first_;
		int fstrength = Collator.IDENTICAL;
		int initstrength = Collator.IDENTICAL;
		
		ceparts[Collator.PRIMARY] = mergeCE(listheader.m_baseCE_, 
                                            listheader.m_baseContCE_,
                                            Collator.PRIMARY);
		ceparts[Collator.SECONDARY] = mergeCE(listheader.m_baseCE_, 
                                              listheader.m_baseContCE_,
                                              Collator.SECONDARY);
		ceparts[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
			        ceparts[Collator.PRIMARY] 
                                         = listheader.m_gapsLo_[fstrength * 3];
			        ceparts[Collator.SECONDARY] 
                                     = listheader.m_gapsLo_[fstrength * 3 + 1];
			        ceparts[Collator.TERTIARY] = getCEGenerator(
                                                       gens[Collator.TERTIARY], 
                                                       listheader.m_gapsLo_, 
                                                       listheader.m_gapsHi_, 
                                                       token, fstrength); 
		        } 
                else if (initstrength == Collator.SECONDARY) { 
                    // secondaries
		            ceparts[Collator.PRIMARY] 
                                         = listheader.m_gapsLo_[fstrength * 3];
		            ceparts[Collator.SECONDARY] 
                                     = getCEGenerator(gens[Collator.SECONDARY], 
                                                      listheader.m_gapsLo_, 
                                                      listheader.m_gapsHi_, 
                                                      token, 
                                                      fstrength);
		            ceparts[Collator.TERTIARY] = getSimpleCEGenerator(
                                                       gens[Collator.TERTIARY], 
                                                       token, 
                                                       Collator.TERTIARY);
		        } 
                else { 
                    // primaries 
		            ceparts[Collator.PRIMARY] = getCEGenerator(
                                                        gens[Collator.PRIMARY], 
                                                        listheader.m_gapsLo_, 
                                                        listheader.m_gapsHi_, 
                                                        token, fstrength);
		            ceparts[Collator.SECONDARY] = getSimpleCEGenerator(
                                                      gens[Collator.SECONDARY], 
                                                      token, 
                                                      Collator.SECONDARY);
		            ceparts[Collator.TERTIARY] = getSimpleCEGenerator(
                                                       gens[Collator.TERTIARY], 
                                                       token, 
                                                       Collator.TERTIARY);
		        }
		    } 
            else {
		        if (token.m_strength_ == Collator.TERTIARY) {
		            ceparts[Collator.TERTIARY] = getNextGenerated(
                                                      gens[Collator.TERTIARY]);
		        } 
                else if (token.m_strength_ == Collator.SECONDARY) {
		            ceparts[Collator.SECONDARY] = getNextGenerated(
                                                     gens[Collator.SECONDARY]);
		            ceparts[Collator.TERTIARY] = getSimpleCEGenerator(
                                                       gens[Collator.TERTIARY], 
                                                       token, 
                                                       Collator.TERTIARY);
		        } 
                else if (token.m_strength_ == Collator.PRIMARY) {
		            ceparts[Collator.PRIMARY] = getNextGenerated(
                                                       gens[Collator.PRIMARY]);
		            ceparts[Collator.SECONDARY] = getSimpleCEGenerator(
                                                      gens[Collator.SECONDARY], 
                                                      token, 
                                                      Collator.SECONDARY);
		            ceparts[Collator.TERTIARY] = getSimpleCEGenerator(
                                                      gens[Collator.TERTIARY], 
                                                      token, 
                                                      Collator.TERTIARY);
		        }
		    }
		    doCE(ceparts, 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 fstrength 
     * @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 = (strength == Collator.TERTIARY) ? 0x3F : 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) {
		                low = RuleBasedCollator.COMMON_TOP_2_ << 24;
		                high = 0xFFFFFFFF;
		            } 
                    else {
		                // low = 0x02000000; 
                        // This needs to be checked - what if low is
		                // not good...
		                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.COMMON_TOP_2_ << 24, 
                                         high, count, maxbyte, g.m_ranges_);
	            g.m_current_ = RuleBasedCollator.COMMON_BOTTOM_2_;
	            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
     */
    private void doCE(int ceparts[], CollationRuleParser.Token token) 
    {
        // this one makes the table and stuff
	    int noofbytes[] = new int[3];
	    for (int i = 0; i < 3; i ++) {
	        noofbytes[i] = countBytes(ceparts[i]);
	    }
	
	    // Here we have to pack CEs from parts
	    int cei = 0;
	    int value = 0;
	
	    while ((cei << 1) < noofbytes[0] || cei < noofbytes[1] 
               || cei <noofbytes[2]) {
	        if (cei > 0) {
	            value = RuleBasedCollator.CE_CONTINUATION_MARKER_;
		    } else {
		        value = 0;
		    }
		
		    if ((cei << 1) < noofbytes[0]) {
		        value |= ((ceparts[0] >> (32 - ((cei + 1) << 4))) & 0xFFFF) 
                                                                        << 16;
		    }
		    if (cei < noofbytes[1]) {
		        value |= ((ceparts[1] >> (32 - ((cei + 1) << 3))) & 0xFF) << 8;
		    }
		    if (cei < noofbytes[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;
		}
	}

    /**
     * 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
	 * @exception Exception thrown when internal program error occurs
	 */
	private void createElements(BuildTable t, 
	                            CollationRuleParser.TokenListHeader lh) 
	                            throws Exception
    {
	    CollationRuleParser.Token tok = lh.m_first_;
	    Elements el = new Elements();
	    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;
	            CollationRuleParser.Token exp 
	                                         = new CollationRuleParser.Token();
	            exp.m_source_ = currentSequenceLen | expOffset;
	            exp.m_rules_ = m_parser_.m_source_;
	
	            while (len > 0) {
			        currentSequenceLen = len;
			        while (currentSequenceLen > 0) {
			            exp.m_source_ = (currentSequenceLen << 24) | expOffset;
			            CollationRuleParser.Token expt = 
			                                   (CollationRuleParser.Token)
			                                   m_parser_.m_hashTable_.get(exp);
			            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
	        el.m_CEs_ = new int[tok.m_CELength_ + tok.m_expCELength_];
	        // copy CEs
	        System.arraycopy(tok.m_CE_, 0, el.m_CEs_, 0, tok.m_CELength_);
	        System.arraycopy(tok.m_expCE_, 0, el.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 - 
	        el.m_prefix_ = 0;// el.m_prefixChars_;
	        el.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;
		        el.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);
		        el.m_uchars_ = m_parser_.m_source_.substring(offset, 
		                                                     offset + size);
		    } 
		    else {
	            el.m_prefixChars_ = null;
	            int offset = tok.m_source_ & 0x00FFFFFF;
	            int size = tok.m_source_ >>> 24;
	            el.m_uchars_ = m_parser_.m_source_.substring(offset, 
	                                                         offset + size);
	        }
	        el.m_cPoints_ = el.m_uchars_;
	        el.m_isThai_ = CollationElementIterator.isThaiPreVowel(
	                                                  el.m_cPoints_.charAt(0));
	        for (int i = 0; i < el.m_cPoints_.length() - el.m_cPointsOffset_; 
	             i ++) {
		         if (isJamo(el.m_cPoints_.charAt(i))) {
		             t.m_collator_.m_isJamoSpecial_ = true;
		             break;
		        }
		    }
	
	        // Case bits handling 
	        el.m_CEs_[0] &= 0xFFFFFF3F; // Clean the case bits field
	        if (el.m_cPoints_.length() - el.m_cPointsOffset_ > 1) {
	            // Do it manually
	            el.m_CEs_[0] |= getCaseBits(el.m_cPoints_);
	        } 
	        else {
	            // Copy it from the UCA
	            int caseCE = getFirstCE(el.m_cPoints_.charAt(0));
	            el.m_CEs_[0] |= (caseCE & 0xC0);
	        }
	
	        // and then, add it
	        addAnElement(t, el);
	        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 final 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 static int addAnElement(BuildTable t, Elements element) 
    {
  		Vector expansions = t.m_expansions_;
        if (element.m_CEs_.length == 1) {
	    	if (element.m_isThai_ == false) {
	            element.m_mapCE_ = element.m_CEs_[0];
	        } 
	        else { // add thai - totally bad here
                // omitted the expansion offset here for the builder
                // (HEADER_SIZE_ >> 2)
	            int expansion = RuleBasedCollator.CE_SPECIAL_FLAG_ 
	                        | (CE_THAI_TAG_ << RuleBasedCollator.CE_TAG_SHIFT_) 
	                        | (addExpansion(expansions, element.m_CEs_[0])
	                           << 4) 
	                        | 0x1;
	            element.m_mapCE_ = expansion;
	        }
	    } 
	    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_CEs_.length == 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_CEs_.length; i ++) {
	                 addExpansion(expansions, element.m_CEs_[i]);
	            }
			    if (element.m_CEs_.length <= 0xF) {
			        expansion |= element.m_CEs_.length;
			    } 
			    else {
			        addExpansion(expansions, 0);
			    }
			    element.m_mapCE_ = expansion;
			    setMaxExpansion(element.m_CEs_[element.m_CEs_.length - 1],
			                    (byte)element.m_CEs_.length, 
			                    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_CEs_.length 
                                                                          - 1],
			                            (byte)element.m_CEs_.length,
			                            t.m_maxJamoExpansions_);
			    }
		    }
	    }
	
	    // 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.
		    Elements composed = new Elements(element);
		    composed.m_prefix_ = 0;
		    composed.m_uchars_ = Normalizer.compose(element.m_prefixChars_, 
                                                    false);
            composed.m_cPoints_ = composed.m_uchars_;                         
            composed.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 (composed.m_prefixChars_.length() 
                        != element.m_prefixChars_.length() - element.m_prefix_
                    || !composed.m_prefixChars_.regionMatches(0,
                                    element.m_prefixChars_, element.m_prefix_,
                                    composed.m_prefixChars_.length())) {
		            // do it!
		            composed.m_mapCE_ = addPrefix(t, element.m_mapCE_, 
                                                  composed);
		        }
		    }
	    }
	
	    // 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
	        CanonicalIterator it = new CanonicalIterator(element.m_cPoints_);
		    String source = it.next();
		    while (source != null && source.length() > 0) {
		        if (Normalizer.quickCheck(source, Normalizer.FCD) 
                    != Normalizer.NO) {
		            element.m_uchars_ = source;
		            element.m_cPoints_ = element.m_uchars_;
		            finalizeAddition(t, element);
		        }
		        source = it.next();
		    }
		
		    return element.m_mapCE_;
		} 
        else {
		    return finalizeAddition(t, element);  
		}
	}

    /**
     * Pads the argument value to a count of 4
     * @param something value to pad
     * @return padded something
     */
    private static final int paddedsize(int something) 
    {
    	return something + ((something % 4) != 0 ? 4 - (something % 4) : 0);
    }    
    
    /**
     * 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(new Boolean(isV));
		  
		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 static 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();
	    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;
	        reversed.append(element.m_prefixChars_.charAt(offset));
	    }
	    element.m_prefixChars_ = reversed.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 = null;

        if (element == 0xFFFFFF || table.m_elements_.get(element) == null) {
            tbl = null;
        } 
        else {
        	tbl = (BasicContractionTable)table.m_elements_.get(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 
     * @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 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_);
		        }
		    } 
		    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 static 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 
        int lengthCounts[] = new int[6];     
        // countBytes to the power of index 
        long powers[] = new long[5]; // for unsignedness
        // gcc requires explicit initialization 
        powers[0] = 1;
        powers[1] = countBytes;
        powers[2] = powers[1] * countBytes;
        powers[3] = powers[2] * countBytes;
        powers[4] = powers[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_ 
                        * powers[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(lengthCounts, 0);
            for (int i = 0; i < rangeCount; ++ i) {
                lengthCounts[ranges[i].m_length2_] += ranges[i].m_count2_;
            }
            // now try to allocate n elements in the available short ranges 
            if (n <= lengthCounts[minLength] + lengthCounts[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 = powers[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 static 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.
        int weight = lowerLimit;
        WeightRange lower[] = {new WeightRange(), new WeightRange(), 
                               new WeightRange(), new WeightRange(), 
                               new WeightRange()}; 
        for (int length = lowerLength; length >= 2; -- length) {
            int trail = getWeightByte(weight, length);
            if (trail < maxByte) {
                lower[length].m_start_ = incWeightTrail(weight, length);
                lower[length].m_end_ = setWeightTrail(weight, length, maxByte);
                lower[length].m_length_ = length;
                lower[length].m_count_ = maxByte - trail;
            }
            weight = truncateWeight(weight, length - 1);
        }
        WeightRange middle = new WeightRange(); 
        middle.m_start_ = incWeightTrail(weight, 1);
    
        weight = upperLimit;
        // [0] and [1] are not used - this simplifies indexing 
        WeightRange upper[] = {new WeightRange(), new WeightRange(), 
                               new WeightRange(), new WeightRange(), 
                               new WeightRange()}; 
        for (int length = upperLength; length >= 2; length --) {
            int trail = getWeightByte(weight, length);
            if (trail > RuleBasedCollator.BYTE_FIRST_TAILORED_) {
                upper[length].m_start_ = setWeightTrail(weight, length, 
                                       RuleBasedCollator.BYTE_FIRST_TAILORED_);
                upper[length].m_end_ = decWeightTrail(weight, length);
                upper[length].m_length_ = length;
                upper[length].m_count_ = trail
                                     - RuleBasedCollator.BYTE_FIRST_TAILORED_;
            }
            weight = truncateWeight(weight, length - 1);
        }
        middle.m_end_ = decWeightTrail(weight, 1);
    
        // set the middle range
        middle.m_length_ = 1;
        if (middle.m_end_ >= middle.m_start_) {
            middle.m_count_ = ((middle.m_end_ - middle.m_start_) >> 24) + 1;
        } 
        else {
            // eliminate overlaps
            // remove the middle range
            middle.m_count_ = 0;
            // reduce or remove the lower ranges that go beyond upperLimit
            for (int length = 4; length >= 2; -- length) {
                if (lower[length].m_count_>0 && upper[length].m_count_ > 0) {
                    int start = upper[length].m_start_;
                    int end = lower[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 = lower[length].m_start_;
                        end = lower[length].m_end_ = upper[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
                        lower[length].m_count_ = getWeightByte(end, length)
                                  - getWeightByte(start, length) + 1 
                                  + countBytes * (getWeightByte(end, length - 1)
                                                  - getWeightByte(start, 
                                                                  length - 1));
                        upper[length].m_count_=0;
                        while (-- length >= 2) {
                            lower[length].m_count_ = upper[length].m_count_ 
                                                                           = 0;
                        }
                        break;
                    }
                }
            }
        }
    
        // copy the ranges, shortest first, into the result array 
        int rangeCount = 0;
        if (middle.m_count_ > 0) {
            ranges[0] = middle;
            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 (upper[length].m_count_ > 0) {
                ranges[rangeCount] = upper[length];
                ++ rangeCount;
            }
            if (lower[length].m_count_ > 0) {
                ranges[rangeCount] = lower[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 final int decWeightTrail(int weight, int length) 
    {
        return weight - (1 << ((4 - length) << 3));
    }
    
    /**
     * 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 boolean isTailored(ContractionTable table, int element, 
                               char array[], int offset) 
    {
        while (array[offset] != 0) {
            element = getCE(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() - 1;
        collator.m_expansionEndCE_ = new int[size];
        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];
        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.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_;    
    }
    
    /**
     * 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 table 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) 
    {
    
        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 (t.m_prefixLookup_ != null) {
            Enumeration enum = t.m_prefixLookup_.elements();
            while (enum.hasMoreElements()) {
                Elements e = (Elements)enum.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.
                String decomp = Normalizer.decompose(e.m_cPoints_, true);
                unsafeCPSet(t.m_unsafeCP_, decomp.charAt(0));
            } 
        }
    }
    
    /**
     * Create closure
     * @param t build table
     * @param collator RuleBasedCollator
     * @param colEl collation element iterator
     * @param start 
     * @param limit
     * @param type character type
     * @return 
     */
    private static boolean enumCategoryRangeClosureCategory(BuildTable t, 
                                             RuleBasedCollator collator, 
                                             CollationElementIterator colEl, 
                                             int start, int limit, int type) 
    {
        if (type > 0) { 
            // if the range is assigned - we might ommit more categories later
            Elements el = new Elements();
            for (int u32 = start; u32 < limit; u32 ++) {
            	String comp = UCharacter.toString(u32);
                String decomp = Normalizer.decompose(comp, false);
                if (decomp.length() > 1 || (decomp.length() == 1 
                                          && decomp.charAt(0) != (char)u32)) {
                    if (!collator.equals(comp, decomp)) {
                        el.m_cPoints_ = decomp;
                        el.m_prefix_ = 0;
                        Vector cevector = new Vector();
                        Elements prefix = (Elements)t.m_prefixLookup_.get(el);
                        if (prefix == null) {
                            el.m_cPoints_ = comp;
                            el.m_prefix_ = 0;
                            el.m_prefixChars_ = null;
                            el.m_CEs_ = null;
                            colEl.setText(decomp);
                            int ce = colEl.next();
                            while (ce != CollationElementIterator.NULLORDER) {
                                cevector.add(new Integer(ce));
                                ce = colEl.next();
                            }
                            int size = cevector.size();
                            el.m_CEs_ = new int[size];
                            for (int i = 0; i < size; i ++) {
                                el.m_CEs_[i] 
                                       = ((Integer)cevector.get(i)).intValue();
                            }
                        } 
                        else {
                            el.m_cPoints_ = comp;
                            el.m_prefix_ = 0;
                            el.m_prefixChars_ = null;
                            el.m_CEs_ = new int[1];
                            el.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
                            el.m_isThai_ 
                                    = CollationElementIterator.isThaiPreVowel(
                                                   el.m_cPoints_.charAt(0));
                        }
                        addAnElement(t, el);
                    }
                }
            }
        }
        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);
        }
    }
    
    private static 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_) {
                        Elements el = new Elements();
                        el.m_isThai_ = false;
                        el.m_prefix_ = 0;
                        el.m_uchars_ = UCharacter.toString(start);
                        el.m_cPoints_ = el.m_uchars_;
                        el.m_cPointsOffset_ = 0;
                        el.m_CEs_ = new int[1];
                        el.m_CEs_[0] = 0;
                        addAnElement(t, el);
                    }
                    start ++;
                }
            }
        }
    }
}
