/**
*******************************************************************************
* 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/08/01 21:09:17 $ 
* $Revision: 1.4 $
*
*******************************************************************************
*/
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.lang.UCharacterCategory;
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.icu";
            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 != UCharacterCategory.UNASSIGNED 
            && type != UCharacterCategory.PRIVATE_USE) { 
            // if the range is assigned - we might ommit more categories later
            Elements el = new Elements();
            char dec[] = new char[256];
            for (int u32 = start; u32 < limit; u32 ++) {
                int noOfDec = NormalizerImpl.getDecomposition(u32, false,
                                                              dec, 0, 256);
                if (noOfDec > 0) {
                    // if we're positive, that means there is no decomposition
                    String comp = UCharacter.toString(u32);
                    String decomp = new String(dec, 0, noOfDec);
                    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 ++;
                }
            }
        }
    }
}
