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

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

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

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

        
        /**
         * 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);
		    int primaryCE = t1 & RuleBasedCollator.CE_PRIMARY_MASK_ | (t2 & RuleBasedCollator.CE_PRIMARY_MASK_) >>> 16;
		    primaryCE = RuleBasedCollator.impCEGen_.getImplicitFromRaw(RuleBasedCollator.impCEGen_.getRawFromImplicit(primaryCE)+1);

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

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

                
                if (needToAdd == true) { 
                    // we need to add if this contraction is not tailored.
		    m_utilElement_.m_prefix_ = 0;
		    m_utilElement_.m_prefixChars_ = null;
		    m_utilElement_.m_cPoints_ = m_utilElement_.m_uchars_;
                    str.delete(0, str.length());
                    str.append(conts[offset]);
                    str.append(conts[offset + 1]);
		    if (conts[offset + 2] != 0) {
			str.append(conts[offset + 2]);
		    } 
                    m_utilElement_.m_uchars_ = str.toString();
                    m_utilElement_.m_CELength_ = 0;
                    m_utilColEIter_.setText(m_utilElement_.m_uchars_);
                    while (true) {
                        int CE = m_utilColEIter_.next();
                        if (CE != CollationElementIterator.NULLORDER) {
                            m_utilElement_.m_CEs_[m_utilElement_.m_CELength_ 
						 ++] = CE;
                        }
                        else {
                            break;
                        }
                    }
                    addAnElement(t, m_utilElement_);
                }
	    } else if(m_parser_.m_removeSet_ != null && m_parser_.m_removeSet_.contains(conts[offset])) {
                copyRangeFromUCA(t, conts[offset], conts[offset]);
            }
            
	    offset += 3;
	}
        
        // Add completely ignorable elements
        processUCACompleteIgnorables(t);
        
        // canonical closure 
        canonicalClosure(t);
  
	// still need to produce compatibility closure
	assembleTable(t, collator);  
    }
    
    // private inner classes -------------------------------------------------
    
    private static class CEGenerator 
    {
        // package private data members --------------------------------------
        
	WeightRange m_ranges_[];
	int m_rangesLength_;
	int m_byteSize_; 
        int m_start_; 
        int m_limit_;
	int m_maxCount_;
	int m_count_;
	int m_current_;
	int m_fLow_; // forbidden Low 
	int m_fHigh_; // forbidden High 
        
        // package private constructor ---------------------------------------
        
        CEGenerator() 
        {
            m_ranges_ = new WeightRange[7];      
            for (int i = 6; i >= 0; i --) {
                m_ranges_[i] = new WeightRange();
            }
        }
    };

    private static class WeightRange implements Comparable
    {
        // public methods ----------------------------------------------------
        
        /**
         * Compares this object with target
         * @param target object to compare with
         * @return 0 if equals, 1 if this is > target, -1 otherwise
         */
        public int compareTo(Object target) 
        {
            if (this == target) {
                return 0;
            }
            int tstart = ((WeightRange)target).m_start_;   
            if (m_start_ == tstart) {
                return 0;
            }
            if (m_start_ > tstart) {
                return 1;
            }
            return -1;
        }
        
        /**
         * Initialize 
         */
        public void clear()
        {
            m_start_ = 0;
            m_end_ = 0;
            m_length_ = 0; 
            m_count_ = 0;
            m_length2_ = 0;
            m_count2_ = 0;
        }
        
        // package private data members --------------------------------------
        
	int m_start_;
        int m_end_;
	int m_length_; 
        int m_count_;
	int m_length2_;
	int m_count2_;
        
        // package private constructor ---------------------------------------
        
        WeightRange()
        {
            clear();
        }
        
        /**
         * Copy constructor.
         * Cloneable is troublesome, needs to check for exception
         * @param source to clone
         */
        WeightRange(WeightRange source)
        {
            m_start_ = source.m_start_;
            m_end_ = source.m_end_;
            m_length_ = source.m_length_; 
            m_count_ = source.m_count_;
            m_length2_ = source.m_length2_;
            m_count2_ = source.m_count2_;
        }
    };
	
    private static class MaxJamoExpansionTable
    {
	// package private data members --------------------------------------
		
	Vector m_endExpansionCE_;
	// vector of booleans
	Vector m_isV_;
	byte m_maxLSize_;
	byte m_maxVSize_;
	byte m_maxTSize_;
	    
	// package private constructor ---------------------------------------
	    
	MaxJamoExpansionTable()
	{
	    m_endExpansionCE_ = new Vector();
	    m_isV_ = new Vector();
	    m_endExpansionCE_.add(new Integer(0));
	    m_isV_.add(new Boolean(false));
            m_maxLSize_ = 1;
            m_maxVSize_ = 1;
            m_maxTSize_ = 1;
	}
        
        MaxJamoExpansionTable(MaxJamoExpansionTable table)
        {
            m_endExpansionCE_ = (Vector)table.m_endExpansionCE_.clone();
            m_isV_ = (Vector)table.m_isV_.clone();
            m_maxLSize_ = table.m_maxLSize_;
            m_maxVSize_ = table.m_maxVSize_;
            m_maxTSize_ = table.m_maxTSize_;
        }
    };
	
    private static class MaxExpansionTable 
    {
	// package private constructor --------------------------------------
		
	MaxExpansionTable() 
	{
	    m_endExpansionCE_ = new Vector();
	    m_expansionCESize_ = new Vector();
	    m_endExpansionCE_.add(new Integer(0));
	    m_expansionCESize_.add(new Byte((byte)0));
	}
        
        MaxExpansionTable(MaxExpansionTable table) 
        {
            m_endExpansionCE_ = (Vector)table.m_endExpansionCE_.clone();
            m_expansionCESize_ = (Vector)table.m_expansionCESize_.clone();
        }
		
	// package private data member --------------------------------------
		
	Vector m_endExpansionCE_;
	Vector m_expansionCESize_;
    };
	
    private static class BasicContractionTable 
    {
	// package private constructors -------------------------------------
		
	BasicContractionTable()
	{
	    m_CEs_ = new Vector();
	    m_codePoints_ = new StringBuffer();
	}
		
	// package private data members -------------------------------------
		
	StringBuffer m_codePoints_;
	Vector m_CEs_;
    };
    
    private static class ContractionTable 
    {
	// package private constructor --------------------------------------
		
	/**
	 * Builds a contraction table
	 * @param 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 final 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 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
            int trieinitialvalue = RuleBasedCollator.CE_SPECIAL_FLAG_
		| (CE_NOT_FOUND_TAG_ << 24);
	    // temporary fix for jb3822, 0x100000 -> 30000
	    m_mapping_ = new IntTrieBuilder(null, 0x30000, trieinitialvalue, 
                                            trieinitialvalue, true); 
	    m_prefixLookup_ = new Hashtable();
	    // uhash_open(prefixLookupHash, prefixLookupComp);
	    m_contractions_ = new ContractionTable(m_mapping_);
	    // copy UCA's maxexpansion and merge as we go along
	    m_maxExpansions_ = maxet;
	    // adding an extra initial value for easier manipulation 
	    for (int i = 0; 
		 i < RuleBasedCollator.UCA_.m_expansionEndCE_.length; i ++) {
		maxet.m_endExpansionCE_.add(new Integer(
							RuleBasedCollator.UCA_.m_expansionEndCE_[i]));
		maxet.m_expansionCESize_.add(new Byte(
						      RuleBasedCollator.UCA_.m_expansionEndCEMaxSize_[i]));
	    }
	    m_maxJamoExpansions_ = maxjet;
		
	    m_unsafeCP_ = new byte[UNSAFECP_TABLE_SIZE_];
	    m_contrEndCP_ = new byte[UNSAFECP_TABLE_SIZE_];
	    Arrays.fill(m_unsafeCP_, (byte)0);
	    Arrays.fill(m_contrEndCP_, (byte)0);
	}
	
        /**
         * Duplicating a BuildTable.
         * Not all data will be duplicated into their own object.
         * @param table to clone
         */
        BuildTable(BuildTable table) 
        {
            m_collator_ = table.m_collator_;
            m_mapping_ = new IntTrieBuilder(table.m_mapping_);
            m_expansions_ = (Vector)table.m_expansions_.clone();
            m_contractions_ = new ContractionTable(table.m_contractions_);
            m_contractions_.m_mapping_ = m_mapping_;
            m_options_ = table.m_options_;
            m_maxExpansions_ = new MaxExpansionTable(table.m_maxExpansions_);
            m_maxJamoExpansions_ 
		= new MaxJamoExpansionTable(table.m_maxJamoExpansions_);
            m_unsafeCP_ = new byte[table.m_unsafeCP_.length];
            System.arraycopy(table.m_unsafeCP_, 0, m_unsafeCP_, 0,
                             m_unsafeCP_.length);
            m_contrEndCP_ = new byte[table.m_contrEndCP_.length];
            System.arraycopy(table.m_contrEndCP_, 0, m_contrEndCP_, 0,
                             m_contrEndCP_.length);
        }
        
	// package private data members -------------------------------------
		
	RuleBasedCollator m_collator_;
        IntTrieBuilder m_mapping_; 
        Vector m_expansions_; 
        ContractionTable m_contractions_;
	// UCATableHeader image;
	CollationRuleParser.OptionSet m_options_;
	MaxExpansionTable m_maxExpansions_;
	MaxJamoExpansionTable m_maxJamoExpansions_;
	byte m_unsafeCP_[];
	byte m_contrEndCP_[];
	Hashtable m_prefixLookup_;
    }; 
	
    private static class Elements
    {
	// package private data members -------------------------------------
		
	String m_prefixChars_;
	int m_prefix_;
	String m_uchars_;
	/**
	 * Working string
	 */
	String m_cPoints_;    
	/**
	 * Offset to the working string
	 */
	int m_cPointsOffset_;
	/** 
	 * These are collation elements - there could be more than one - in 
	 * case of expansion 
	 */    
	int m_CEs_[];      
        int m_CELength_;
	/** 
	 * This is the value element maps in original table   
	 */
	int m_mapCE_;         
	int m_sizePrim_[];
	int m_sizeSec_[];
	int m_sizeTer_[];
	boolean m_variableTop_;
	boolean m_caseBit_;
	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];	
            m_CEs_ = new int[256];
            m_CELength_ = 0;
	}

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

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

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

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

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

    /**
     * @param g CEGenerator
     * @param token rule token
     * @param 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 = 0;
	if(strength == Collator.TERTIARY) {
	    maxbyte = 0x3F;
	} else if(strength == Collator.PRIMARY) {
	    maxbyte = 0xFE;
	} else {
	    maxbyte = 0xFF;
	}
	
	int count = token.m_toInsert_;
	
	if (Utility.compareUnsigned(low, high) >= 0 
            && strength > Collator.PRIMARY) {
	    int s = strength;
	    while (true) {
		s --;
		if (lows[fstrength * 3 + s] != highs[fstrength * 3 + s]) {
		    if (strength == Collator.SECONDARY) {
			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.BYTE_UNSHIFTED_MIN_ << 24, 
						    high, count, maxbyte, g.m_ranges_);
        g.m_current_ = nextWeight(g);
		//g.m_current_ = RuleBasedCollator.COMMON_BOTTOM_2_ << 24;
		return g.m_current_;
	    }
	} 
	
	g.m_rangesLength_ = allocateWeights(low, high, count, maxbyte, 
                                            g.m_ranges_);
	if (g.m_rangesLength_ == 0) {
	    throw new Exception("Internal program error");
	}
	g.m_current_ = nextWeight(g);
	return g.m_current_;
    }

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

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

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

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

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

    /**
     * Constructs a special ce
     * @param tag special tag
     * @param ce 
     * @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 int allocateWeights(int lowerLimit, int upperLimit, int n,
                                int maxByte, WeightRange ranges[]) 
    {
        // number of usable byte values 3..maxByte
        int countBytes = maxByte - RuleBasedCollator.BYTE_FIRST_TAILORED_ + 1;
        // [0] unused, [5] to make index checks unnecessary, m_utilCountBuffer_
        // countBytes to the power of index, m_utilLongBuffer_ for unsignedness
        // gcc requires explicit initialization 
        m_utilLongBuffer_[0] = 1;
        m_utilLongBuffer_[1] = countBytes;
        m_utilLongBuffer_[2] = m_utilLongBuffer_[1] * countBytes;
        m_utilLongBuffer_[3] = m_utilLongBuffer_[2] * countBytes;
        m_utilLongBuffer_[4] = m_utilLongBuffer_[3] * countBytes;
        int rangeCount = getWeightRanges(lowerLimit, upperLimit, maxByte, 
                                         countBytes, ranges);
        if (rangeCount <= 0) {
            return 0;
        }
        // what is the maximum number of weights with these ranges?
        long maxCount = 0;
        for (int i = 0; i < rangeCount; ++ i) {
            maxCount += (long)ranges[i].m_count_ 
		* m_utilLongBuffer_[4 - ranges[i].m_length_];
        }
        if (maxCount < n) {
            return 0;
        }
        // set the length2 and count2 fields
        for (int i = 0; i < rangeCount; ++ i) {
            ranges[i].m_length2_ = ranges[i].m_length_;
            ranges[i].m_count2_ = ranges[i].m_count_;
        }
        // try until we find suitably large ranges
        while (true) {
            // get the smallest number of bytes in a range
            int minLength = ranges[0].m_length2_;
            // sum up the number of elements that fit into ranges of each byte 
            // length
            Arrays.fill(m_utilCountBuffer_, 0);
            for (int i = 0; i < rangeCount; ++ i) {
                m_utilCountBuffer_[ranges[i].m_length2_] += ranges[i].m_count2_;
            }
            // now try to allocate n elements in the available short ranges 
            if (n <= m_utilCountBuffer_[minLength] 
		+ m_utilCountBuffer_[minLength + 1]) {
                // trivial cases, use the first few ranges
                maxCount = 0;
                rangeCount = 0;
                do {
                    maxCount += ranges[rangeCount].m_count2_;
                    ++ rangeCount;
                } while (n > maxCount);
                break;
            } 
            else if (n <= ranges[0].m_count2_ * countBytes) {
                // easy case, just make this one range large enough by 
                // lengthening it once more, possibly split it
                rangeCount = 1;
                // calculate how to split the range between maxLength-1 
                // (count1) and maxLength (count2) 
                long power_1 
		    = m_utilLongBuffer_[minLength - ranges[0].m_length_];
                long power = power_1 * countBytes;
                int count2 = (int)((n + power - 1) / power);
                int count1 = ranges[0].m_count_ - count2;
                // split the range
                if (count1 < 1) {
                    // lengthen the entire range to maxLength 
                    lengthenRange(ranges, 0, maxByte, countBytes);
                } 
                else {
                    // really split the range
                    // create a new range with the end and initial and current 
                    // length of the old one
                    rangeCount = 2;
                    ranges[1].m_end_ = ranges[0].m_end_;
                    ranges[1].m_length_ = ranges[0].m_length_;
                    ranges[1].m_length2_ = minLength;
                    // set the end of the first range according to count1
                    int i = ranges[0].m_length_;
                    int b = getWeightByte(ranges[0].m_start_, i) + count1 - 1;
                    // ranges[0].count and count1 may be >countBytes from 
                    // merging adjacent ranges; b > maxByte is possible
                    if (b <= maxByte) {
                        ranges[0].m_end_ = setWeightByte(ranges[0].m_start_, i, 
                                                         b);
                    } 
                    else {
                        ranges[0].m_end_ = setWeightByte(
							 incWeight(ranges[0].m_start_, i - 1, 
								   maxByte), 
							 i, b - countBytes);
                    }
                    // set the bytes in the end weight at length + 1..length2 
                    // to maxByte
                    b = (maxByte << 24) | (maxByte << 16) | (maxByte << 8)
                        | maxByte; // this used to be 0xffffffff 
                    ranges[0].m_end_ = truncateWeight(ranges[0].m_end_, i) 
			| (b >>> (i << 3)) 
			& (b << ((4 - minLength) << 3));
                    // set the start of the second range to immediately follow 
                    // the end of the first one
                    ranges[1].m_start_ = incWeight(ranges[0].m_end_, minLength, 
                                                   maxByte);
                    // set the count values (informational)
                    ranges[0].m_count_ = count1;
                    ranges[1].m_count_ = count2;
    
                    ranges[0].m_count2_ = (int)(count1 * power_1);
                    // will be *countBytes when lengthened 
                    ranges[1].m_count2_ = (int)(count2 * power_1); 
    
                    // lengthen the second range to maxLength
                    lengthenRange(ranges, 1, maxByte, countBytes);
                }
                break;
            }
            // no good match, lengthen all minLength ranges and iterate 
            for (int i=0; ranges[i].m_length2_ == minLength; ++ i) {
                lengthenRange(ranges, i, maxByte, countBytes);
            }
        }
    
        if (rangeCount > 1) {
            // sort the ranges by weight values 
            Arrays.sort(ranges, 0, rangeCount);
        }
    
        // set maxByte in ranges[0] for ucol_nextWeight()
        ranges[0].m_count_ = maxByte;
    
        return rangeCount;
    }
    
    /**
     * Updates the range length
     * @param range weight range array
     * @param offset to weight range array
     * @param maxByte
     * @param countBytes
     * @return new length
     */
    private static final int lengthenRange(WeightRange range[], int offset, 
                                           int maxByte, int countBytes) 
    {
        int length = range[offset].m_length2_ + 1;
        range[offset].m_start_ = setWeightTrail(range[offset].m_start_, length, 
						RuleBasedCollator.BYTE_FIRST_TAILORED_);
        range[offset].m_end_ = setWeightTrail(range[offset].m_end_, length, 
                                              maxByte);
        range[offset].m_count2_ *= countBytes;
        range[offset].m_length2_ = length;
        return length;
    }
    
    /**
     * Gets the weight 
     * @param weight
     * @param length
     * @param trail
     * @return new weight
     */
    private static final int setWeightTrail(int weight, int length, int trail) 
    {
        length = (4 - length) << 3;
        return (weight & (0xffffff00 << length)) | (trail << length);
    }
    
    /**
     * take two CE weights and calculate the
     * possible ranges of weights between the two limits, excluding them
     * for weights with up to 4 bytes there are up to 2*4-1=7 ranges
     * @param lowerlimit
     * @param upperlimit
     * @param maxByte
     * @param countBytes
     * @param ranges
     * @return weight ranges
     */
    private int getWeightRanges(int lowerLimit, int upperLimit, int maxByte, 
                                int countBytes, WeightRange ranges[]) 
    {
        // assume that both lowerLimit & upperLimit are not 0 
        // get the lengths of the limits 
        int lowerLength = lengthOfWeight(lowerLimit);
        int upperLength = lengthOfWeight(upperLimit);
        if (Utility.compareUnsigned(lowerLimit, upperLimit) >= 0) {
            return 0;
        }
        // check that neither is a prefix of the other
        if (lowerLength < upperLength) {
            if (lowerLimit == truncateWeight(upperLimit, lowerLength)) {
                return 0;
            }
        }
        // if the upper limit is a prefix of the lower limit then the earlier 
        // test lowerLimit >= upperLimit has caught it
        // reset local variables
        // With the limit lengths of 1..4, there are up to 7 ranges for 
        // allocation:
        // range     minimum length
        // lower[4]  4
        // lower[3]  3
        // lower[2]  2
        // middle    1
        // upper[2]  2
        // upper[3]  3
        // upper[4]  4
        // We are now going to calculate up to 7 ranges.
        // Some of them will typically overlap, so we will then have to merge 
        // and eliminate ranges.
        
        // We have to clean cruft from previous invocations
        // before doing anything. C++ already does that
        for(int length = 0; length < 5; length++) {
            m_utilLowerWeightRange_[length].clear();
            m_utilUpperWeightRange_[length].clear();
        }
        m_utilWeightRange_.clear();
        
        int weight = lowerLimit;
        for (int length = lowerLength; length >= 2; -- length) {
            m_utilLowerWeightRange_[length].clear();
            int trail = getWeightByte(weight, length);
            if (trail < maxByte) {
                m_utilLowerWeightRange_[length].m_start_ 
		    = incWeightTrail(weight, length);
                m_utilLowerWeightRange_[length].m_end_ 
		    = setWeightTrail(weight, length, maxByte);
                m_utilLowerWeightRange_[length].m_length_ = length;
                m_utilLowerWeightRange_[length].m_count_ = maxByte - trail;
            }
            weight = truncateWeight(weight, length - 1);
        }
        m_utilWeightRange_.m_start_ = incWeightTrail(weight, 1);
    
        weight = upperLimit;
        // [0] and [1] are not used - this simplifies indexing, 
        // m_utilUpperWeightRange_
        
        for (int length = upperLength; length >= 2; length --) {
            int trail = getWeightByte(weight, length);
            if (trail > RuleBasedCollator.BYTE_FIRST_TAILORED_) {
                m_utilUpperWeightRange_[length].m_start_ 
		    = setWeightTrail(weight, length, 
				     RuleBasedCollator.BYTE_FIRST_TAILORED_);
                m_utilUpperWeightRange_[length].m_end_ 
		    = decWeightTrail(weight, length);
                m_utilUpperWeightRange_[length].m_length_ = length;
                m_utilUpperWeightRange_[length].m_count_ = trail
		    - RuleBasedCollator.BYTE_FIRST_TAILORED_;
            }
            weight = truncateWeight(weight, length - 1);
        }
        m_utilWeightRange_.m_end_ = decWeightTrail(weight, 1);
    
        // set the middle range
        m_utilWeightRange_.m_length_ = 1;
        if (Utility.compareUnsigned(m_utilWeightRange_.m_end_, m_utilWeightRange_.m_start_) >= 0) {
	    //if (m_utilWeightRange_.m_end_ >= m_utilWeightRange_.m_start_) {
            m_utilWeightRange_.m_count_ 
		= ((m_utilWeightRange_.m_end_ - m_utilWeightRange_.m_start_) 
		   >>> 24) + 1;
        } 
        else {
            // eliminate overlaps
            // remove the middle range
            m_utilWeightRange_.m_count_ = 0;
            // reduce or remove the lower ranges that go beyond upperLimit
            for (int length = 4; length >= 2; -- length) {
                if (m_utilLowerWeightRange_[length].m_count_ > 0 
                    && m_utilUpperWeightRange_[length].m_count_ > 0) {
                    int start = m_utilUpperWeightRange_[length].m_start_;
                    int end = m_utilLowerWeightRange_[length].m_end_;
                    if (end >= start || incWeight(end, length, maxByte) 
			== start) {
                        // lower and upper ranges collide or are directly 
                        // adjacent: merge these two and remove all shorter 
                        // ranges
                        start = m_utilLowerWeightRange_[length].m_start_;
                        end = m_utilLowerWeightRange_[length].m_end_ 
                            = m_utilUpperWeightRange_[length].m_end_;
                        // merging directly adjacent ranges needs to subtract 
                        // the 0/1 gaps in between;
                        // it may result in a range with count>countBytes
                        m_utilLowerWeightRange_[length].m_count_ 
			    = getWeightByte(end, length)
			    - getWeightByte(start, length) + 1 
			    + countBytes * (getWeightByte(end, length - 1)
					    - getWeightByte(start, 
							    length - 1));
                        m_utilUpperWeightRange_[length].m_count_ = 0;
                        while (-- length >= 2) {
                            m_utilLowerWeightRange_[length].m_count_ 
                                = m_utilUpperWeightRange_[length].m_count_ = 0;
                        }
                        break;
                    }
                }
            }
        }
    
        // copy the ranges, shortest first, into the result array 
        int rangeCount = 0;
        if (m_utilWeightRange_.m_count_ > 0) {
            ranges[0] = new WeightRange(m_utilWeightRange_);
            rangeCount = 1;
        }
        for (int length = 2; length <= 4; ++ length) {
            // copy upper first so that later the middle range is more likely 
            // the first one to use
            if (m_utilUpperWeightRange_[length].m_count_ > 0) {
                ranges[rangeCount] 
		    = new WeightRange(m_utilUpperWeightRange_[length]);
                ++ rangeCount;
            }
            if (m_utilLowerWeightRange_[length].m_count_ > 0) {
                ranges[rangeCount] 
		    = new WeightRange(m_utilLowerWeightRange_[length]);
                ++ rangeCount;
            }
        }
        return rangeCount;
    }
    
    /**
     * Truncates the weight with length
     * @param weight
     * @param length
     * @return truncated weight
     */
    private static final int truncateWeight(int weight, int length) 
    {
        return weight & (0xffffffff << ((4 - length) << 3));
    }
    
    /**
     * Length of the weight
     * @param weight
     * @return length of the weight
     */
    private static final int lengthOfWeight(int weight) 
    {
        if ((weight & 0xffffff) == 0) {
            return 1;
        } 
        else if ((weight & 0xffff) == 0) {
            return 2;
        } 
        else if ((weight & 0xff) == 0) {
            return 3;
        } 
        return 4;
    }
    
    /**
     * Increment the weight trail
     * @param weight 
     * @param length
     * @return new weight
     */
    private static final int incWeightTrail(int weight, int length) 
    {
        return weight + (1 << ((4-length) << 3));
    }

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

    /**
     * Finds a contraction ce
     * @param table
     * @param element
     * @param ch
     * @return ce
     */
    private static int findCE(ContractionTable table, int element, char ch) 
    {
        if (table == null) {
            return CE_NOT_FOUND_;
        }
        BasicContractionTable tbl = getBasicContractionTable(table, element);
        if (tbl == null) {
            return CE_NOT_FOUND_;
        }
        int position = findCP(tbl, ch);
        if (position > tbl.m_CEs_.size() || position < 0) {
            return CE_NOT_FOUND_;
        } 
        return ((Integer)tbl.m_CEs_.get(position)).intValue();
    }    
    
    /**
     * Checks if the string is tailored in the contraction
     * @param table contraction table
     * @param element 
     * @param array character array to check
     * @param offset array offset
     * @return true if it is tailored
     */
    private static boolean isTailored(ContractionTable table, int element, 
                                      char array[], int offset) 
    {
        while (array[offset] != 0) {
            element = findCE(table, element, array[offset]);
            if (element == CE_NOT_FOUND_) {
                return false;
            }
            if (!isContractionTableElement(element)) {
                return true;
            }
            offset ++;
        }
        if (getCE(table, element, 0) != CE_NOT_FOUND_) {
            return true;
        } 
        else {
            return false; 
        }
    }
    
    /**
     * Assemble RuleBasedCollator
     * @param t build table
     * @param collator to update
     */
    private void assembleTable(BuildTable t, RuleBasedCollator collator) 
    {
        IntTrieBuilder mapping = t.m_mapping_;
        Vector expansions = t.m_expansions_;
        ContractionTable contractions = t.m_contractions_;
        MaxExpansionTable maxexpansion = t.m_maxExpansions_;
        
        // contraction offset has to be in since we are building on the 
        // UCA contractions 
        // int beforeContractions = (HEADER_SIZE_ 
        //                         + paddedsize(expansions.size() << 2)) >>> 1;
        collator.m_contractionOffset_ = 0;
        int contractionsSize = constructTable(contractions);
        
        // the following operation depends on the trie data. Therefore, we have 
        // to do it before the trie is compacted 
        // sets jamo expansions
        getMaxExpansionJamo(mapping, maxexpansion, t.m_maxJamoExpansions_,
                            collator.m_isJamoSpecial_);
        
        // TODO: LATIN1 array is now in the utrie - it should be removed from 
        // the calculation
        setAttributes(collator, t.m_options_);
        // copy expansions
        int size = expansions.size();
        collator.m_expansion_ = new int[size];
        for (int i = 0; i < size; i ++) {
            collator.m_expansion_[i] = ((Integer)expansions.get(i)).intValue();
        }
        // contractions block 
        if (contractionsSize != 0) {
            // copy contraction index 
            collator.m_contractionIndex_ = new char[contractionsSize];
            contractions.m_codePoints_.getChars(0, contractionsSize, 
                                                collator.m_contractionIndex_, 
                                                0);
            // copy contraction collation elements
            collator.m_contractionCE_ = new int[contractionsSize];
            for (int i = 0; i < contractionsSize; i ++) {
                collator.m_contractionCE_[i] = ((Integer)
						contractions.m_CEs_.get(i)).intValue();
            }
        }
        // copy mapping table
        collator.m_trie_ = mapping.serialize(t, 
					     RuleBasedCollator.DataManipulate.getInstance());
        // copy max expansion table
        // not copying the first element which is a dummy
        // to be in synch with icu4c's builder, we continue to use the 
        // expansion offset
        // omitting expansion offset in builder
        collator.m_expansionOffset_ = 0; 
        size = maxexpansion.m_endExpansionCE_.size();
        collator.m_expansionEndCE_ = new int[size - 1];
        for (int i = 1; i < size; i ++) {
            collator.m_expansionEndCE_[i - 1] = ((Integer)
						 maxexpansion.m_endExpansionCE_.get(i)).intValue();
        }
        collator.m_expansionEndCEMaxSize_ = new byte[size - 1];
        for (int i = 1; i < size; i ++) {
            collator.m_expansionEndCEMaxSize_[i - 1] 
		= ((Byte)maxexpansion.m_expansionCESize_.get(i)).byteValue();
        }
        // Unsafe chars table.  Finish it off, then copy it.
        unsafeCPAddCCNZ(t);
        // Or in unsafebits from UCA, making a combined table.
        for (int i = 0; i < UNSAFECP_TABLE_SIZE_; i ++) {    
	    t.m_unsafeCP_[i] |= RuleBasedCollator.UCA_.m_unsafe_[i];
        }
        collator.m_unsafe_ = t.m_unsafeCP_;
    
        // Finish building Contraction Ending chars hash table and then copy it 
        // out.
        // Or in unsafebits from UCA, making a combined table
        for (int i = 0; i < UNSAFECP_TABLE_SIZE_; i ++) {    
	    t.m_contrEndCP_[i] |= RuleBasedCollator.UCA_.m_contractionEnd_[i];
        }
        collator.m_contractionEnd_ = t.m_contrEndCP_;
    }
    
    /**
     * Sets this collator to use the all options and tables in UCA. 
     * @param collator which attribute is to be set 
     * @param option to set with
     */
    private static final void setAttributes(RuleBasedCollator collator,
					    CollationRuleParser.OptionSet option)
    {
        collator.latinOneFailed_ = true;
        collator.m_caseFirst_ = option.m_caseFirst_;
        collator.setDecomposition(option.m_decomposition_);
        collator.setAlternateHandlingShifted(
					     option.m_isAlternateHandlingShifted_);
        collator.setCaseLevel(option.m_isCaseLevel_);
        collator.setFrenchCollation(option.m_isFrenchCollation_);
        collator.m_isHiragana4_ = option.m_isHiragana4_;
        collator.setStrength(option.m_strength_);
        collator.m_variableTopValue_ = option.m_variableTopValue_;    
        collator.latinOneFailed_ = false;
    }
    
    /**
     * Constructing the contraction table
     * @param table contraction table
     * @return 
     */
    private int constructTable(ContractionTable table) 
    {
        // See how much memory we need 
        int tsize = table.m_elements_.size();
        if (tsize == 0) {
            return 0;
        }
        table.m_offsets_.clear();
        int position = 0;
        for (int i = 0; i < tsize; i ++) {
            table.m_offsets_.add(new Integer(position));
            position += ((BasicContractionTable)
			 table.m_elements_.get(i)).m_CEs_.size();
        }
        table.m_CEs_.clear();
        table.m_codePoints_.delete(0, table.m_codePoints_.length());
        // Now stuff the things in
        StringBuffer cpPointer = table.m_codePoints_;
        Vector CEPointer = table.m_CEs_;
        for (int i = 0; i < tsize; i ++) {
            BasicContractionTable bct = (BasicContractionTable)
		table.m_elements_.get(i);
            int size = bct.m_CEs_.size();
            char ccMax = 0;
            char ccMin = 255;
            int offset = CEPointer.size();
            CEPointer.add(bct.m_CEs_.get(0));
            for (int j = 1; j < size; j ++) {
                char ch = bct.m_codePoints_.charAt(j);
                char cc = (char)(UCharacter.getCombiningClass(ch) & 0xFF);
                if (cc > ccMax) {
                    ccMax = cc;
                }
                if (cc < ccMin) {
                    ccMin = cc;
                }
                cpPointer.append(ch);
                CEPointer.add(bct.m_CEs_.get(j));
            }
            cpPointer.insert(offset, 
                             (char)(((ccMin == ccMax) ? 1 : 0 << 8) | ccMax));
            for (int j = 0; j < size; j ++) {
                if (isContractionTableElement(((Integer)
					       CEPointer.get(offset + j)).intValue())) {
                    int ce = ((Integer)CEPointer.get(offset + j)).intValue();
                    CEPointer.set(offset + j, 
				  new Integer(constructSpecialCE(getCETag(ce), 
								 ((Integer)table.m_offsets_.get(
												getContractionOffset(ce))).intValue())));
                }
            }
        }
    
        for (int i = 0; i <= 0x10FFFF; i ++) {
            int CE = table.m_mapping_.getValue(i);
            if (isContractionTableElement(CE)) {
                CE = constructSpecialCE(getCETag(CE), 
                                        ((Integer)table.m_offsets_.get(
								       getContractionOffset(CE))).intValue());
                table.m_mapping_.setValue(i, CE);
            }
        }
        return position;
    }
    
    /**
     * Get contraction offset
     * @param ce collation element 
     * @return contraction offset
     */
    private static final int getContractionOffset(int ce)
    {
        return ce & 0xFFFFFF;
    }
    
    /**
     * Gets the maximum Jamo expansion
     * @param 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 els = t.m_prefixLookup_.elements();
            while (els.hasMoreElements()) {
                Elements e = (Elements)els.nextElement();
                // codepoints here are in the NFD form. We need to add the
                // first code point of the NFC form to unsafe, because 
                // strcoll needs to backup over them.
                // weiv: This is wrong! See the comment above.
                //String decomp = Normalizer.decompose(e.m_cPoints_, true);
                //unsafeCPSet(t.m_unsafeCP_, decomp.charAt(0));
                // it should be:
                String comp = Normalizer.compose(e.m_cPoints_, false);
                unsafeCPSet(t.m_unsafeCP_, comp.charAt(0));
            } 
        }
    }
    
    /**
     * Create closure
     * @param t build table
     * @param collator RuleBasedCollator
     * @param colEl collation element iterator
     * @param start 
     * @param limit
     * @param type character type
     * @return 
     */
    private boolean enumCategoryRangeClosureCategory(BuildTable t, 
						     RuleBasedCollator collator, 
						     CollationElementIterator colEl, 
						     int start, int limit, int type) 
    {
        if (type != UCharacterCategory.UNASSIGNED 
            && type != UCharacterCategory.PRIVATE_USE) { 
            // if the range is assigned - we might ommit more categories later
            
            for (int u32 = start; u32 < limit; u32 ++) {
                int noOfDec = NormalizerImpl.getDecomposition(u32, false,
                                                              m_utilCharBuffer_, 
                                                              0, 256);
                if (noOfDec > 0) {
                    // if we're positive, that means there is no decomposition
                    String comp = UCharacter.toString(u32);
                    String decomp = new String(m_utilCharBuffer_, 0, noOfDec);
                    if (!collator.equals(comp, decomp)) {
                        m_utilElement_.m_cPoints_ = decomp;
                        m_utilElement_.m_prefix_ = 0;
                        Elements prefix 
			    = (Elements)t.m_prefixLookup_.get(m_utilElement_);
                        if (prefix == null) {
                            m_utilElement_.m_cPoints_ = comp;
                            m_utilElement_.m_prefix_ = 0;
                            m_utilElement_.m_prefixChars_ = null;
                            colEl.setText(decomp);
                            int ce = colEl.next();
                            m_utilElement_.m_CELength_ = 0;
                            while (ce != CollationElementIterator.NULLORDER) {
                                m_utilElement_.m_CEs_[
						      m_utilElement_.m_CELength_ ++] 
				    = ce;
                                ce = colEl.next();
                            }
                        } 
                        else {
                            m_utilElement_.m_cPoints_ = comp;
                            m_utilElement_.m_prefix_ = 0;
                            m_utilElement_.m_prefixChars_ = null;
                            m_utilElement_.m_CELength_ = 1;
                            m_utilElement_.m_CEs_[0] = prefix.m_mapCE_;
                            // This character uses a prefix. We have to add it 
                            // to the unsafe table, as it decomposed form is 
                            // already in. In Japanese, this happens for \u309e 
                            // & \u30fe
                            // Since unsafeCPSet is static in ucol_elm, we are 
                            // going to wrap it up in the unsafeCPAddCCNZ 
                            // function
                            m_utilElement_.m_isThai_ 
				= CollationElementIterator.isThaiPreVowel(
									  m_utilElement_.m_cPoints_.charAt(0));
                        }
                        addAnElement(t, m_utilElement_);
                    }
                }
            }
        }
        return true;
    }
    
    /**
     * Determine if a character is a Jamo
     * @param ch character to test
     * @return true if ch is a Jamo, false otherwise
     */
    private static final boolean isJamo(char ch)
    { 
	return (ch >= 0x1100 && ch <= 0x1112) 
	    || (ch >= 0x1175 && ch <= 0x1161) 
	    || (ch >= 0x11A8 && ch <= 0x11C2);
    }
    
    /**
     * Produces canonical closure
     */
    private void canonicalClosure(BuildTable t) 
    {
        BuildTable temp = new BuildTable(t);
        assembleTable(temp, temp.m_collator_);
        // produce canonical closure 
        CollationElementIterator coleiter 
	    = temp.m_collator_.getCollationElementIterator("");
        RangeValueIterator typeiter = UCharacter.getTypeIterator();
        RangeValueIterator.Element element = new RangeValueIterator.Element();
        while (typeiter.next(element)) {
            enumCategoryRangeClosureCategory(t, temp.m_collator_, coleiter, 
					     element.start, element.limit, 
					     element.value);
        }
    }
    
    private void processUCACompleteIgnorables(BuildTable t) 
    {
        TrieIterator trieiterator 
	    = new TrieIterator(RuleBasedCollator.UCA_.m_trie_);
        RangeValueIterator.Element element = new RangeValueIterator.Element();
        while (trieiterator.next(element)) {
            int start = element.start;
            int limit = element.limit;
            if (element.value == 0) {
                while (start < limit) {
                    int CE = t.m_mapping_.getValue(start);
                    if (CE == CE_NOT_FOUND_) {
                        m_utilElement_.m_isThai_ = false;
                        m_utilElement_.m_prefix_ = 0;
                        m_utilElement_.m_uchars_ = UCharacter.toString(start);
                        m_utilElement_.m_cPoints_ = m_utilElement_.m_uchars_;
                        m_utilElement_.m_cPointsOffset_ = 0;
                        m_utilElement_.m_CELength_ = 1;
                        m_utilElement_.m_CEs_[0] = 0;
                        addAnElement(t, m_utilElement_);
                    }
                    start ++;
                }
            }
        }
    }
}
