 /*
 *******************************************************************************
 * Copyright (C) 1996-2003, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/impl/NormalizerImpl.java,v $
 * $Date: 2003/06/09 23:31:09 $
 * $Revision: 1.22 $
 *******************************************************************************
 */
 
package com.ibm.icu.impl;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.BufferedInputStream;
import java.io.InputStream;

import com.ibm.icu.text.Normalizer;
import com.ibm.icu.text.UTF16;	
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.text.UnicodeSetIterator;
import com.ibm.icu.util.RangeValueIterator;
import com.ibm.icu.lang.UCharacter;

/**
 * @version 	1.0
 * @author  Ram Viswanadha
 */
public final class NormalizerImpl {
	// Static block for the class to initialize its own self 
	static final NormalizerImpl IMPL;
	
	static
    {
        try
        {
            IMPL = new NormalizerImpl();
        }
        catch (Exception e)
        {
            throw new RuntimeException(e.getMessage());
        }
    }
	
	static final int UNSIGNED_BYTE_MASK =0xFF;
	static final long UNSIGNED_INT_MASK = 0xffffffffL;
	/*
	 * This new implementation of the normalization code loads its data from
	 * unorm.icu, which is generated with the gennorm tool.
	 * The format of that file is described at the end of this file.
	 */
	private static final String DATA_FILE_NAME = "data/unorm.icu";
	
	// norm32 value constants 
	
    // quick check flags 0..3 set mean "no" for their forms 
    public static final int QC_NFC=0x11;          /* no|maybe */
    public static final int QC_NFKC=0x22;         /* no|maybe */
    public static final int QC_NFD=4;             /* no */
    public static final int QC_NFKD=8;            /* no */
	
    public static final int QC_ANY_NO=0xf;

    /* quick check flags 4..5 mean "maybe" for their forms; 
     * test flags>=QC_MAYBE 
     */
    public static final int QC_MAYBE=0x10;
    public static final int QC_ANY_MAYBE=0x30;

    public static final int QC_MASK=0x3f;

    private static final int COMBINES_FWD=0x40;
    private static final int COMBINES_BACK=0x80;
    public  static final int COMBINES_ANY=0xc0;
    // UnicodeData.txt combining class in bits 15.
    private static final int CC_SHIFT=8;           		  
    public  static final int CC_MASK=0xff00;
    // 16 bits for the index to UChars and other extra data
    private static final int EXTRA_SHIFT=16;
    // start of surrogate specials after shift                
    private static final int EXTRA_INDEX_TOP=0xfc00;       

    private static final int EXTRA_SURROGATE_MASK=0x3ff;
    private static final int EXTRA_SURROGATE_TOP=0x3f0;    /* hangul etc. */

    private static final int EXTRA_HANGUL=EXTRA_SURROGATE_TOP;
    private static final int EXTRA_JAMO_L=EXTRA_SURROGATE_TOP+1;/* ### not used */
    private static final int EXTRA_JAMO_V=EXTRA_SURROGATE_TOP+2;
    private static final int EXTRA_JAMO_T=EXTRA_SURROGATE_TOP+3;
	
	/* norm32 value constants using >16 bits */
	private static final long  MIN_SPECIAL    =  (long)(0xfc000000 & UNSIGNED_INT_MASK);
	private static final long  SURROGATES_TOP =  (long)(0xfff00000 & UNSIGNED_INT_MASK);
	private static final long  MIN_HANGUL     =  (long)(0xfff00000 & UNSIGNED_INT_MASK);
	private static final long  MIN_JAMO_V     =  (long)(0xfff20000 & UNSIGNED_INT_MASK);
	private static final long  JAMO_V_TOP     =  (long)(0xfff30000 & UNSIGNED_INT_MASK);
	
	
	/* indexes[] value names */
	/* number of bytes in normalization trie */
	static final int INDEX_TRIE_SIZE 		  = 0;
     /* number of chars in extra data */     
	static final int INDEX_CHAR_COUNT 		  = 1;    
	/* number of uint16_t words for combining data */
	static final int INDEX_COMBINE_DATA_COUNT = 2;
    /* number of code points that combine forward */     
	static final int INDEX_COMBINE_FWD_COUNT  = 3;
    /* number of code points that combine forward and backward */     
	static final int INDEX_COMBINE_BOTH_COUNT = 4;
    /* number of code points that combine backward */     
	static final int INDEX_COMBINE_BACK_COUNT = 5;     
	 /* first code point with quick check NFC NO/MAYBE */
	public static final int INDEX_MIN_NFC_NO_MAYBE   = 6;
    /* first code point with quick check NFKC NO/MAYBE */    
	public static final int INDEX_MIN_NFKC_NO_MAYBE  = 7;
     /* first code point with quick check NFD NO/MAYBE */     
	public static final int INDEX_MIN_NFD_NO_MAYBE   = 8;
    /* first code point with quick check NFKD NO/MAYBE */    
	public static final int INDEX_MIN_NFKD_NO_MAYBE  = 9;     
	/* number of bytes in FCD trie */
	static final int INDEX_FCD_TRIE_SIZE      = 10;
    /* number of bytes in the auxiliary trie */    
    static final int INDEX_AUX_TRIE_SIZE      = 11;
    /* number of uint16_t in the array of serialized USet */    
    static final int INDEX_CANON_SET_COUNT    = 12;    
    /* changing this requires a new formatVersion */
	static final int INDEX_TOP                = 32;    
	
	
	/* AUX constants */
	/* value constants for auxTrie */	
	private static final int AUX_UNSAFE_SHIFT	       = 11;
	private static final int AUX_COMP_EX_SHIFT	       = 10;
    private static final int AUX_NFC_SKIPPABLE_F_SHIFT = 12;
	
	private static final int AUX_MAX_FNC          =   ((int)1<<AUX_COMP_EX_SHIFT);
	private static final int AUX_UNSAFE_MASK      =   (int)((1<<AUX_UNSAFE_SHIFT) & UNSIGNED_INT_MASK);
	private static final int AUX_FNC_MASK         =   (int)((AUX_MAX_FNC-1) & UNSIGNED_INT_MASK);
	private static final int AUX_COMP_EX_MASK     =   (int)((1<<AUX_COMP_EX_SHIFT) & UNSIGNED_INT_MASK);
	private static final long AUX_NFC_SKIP_F_MASK =   ((UNSIGNED_INT_MASK&1)<<AUX_NFC_SKIPPABLE_F_SHIFT);
    
	/* canonStartSets[0..31] contains indexes for what is in the array */
    /* number of uint16_t in canonical starter sets */
    static final int SET_INDEX_CANON_SETS_LENGTH		= 0;
    /* number of uint16_t in the BMP search table (contains pairs) */ 
    static final int SET_INDEX_CANON_BMP_TABLE_LENGTH	= 1;
    /* number of uint16_t in the supplementary search table(contains triplets)*/ 
    static final int SET_INDEX_CANON_SUPP_TABLE_LENGTH  = 2;
    /* changing this requires a new formatVersion */ 
    static final int SET_INDEX_TOP						= 32;
	
	static final int CANON_SET_INDICIES_INDEX  			= 0;
	static final int CANON_SET_START_SETS_INDEX			= 1;
	static final int CANON_SET_BMP_TABLE_INDEX			= 2;
	static final int CANON_SET_SUPP_TABLE_INDEX			= 3;
	/* 14 bit indexes to canonical USerializedSets */
	static final int CANON_SET_MAX_CANON_SETS     		= 0x4000; 
	/* single-code point BMP sets are encoded directly in the search table 
     * except if result=0x4000..0x7fff 
     */
	static final int CANON_SET_BMP_MASK        			= 0xc000;
	static final int CANON_SET_BMP_IS_INDEX    			= 0x4000;
    
    private static final int MAX_BUFFER_SIZE                    = 20;
	
    /**
	 * Internal option for cmpEquivFold() for decomposing.
	 * If not set, just do strcasecmp().
	 * @internal
	 */
	 public static final int COMPARE_EQUIV = 0x80000;
	
	/*******************************/

	/* Wrappers for Trie implementations */ 
	static final class NormTrieImpl implements Trie.DataManipulate{
		static IntTrie normTrie= null;
	   /**
	    * Called by com.ibm.icu.util.Trie to extract from a lead surrogate's 
	    * data the index array offset of the indexes for that lead surrogate.
	    * @param property data value for a surrogate from the trie, including 
        *         the folding offset
	    * @return data offset or 0 if there is no data for the lead surrogate
	    */
        /* normTrie: 32-bit trie result may contain a special extraData index with the folding offset */
	    public int getFoldingOffset(int value){
            return  BMP_INDEX_LENGTH+
                    ((value>>(EXTRA_SHIFT-SURROGATE_BLOCK_BITS))&
                    (0x3ff<<SURROGATE_BLOCK_BITS)); 
	    }
		
	}
	static final class FCDTrieImpl implements Trie.DataManipulate{
		static CharTrie fcdTrie=null;
	   /**
	    * Called by com.ibm.icu.util.Trie to extract from a lead surrogate's 
	    * data the index array offset of the indexes for that lead surrogate.
	    * @param property data value for a surrogate from the trie, including
        *         the folding offset
	    * @return data offset or 0 if there is no data for the lead surrogate
	    */
        /* fcdTrie: the folding offset is the lead FCD value itself */
	    public int getFoldingOffset(int value){
			return value;
	    }
	}
	
	static final class AuxTrieImpl implements Trie.DataManipulate{
		static CharTrie auxTrie = null;
	   /**
	    * Called by com.ibm.icu.util.Trie to extract from a lead surrogate's 
	    * data the index array offset of the indexes for that lead surrogate.
	    * @param property data value for a surrogate from the trie, including 
        *        the folding offset
	    * @return data offset or 0 if there is no data for the lead surrogate
	    */
        /* auxTrie: the folding offset is in bits 9..0 of the 16-bit trie result */
	    public int getFoldingOffset(int value){
	        return (int)(value &AUX_FNC_MASK)<<SURROGATE_BLOCK_BITS;
	    }
	}
		 
	/****************************************************/
	
	
	static FCDTrieImpl fcdTrieImpl;
	static NormTrieImpl normTrieImpl;
	static AuxTrieImpl auxTrieImpl;
	private static int[] indexes;
	static char[] combiningTable;
	static char[] extraData;
	static Object[] canonStartSets;
	
	static boolean isDataLoaded;
	static boolean isFormatVersion_2_1;
    static boolean isFormatVersion_2_2;
	/**
     * Default buffer size of datafile
     */
    private static final int DATA_BUFFER_SIZE = 25000;
	
	/**
     * FCD check: everything below this code point is known to have a 0 
     * lead combining class 
     */
	public static final int MIN_WITH_LEAD_CC=0x300;


    /**
     * Bit 7 of the length byte for a decomposition string in extra data is
     * a flag indicating whether the decomposition string is
     * preceded by a 16-bit word with the leading and trailing cc
     * of the decomposition (like for A-umlaut);
     * if not, then both cc's are zero (like for compatibility ideographs).
     */
	private static final int DECOMP_FLAG_LENGTH_HAS_CC=0x80;
    /**
	 * Bits 6..0 of the length byte contain the actual length.
	 */
	private static final int DECOMP_LENGTH_MASK=0x7f;   
	
	/** Length of the BMP portion of the index (stage 1) array. */
    private static final int BMP_INDEX_LENGTH=0x10000>>Trie.INDEX_STAGE_1_SHIFT_;
    /** Number of bits of a trail surrogate that are used in index table 
     * lookups. 
     */
    private static final int SURROGATE_BLOCK_BITS=10-Trie.INDEX_STAGE_1_SHIFT_;


   // public utility
   public static int getFromIndexesArr(int index){
        return indexes[index];
   }
   
   // protected constructor ---------------------------------------------
    
    /**
    * Constructor
    * @exception thrown when data reading fails or data corrupted
    */
    private NormalizerImpl() throws IOException{
        //data should be loaded only once
        if(!isDataLoaded){
            
            // jar access
            InputStream i = getClass().getResourceAsStream(DATA_FILE_NAME);
            BufferedInputStream b = new BufferedInputStream(i,DATA_BUFFER_SIZE);
            NormalizerDataReader reader = new NormalizerDataReader(b);
            
            // read the indexes            
            indexes = reader.readIndexes(NormalizerImpl.INDEX_TOP);
            
            byte[] normBytes = new byte[indexes[NormalizerImpl.INDEX_TRIE_SIZE]];
            
            int combiningTableTop = indexes[NormalizerImpl.INDEX_COMBINE_DATA_COUNT];
            combiningTable = new char[combiningTableTop];
            
            int extraDataTop = indexes[NormalizerImpl.INDEX_CHAR_COUNT];
            extraData = new char[extraDataTop];

            byte[] fcdBytes = new byte[indexes[NormalizerImpl.INDEX_FCD_TRIE_SIZE]];
            byte[] auxBytes = new byte[indexes[NormalizerImpl.INDEX_AUX_TRIE_SIZE]];
            canonStartSets=new Object[NormalizerImpl.CANON_SET_MAX_CANON_SETS];
            
            fcdTrieImpl = new FCDTrieImpl();
            normTrieImpl = new NormTrieImpl();
            auxTrieImpl = new AuxTrieImpl();
                        

            // load the rest of the data data and initialize the data members
            reader.read(normBytes, fcdBytes,auxBytes, extraData, combiningTable, 
                        canonStartSets);
                                       
            NormTrieImpl.normTrie = new IntTrie( new ByteArrayInputStream(normBytes),normTrieImpl );
            FCDTrieImpl.fcdTrie   = new CharTrie( new ByteArrayInputStream(fcdBytes),fcdTrieImpl  );
            AuxTrieImpl.auxTrie   = new CharTrie( new ByteArrayInputStream(auxBytes),auxTrieImpl  );
            
            // we reached here without any exceptions so the data is fully 
            // loaded set the variable to true
            isDataLoaded = true;
            
            // get the data format version                           
            byte[] formatVersion = reader.getDataFormatVersion();
            
            isFormatVersion_2_1 =( formatVersion[0]>2 
                                    ||
                                   (formatVersion[0]==2 && formatVersion[1]>=1)
                                 );
            isFormatVersion_2_2 =( formatVersion[0]>2 
                                    ||
                                   (formatVersion[0]==2 && formatVersion[1]>=2)
                                 );
            
            b.close();
            i.close();
        }
    }
        
	/* ---------------------------------------------------------------------- */
	
	/* Korean Hangul and Jamo constants */
	
	public static final int JAMO_L_BASE=0x1100;     /* "lead" jamo */
	public static final int JAMO_V_BASE=0x1161;     /* "vowel" jamo */
	public static final int JAMO_T_BASE=0x11a7;     /* "trail" jamo */
	
	public static final int HANGUL_BASE=0xac00;
	
	public static final int JAMO_L_COUNT=19;
	public static final int JAMO_V_COUNT=21;
	public static final int JAMO_T_COUNT=28;
	public  static final int HANGUL_COUNT=JAMO_L_COUNT*JAMO_V_COUNT*JAMO_T_COUNT;
	
	private static boolean isHangulWithoutJamoT(char c) {
	    c-=HANGUL_BASE;
	    return c<HANGUL_COUNT && c%JAMO_T_COUNT==0;
	}
	
	/* norm32 helpers */
	
	/* is this a norm32 with a regular index? */
	private static boolean isNorm32Regular(long norm32) {
	    return norm32<MIN_SPECIAL;
	}
	
	/* is this a norm32 with a special index for a lead surrogate? */
	private static boolean isNorm32LeadSurrogate(long norm32) {
	    return MIN_SPECIAL<=norm32 && norm32<SURROGATES_TOP;
	}
	
	/* is this a norm32 with a special index for a Hangul syllable or a Jamo? */
	private static boolean isNorm32HangulOrJamo(long norm32) {
	    return norm32>=MIN_HANGUL;
	}
	
	/*
	 * Given isNorm32HangulOrJamo(),
	 * is this a Hangul syllable or a Jamo?
	 */
     ///CLOVER:OFF
	private static  boolean isHangulJamoNorm32HangulOrJamoL(long norm32) {
	    return norm32<MIN_JAMO_V;
	}
    ///CLOVER:ON
	
	/*
	 * Given norm32 for Jamo V or T,
	 * is this a Jamo V?
	 */
	private static boolean isJamoVTNorm32JamoV(long norm32) {
	    return norm32<JAMO_V_TOP;
	}
	
	/* data access primitives ----------------------------------------------- */
	
	public static long/*unsigned*/ getNorm32(char c) {
        return ((UNSIGNED_INT_MASK) & (NormTrieImpl.normTrie.getLeadValue(c)));
	}
	
	public static long/*unsigned*/ getNorm32FromSurrogatePair(long norm32, 
                                                               char c2) {
	    /*
	     * the surrogate index in norm32 stores only the number of the surrogate
         * index block see gennorm/store.c/getFoldedNormValue()
	     */
	    return ((UNSIGNED_INT_MASK) & 
                    NormTrieImpl.normTrie.getTrailValue((int)norm32, c2));
	}
    ///CLOVER:OFF
	private static long getNorm32(int c){
        return (UNSIGNED_INT_MASK&(NormTrieImpl.normTrie.getCodePointValue(c)));
    }
    
    private static long getNorm32(int c,int mask){
        long/*unsigned*/ norm32= getNorm32(UTF16.getLeadSurrogate(c));
        if(((norm32&mask)>0) && isNorm32LeadSurrogate(norm32)) {
            /* c is a lead surrogate, get the real norm32 */
            norm32=getNorm32FromSurrogatePair(norm32,UTF16.getTrailSurrogate(c));
        }
        return norm32; 
    }
    ///CLOVER:ON
    
	
    /*
	 * get a norm32 from text with complete code points
	 * (like from decompositions)
	 */
	private static long/*unsigned*/ getNorm32(char[] p,int start,
                                              int/*unsigned*/ mask) {
	    long/*unsigned*/ norm32= getNorm32(p[start]);
	    if(((norm32&mask)>0) && isNorm32LeadSurrogate(norm32)) {
	        /* *p is a lead surrogate, get the real norm32 */
	        norm32=getNorm32FromSurrogatePair(norm32, p[start+1]);
	    }
	    return norm32;
	}

	public static char	getFCD16(char c) {
	    return  FCDTrieImpl.fcdTrie.getLeadValue(c);
	}
	
	public static char getFCD16FromSurrogatePair(char fcd16, char c2) {
	    /* the surrogate index in fcd16 is an absolute offset over the 
         * start of stage 1 
         * */
	    return FCDTrieImpl.fcdTrie.getTrailValue(fcd16, c2);
	}
    public static int getFCD16(int c) {
        return  FCDTrieImpl.fcdTrie.getCodePointValue(c);
    }
    	
	private static int getExtraDataIndex(long norm32) {
	    return (int)(norm32>>EXTRA_SHIFT);
	}
	
	private static final class DecomposeArgs{
		int /*unsigned byte*/ cc;
		int /*unsigned byte*/ trailCC;
		int length;
	}
    /**
     * 
     * get the canonical or compatibility decomposition for one character 
     * 
     * @return index into the extraData array
     */
    private static int/*index*/ decompose(long/*unsigned*/ norm32, 
    							          int/*unsigned*/ qcMask, 
    							          DecomposeArgs args) {
        int p= getExtraDataIndex(norm32);
        args.length=extraData[p++];
    
        if((norm32&qcMask&QC_NFKD)!=0 && args.length>=0x100) {
            /* use compatibility decomposition, skip canonical data */
            p+=((args.length>>7)&1)+(args.length&DECOMP_LENGTH_MASK);
            args.length>>=8;
        }
    
        if((args.length&DECOMP_FLAG_LENGTH_HAS_CC)>0) {
            /* get the lead and trail cc's */
            char bothCCs=extraData[p++];
            args.cc=(UNSIGNED_BYTE_MASK) & (bothCCs>>8);
            args.trailCC=(UNSIGNED_BYTE_MASK) & bothCCs;
        } else {
            /* lead and trail cc's are both 0 */
            args.cc=args.trailCC=0;
        }
    
        args.length&=DECOMP_LENGTH_MASK;
        return p;
    }
    
       
    /**
     * get the canonical decomposition for one character 
     * @return index into the extraData array
     */
    private static int decompose(long/*unsigned*/ norm32, 
            			         DecomposeArgs args) {
            			 	
        int p= getExtraDataIndex(norm32);
        args.length=extraData[p++];
    
        if((args.length&DECOMP_FLAG_LENGTH_HAS_CC)>0) {
            /* get the lead and trail cc's */
            char bothCCs=extraData[p++];
            args.cc=(UNSIGNED_BYTE_MASK) & (bothCCs>>8);
            args.trailCC=(UNSIGNED_BYTE_MASK) & bothCCs;
        } else {
            /* lead and trail cc's are both 0 */
            args.cc=args.trailCC=0;
        }
    
        args.length&=DECOMP_LENGTH_MASK;
        return p;
    }
    
    
    private static final class NextCCArgs{
    	char[] source;
    	int next;
    	int limit;
    	char c;
    	char c2;
    }
    
    /*
     * get the combining class of (c, c2)= args.source[args.next++]
     * before: args.next<args.limit  after: args.next<=args.limit
     * if only one code unit is used, then c2==0
     */
    private static int /*unsigned byte*/ getNextCC(NextCCArgs args) {
        long /*unsigned*/ norm32;
    
        args.c=args.source[args.next++];
        
        norm32= getNorm32(args.c);
        if((norm32 & CC_MASK)==0) {
            args.c2=0;
            return 0;
        } else {
            if(!isNorm32LeadSurrogate(norm32)) {
                args.c2=0;
            } else {
                /* c is a lead surrogate, get the real norm32 */
                if(args.next!=args.limit && 
                        UTF16.isTrailSurrogate(args.c2=args.source[args.next])){
                    ++args.next;
                    norm32=getNorm32FromSurrogatePair(norm32, args.c2);
                } else {
                    args.c2=0;
                    return 0;
                }
            }
    
            return (int)((UNSIGNED_BYTE_MASK) & (norm32>>CC_SHIFT));
        }
    }

	private static final class PrevArgs{
		char[] src;
		int start;
		int current;
		char c;
		char c2;
	}
	
    /*
     * read backwards and get norm32
     * return 0 if the character is <minC
     * if c2!=0 then (c2, c) is a surrogate pair (reversed - c2 is first 
     * surrogate but read second!)
     */
    private static long /*unsigned*/ getPrevNorm32(PrevArgs args,
                   						           int/*unsigned*/ minC, 
                   						           int/*unsigned*/ mask) {
        long/*unsigned*/ norm32;
    
        args.c=args.src[--args.current];
        args.c2=0;
    
        /* check for a surrogate before getting norm32 to see if we need to 
         * predecrement further 
         */
        if(args.c<minC) {
            return 0;
        } else if(!UTF16.isSurrogate(args.c)) {
            return getNorm32(args.c);
        } else if(UTF16.isLeadSurrogate(args.c)) {
            /* unpaired first surrogate */
            return 0;
        } else if(args.current!=args.start && 
                    UTF16.isLeadSurrogate(args.c2=args.src[args.current-1])) {
            --args.current;
            norm32=getNorm32(args.c2);
    
            if((norm32&mask)==0) {
                /* all surrogate pairs with this lead surrogate have 
                 * only irrelevant data 
                 */
                return 0;
            } else {
                /* norm32 must be a surrogate special */
                return getNorm32FromSurrogatePair(norm32, args.c);
            }
        } else {
            /* unpaired second surrogate */
            args.c2=0;
            return 0;
        }
    }
    
    /*
     * get the combining class of (c, c2)=*--p
     * before: start<p  after: start<=p
     */
    private static int /*unsigned byte*/ getPrevCC(PrevArgs args) {

        return (int)((UNSIGNED_BYTE_MASK)&(getPrevNorm32(args, MIN_WITH_LEAD_CC,
                                                         CC_MASK)>>CC_SHIFT));
    }

	/*
	 * is this a safe boundary character for NF*D?
	 * (lead cc==0)
	 */
	public static boolean isNFDSafe(long/*unsigned*/ norm32, 
                                     int/*unsigned*/ccOrQCMask, 
					                 int/*unsigned*/ decompQCMask) {
	    if((norm32&ccOrQCMask)==0) {
	        return true; /* cc==0 and no decomposition: this is NF*D safe */
	    }
	
	    /* inspect its decomposition - maybe a Hangul but not a surrogate here*/
	    if(isNorm32Regular(norm32) && (norm32&decompQCMask)!=0) {
	        DecomposeArgs args=new DecomposeArgs();
	        /* decomposes, get everything from the variable-length extra data */
	        decompose(norm32, decompQCMask, args);
	        return args.cc==0;
	    } else {
	        /* no decomposition (or Hangul), test the cc directly */
	        return (norm32&CC_MASK)==0;
	    }
	}
	
	/*
	 * is this (or does its decomposition begin with) a "true starter"?
	 * (cc==0 and NF*C_YES)
	 */
    public static boolean isTrueStarter(long/*unsigned*/ norm32, 
								          int/*unsigned*/ ccOrQCMask, 
								          int/*unsigned*/ decompQCMask) {
	    if((norm32&ccOrQCMask)==0) {
	        return true; /* this is a true starter (could be Hangul or Jamo L)*/
	    }
	
	    /* inspect its decomposition - not a Hangul or a surrogate here */
	    if((norm32&decompQCMask)!=0) {
	        int p; /* index into extra data array */
	        DecomposeArgs args=new DecomposeArgs();
	        /* decomposes, get everything from the variable-length extra data */
	        p=decompose(norm32, decompQCMask, args);
	      
	        if(args.cc==0) {
	            int/*unsigned*/ qcMask=ccOrQCMask&QC_MASK;
	
	            /* does it begin with NFC_YES? */
	            if((getNorm32(extraData,p, qcMask)&qcMask)==0) {
	                /* yes, the decomposition begins with a true starter */
	                return true;
	            }
	        }
	    }
	    return false;
	}

	/* reorder UTF-16 in-place ---------------------------------------------- */
	
	/**
	 * simpler, single-character version of mergeOrdered() -
	 * bubble-insert one single code point into the preceding string
	 * which is already canonically ordered
	 * (c, c2) may or may not yet have been inserted at src[current]..src[p]
	 *
	 * it must be p=current+lengthof(c, c2) i.e. p=current+(c2==0 ? 1 : 2)
	 *
	 * before: src[start]..src[current] is already ordered, and
	 *         src[current]..src[p]     may or may not hold (c, c2) but
	 *                          must be exactly the same length as (c, c2)
	 * after: src[start]..src[p] is ordered
	 *
	 * @return the trailing combining class
	 */
	private static int/*unsigned byte*/ insertOrdered(char[] source, 
                                                      int start, 
											          int current, int p,
	               							          char c, char c2, 
	               							          int/*unsigned byte*/ cc) {
	    int back, preBack;
	    int r;
	    int prevCC, trailCC=cc;
	
	    if(start<current && cc!=0) {
	        // search for the insertion point where cc>=prevCC 
	        preBack=back=current;
	        PrevArgs prevArgs = new PrevArgs();
	        prevArgs.current  = current;
	        prevArgs.start    = start;
	        prevArgs.src	  = source;
	        // get the prevCC 
	        prevCC=getPrevCC(prevArgs);
	        preBack = prevArgs.current;
	        
	        if(cc<prevCC) {
	            // this will be the last code point, so keep its cc 
	            trailCC=prevCC;
	            back=preBack;
	            while(start<preBack) {
	                prevCC=getPrevCC(prevArgs);
	                preBack=prevArgs.current;
	                if(cc>=prevCC) {
	                    break;
	                }
	                back=preBack;
	            }
	
	            
	            // this is where we are right now with all these indicies:
	            // [start]..[pPreBack] 0..? code points that we can ignore
	            // [pPreBack]..[pBack] 0..1 code points with prevCC<=cc
	            // [pBack]..[current] 0..n code points with >cc, move up to insert (c, c2)
	            // [current]..[p]         1 code point (c, c2) with cc
	             
	            // move the code units in between up 
	            r=p;
	            do {
	                source[--r]=source[--current];
	            } while(back!=current);
	        }
	    }
	
	    // insert (c, c2) 
	    source[current]=c;
	    if(c2!=0) {
	        source[(current+1)]=c2;
	    }
	
	    // we know the cc of the last code point 
	    return trailCC;
	}
	
	/**
	 * merge two UTF-16 string parts together
	 * to canonically order (order by combining classes) their concatenation
	 *
	 * the two strings may already be adjacent, so that the merging is done 
     * in-place if the two strings are not adjacent, then the buffer holding the
     * first one must be large enough
	 * the second string may or may not be ordered in itself
	 *
	 * before: [start]..[current] is already ordered, and
	 *         [next]..[limit]    may be ordered in itself, but
	 *                          is not in relation to [start..current[
	 * after: [start..current+(limit-next)[ is ordered
	 *
	 * the algorithm is a simple bubble-sort that takes the characters from 
     * src[next++] and inserts them in correct combining class order into the 
     * preceding part of the string
	 *
	 * since this function is called much less often than the single-code point
	 * insertOrdered(), it just uses that for easier maintenance
	 *
	 * @return the trailing combining class
	 */
	private static int /*unsigned byte*/ mergeOrdered(char[] source,
													  int start, 
													  int current,
		                                              char[] data,
			              							  int next, 
			              							  int limit, 
			              							  boolean isOrdered) {
            int r;
            int /*unsigned byte*/ cc, trailCC=0;
            boolean adjacent;
        
            adjacent= current==next;
            NextCCArgs ncArgs = new NextCCArgs();
            ncArgs.source = data;
            ncArgs.next   = next;
            ncArgs.limit  = limit;
            
            if(start!=current || !isOrdered) {
                	
                while(ncArgs.next<ncArgs.limit) {
                    cc=getNextCC(ncArgs);
                    if(cc==0) {
                        // does not bubble back 
                        trailCC=0;
                        if(adjacent) {
                            current=ncArgs.next;
                        } else {
                            data[current++]=ncArgs.c;
                            if(ncArgs.c2!=0) {
                                data[current++]=ncArgs.c2;
                            }
                        }
                        if(isOrdered) {
                            break;
                        } else {
                            start=current;
                        }
                    } else {
                        r=current+(ncArgs.c2==0 ? 1 : 2);
                        trailCC=insertOrdered(source,start, current, r, 
                                              ncArgs.c, ncArgs.c2, cc);
                        current=r;
                    }
                }
            }
        
            if(ncArgs.next==ncArgs.limit) {
                // we know the cc of the last code point 
                return trailCC;
            } else {
                if(!adjacent) {
                    // copy the second string part 
                    do {
                        source[current++]=data[ncArgs.next++];
                    } while(ncArgs.next!=ncArgs.limit);
                    ncArgs.limit=current;
                }
                PrevArgs prevArgs = new PrevArgs();
                prevArgs.src   = data;
                prevArgs.start = start;
                prevArgs.current =  ncArgs.limit;
                return getPrevCC(prevArgs);
            }

	}
	private static int /*unsigned byte*/ mergeOrdered(char[] source,
													  int start, 
													  int current,
		                                              char[] data,
			              							  final int next, 
			              							  final int limit) {
	    return mergeOrdered(source,start,current,data,next,limit,true);
	} 

    
      
    public static boolean checkFCD(char[] src,int srcStart, int srcLimit,
    							   UnicodeSet nx) {

	    char fcd16,c,c2;
	    int prevCC=0, cc;
		int i =srcStart, length = srcLimit;
	
	    for(;;) {
            for(;;) {
                if(i==length) {
                    return true;
                } else if((c=src[i++])<MIN_WITH_LEAD_CC) {
                    prevCC=(int)-c;
                } else if((fcd16=getFCD16(c))==0) {
                    prevCC=0;
                } else {
                    break;
                }
            }

	        // check one above-minimum, relevant code unit 
	        if(UTF16.isLeadSurrogate(c)) {
	            // c is a lead surrogate, get the real fcd16 
	            if(i!=length && UTF16.isTrailSurrogate(c2=src[i])) {
	                ++i;
	                fcd16=getFCD16FromSurrogatePair(fcd16, c2);
	            } else {
	            	c2=0;
	                fcd16=0;
	            }
	        }else{
	        	c2=0;
	        }
	        
	        if(nx_contains(nx, c, c2)) {
	            prevCC=0; /* excluded: fcd16==0 */
	            continue;
	        }

	        // prevCC has values from the following ranges:
	        // 0..0xff -the previous trail combining class
	        // <0      -the negative value of the previous code unit;
	        //          that code unit was <MIN_WITH_LEAD_CC and its getFCD16()
	        //          was deferred so that average text is checked faster
	        //
	
	        // check the combining order 
	        cc=(int)(fcd16>>8);
	        if(cc!=0) {
	            if(prevCC<0) {
	                // the previous character was <_NORM_MIN_WITH_LEAD_CC, 
                    // we need to get its trail cc 
                    //
                    if(!nx_contains(nx, (int)-prevCC)) {
    	                prevCC=(int)(FCDTrieImpl.fcdTrie.getBMPValue(
                                             (char)-prevCC)&0xff
                                             ); 
	                } else {
	                    prevCC=0; /* excluded: fcd16==0 */
	                }
                                      
	            }
	
	            if(cc<prevCC) {
	                return false;
	            }
	        }
	        prevCC=(int)(fcd16&0xff);
	    }
	}
    
    public static Normalizer.QuickCheckResult quickCheck(char[] src,
                                                            int srcStart, 
                                                            int srcLimit,
                                                            int minNoMaybe,
                                                            int qcMask,
                                                            boolean allowMaybe,
                                                            UnicodeSet nx){
        
        int ccOrQCMask;
        long norm32;
        char c, c2;
        char cc, prevCC;
        long qcNorm32;
        Normalizer.QuickCheckResult result;
        ComposePartArgs args = new ComposePartArgs();
        char[] buffer ;
        int start = srcStart;
        
        if(!isDataLoaded) {
            return Normalizer.MAYBE;
        }
        // initialize 
        ccOrQCMask=CC_MASK|qcMask;
        result=Normalizer.YES;
        prevCC=0;
                
        for(;;) {
            for(;;) {
                if(srcStart==srcLimit) {
                    return result;
                } else if((c=src[srcStart++])>=minNoMaybe && 
                                  (( norm32=getNorm32(c)) & ccOrQCMask)!=0) {
                    break;
                }
                prevCC=0;
            }
            
    
            // check one above-minimum, relevant code unit 
            if(isNorm32LeadSurrogate(norm32)) {
                // c is a lead surrogate, get the real norm32 
                if(srcStart!=srcLimit&& UTF16.isTrailSurrogate(c2=src[srcStart])) {
                    ++srcStart;
                    norm32=getNorm32FromSurrogatePair(norm32,c2);
                } else {
                    norm32=0;
                    c2=0;
                }
            }else{
            	c2=0;
            }
            if(nx_contains(nx, c, c2)) {
	            /* excluded: norm32==0 */
	            norm32=0;
	        }
    
            // check the combining order 
            cc=(char)((norm32>>CC_SHIFT)&0xFF);
            if(cc!=0 && cc<prevCC) {
                return Normalizer.NO;
            }
            prevCC=cc;
    
            // check for "no" or "maybe" quick check flags 
            qcNorm32 = norm32 & qcMask;
            if((qcNorm32& QC_ANY_NO)>=1) {
                result= Normalizer.NO;
                break;
            } else if(qcNorm32!=0) {
                // "maybe" can only occur for NFC and NFKC 
                if(allowMaybe){
                    result=Normalizer.MAYBE;
                }else{
                    // normalize a section around here to see if it is really 
                    // normalized or not 
                    int prevStarter;
                    int/*unsigned*/ decompQCMask;
    
                    decompQCMask=(qcMask<<2)&0xf; // decomposition quick check mask 
    
                    // find the previous starter 
                    
                    // set prevStarter to the beginning of the current character 
                    prevStarter=srcStart-1; 
                    if(UTF16.isTrailSurrogate(src[prevStarter])) {
                        // safe because unpaired surrogates do not result 
                        // in "maybe"
                        --prevStarter; 
                    }
                    prevStarter=findPreviousStarter(src, start, prevStarter,
                                                    ccOrQCMask, decompQCMask,
                                                    (char)minNoMaybe);
    
                    // find the next true starter in [src..limit[ - modifies 
                    // src to point to the next starter 
                    srcStart=findNextStarter(src,srcStart, srcLimit, qcMask, 
                                             decompQCMask,(char) minNoMaybe);
                    
                    //set the args for compose part
                    args.prevCC = prevCC;
                       
                    // decompose and recompose [prevStarter..src[ 
                    buffer = composePart(args,prevStarter,src,srcStart,srcLimit,qcMask,nx);
    
                    // compare the normalized version with the original 
                    if(0!=strCompare(buffer,0,args.length,src,prevStarter,(srcStart-prevStarter), false)) {
                        result=Normalizer.NO; // normalization differs 
                        break;
                    }
    
                    // continue after the next starter 
                }
            }
        }
        return result;
    } 
 
	   
    //------------------------------------------------------ 
    // make NFD & NFKD 
    //------------------------------------------------------
	public static int getDecomposition(int c /*UTF-32*/ , 
										boolean compat,
			                       		char[] dest,
			                       		int destStart, 
			                       		int destCapacity) {
	        
	    if( (UNSIGNED_INT_MASK & c)<=0x10ffff) {
	        long /*unsigned*/ norm32;
            int qcMask;
	        int minNoMaybe;
	        int length;
	
	        // initialize 
	        if(!compat) {
	            minNoMaybe=(int)indexes[INDEX_MIN_NFD_NO_MAYBE];
	            qcMask=QC_NFD;
	        } else {
	            minNoMaybe=(int)indexes[INDEX_MIN_NFKD_NO_MAYBE];
	            qcMask=QC_NFKD;
	        }
	
	        if(c<minNoMaybe) {
	            // trivial case 
	            if(destCapacity>0) {
	                dest[0]=(char)c;
	            }
	            return -1;
	        }
	
	        /* data lookup */
	        norm32=getNorm32(c);
	        if((norm32&qcMask)==0) {
	            /* simple case: no decomposition */
	            if(c<=0xffff) {
	                if(destCapacity>0) {
	                    dest[0]=(char)c;
	                }
	                return -1;
	            } else {
	                if(destCapacity>=2) {
	                    dest[0]=UTF16.getLeadSurrogate(c);
	                    dest[1]=UTF16.getTrailSurrogate(c);
	                }
	                return -2;
	            }
	        } else if(isNorm32HangulOrJamo(norm32)) {
	            /* Hangul syllable: decompose algorithmically */
	            char c2;
	
	            c-=HANGUL_BASE;
	
	            c2=(char)(c%JAMO_T_COUNT);
	            c/=JAMO_T_COUNT;
	            if(c2>0) {
	                if(destCapacity>=3) {
	                    dest[2]=(char)(JAMO_T_BASE+c2);
	                }
	                length=3;
	            } else {
	                length=2;
	            }
	
	            if(destCapacity>=2) {
	                dest[1]=(char)(JAMO_V_BASE+c%JAMO_V_COUNT);
	                dest[0]=(char)(JAMO_L_BASE+c/JAMO_V_COUNT);
	            }
	            return length;
	        } else {
	            /* c decomposes, get everything from the variable-length extra 
                 * data 
                 */
	            int p, limit;
	            DecomposeArgs args = new DecomposeArgs();
	            /* the index into extra data array*/ 				
	            p=decompose(norm32, qcMask, args);
	            if(args.length<=destCapacity) {
	                limit=p+args.length;
	                do {
	                    dest[destStart++]=extraData[p++];
	                } while(p<limit);
	            }
	            return args.length;
	        }
	    } else {
	        return 0;
	    }
	}

	
	public static int decompose(char[] src,int srcIndex,int srcLimit,
								char[] dest,int destIndex,int destLimit,
						 		boolean compat,int[] outTrailCC,
						 		UnicodeSet nx) {
	           			 	
	    char[] buffer = new char[3];
	    int prevSrc;
	    long norm32;
        int ccOrQCMask, qcMask;
	    int reorderStartIndex, length;
	    char c, c2, minNoMaybe;
	    int/*unsigned byte*/ cc, prevCC, trailCC;
		char[] p;
		int pStart;
	    if(!compat) {
	        minNoMaybe=(char)indexes[INDEX_MIN_NFD_NO_MAYBE];
	        qcMask=QC_NFD;
	    } else {
	        minNoMaybe=(char)indexes[INDEX_MIN_NFKD_NO_MAYBE];
	        qcMask=QC_NFKD;
	    }
	
	    /* initialize */
	    ccOrQCMask=CC_MASK|qcMask;
	    reorderStartIndex=0;
	    prevCC=0;
	    norm32=0;
	    c=0;
		pStart=0;
	    
	    cc=trailCC=-1;//initialize to bogus value
	    
	    for(;;) {
	        /* count code units below the minimum or with irrelevant data for 
             * the quick check 
             */
	        prevSrc=srcIndex;

            while(srcIndex!=srcLimit &&((c=src[srcIndex])<minNoMaybe || 
                                        ((norm32=getNorm32(c))&ccOrQCMask)==0)){
                prevCC=0;
                ++srcIndex;
            }

	        /* copy these code units all at once */
	        if(srcIndex!=prevSrc) {
	            length=(int)(srcIndex-prevSrc);
	            if((destIndex+length)<=destLimit) {
	            	System.arraycopy(src,prevSrc,dest,destIndex,length);
	            }
	          
	            destIndex+=length;
	            reorderStartIndex=destIndex;
	        }
	
	        /* end of source reached? */
	        if(srcIndex==srcLimit) {
	            break;
	        }
	
	        /* c already contains *src and norm32 is set for it, increment src*/
	        ++srcIndex;
	
	        /* check one above-minimum, relevant code unit */
	        /*
	         * generally, set p and length to the decomposition string
	         * in simple cases, p==NULL and (c, c2) will hold the length code 
             * units to append in all cases, set cc to the lead and trailCC to 
             * the trail combining class
	         *
	         * the following merge-sort of the current character into the 
             * preceding, canonically ordered result text will use the 
             * optimized insertOrdered()
	         * if there is only one single code point to process;
	         * this is indicated with p==NULL, and (c, c2) is the character to 
             * insert
	         * ((c, 0) for a BMP character and (lead surrogate, trail surrogate)
	         * for a supplementary character)
	         * otherwise, p[length] is merged in with _mergeOrdered()
	         */
	        if(isNorm32HangulOrJamo(norm32)) {
	            if(nx_contains(nx, c)) {
	                c2=0;
	                p=null;
	                length=1;
	            } else {
	                // Hangul syllable: decompose algorithmically 
	                p=buffer;
	                pStart=0;
	                cc=trailCC=0;
	
	                c-=HANGUL_BASE;
	
	                c2=(char)(c%JAMO_T_COUNT);
	                c/=JAMO_T_COUNT;
	                if(c2>0) {
	                    buffer[2]=(char)(JAMO_T_BASE+c2);
	                    length=3;
	                } else {
	                    length=2;
	                }
	
	                buffer[1]=(char)(JAMO_V_BASE+c%JAMO_V_COUNT);
	                buffer[0]=(char)(JAMO_L_BASE+c/JAMO_V_COUNT);
	            }
	        } else {
	            if(isNorm32Regular(norm32)) {
	                c2=0;
	                length=1;
	            } else {
	                // c is a lead surrogate, get the real norm32 
	                if(srcIndex!=srcLimit && 
                                    UTF16.isTrailSurrogate(c2=src[srcIndex])) {
	                    ++srcIndex;
	                    length=2;
	                    norm32=getNorm32FromSurrogatePair(norm32, c2);
	                } else {
	                    c2=0;
	                    length=1;
	                    norm32=0;
	                }
	            }
	
	            /* get the decomposition and the lead and trail cc's */
	            if(nx_contains(nx, c, c2)) {
	                /* excluded: norm32==0 */
	                cc=trailCC=0;
	                p=null;
            	} else if((norm32&qcMask)==0) {
	                /* c does not decompose */
	                cc=trailCC=(int)((UNSIGNED_BYTE_MASK) & (norm32>>CC_SHIFT));
	                p=null;
                    pStart=-1;
	            } else {
	            	DecomposeArgs arg = new DecomposeArgs();
	            	/* c decomposes, get everything from the variable-length 
                     * extra data 
                     */
	                pStart=decompose(norm32, qcMask, arg);
	                p=extraData;
	                length=arg.length;
	                cc=arg.cc;
	                trailCC=arg.trailCC;
	                if(length==1) {
	                    /* fastpath a single code unit from decomposition */
	                    c=p[pStart];
	                    c2=0;
	                    p=null;
                        pStart=-1;
	                }
	            }
	        }
	
	        /* append the decomposition to the destination buffer, assume 
             * length>0 
             */
	        if((destIndex+length)<=destLimit) {
	            int reorderSplit=destIndex;
	            if(p==null) {
	                /* fastpath: single code point */
	                if(cc!=0 && cc<prevCC) {
	                    /* (c, c2) is out of order with respect to the preceding
                         *  text 
                         */
	                    destIndex+=length;
	                    trailCC=insertOrdered(dest,reorderStartIndex, 
                                            reorderSplit, destIndex, c, c2, cc);
	                } else {
	                    /* just append (c, c2) */
	                    dest[destIndex++]=c;
	                    if(c2!=0) {
	                        dest[destIndex++]=c2;
	                    }
	                }
	            } else {
	                /* general: multiple code points (ordered by themselves) 
                     * from decomposition 
                     */
	                if(cc!=0 && cc<prevCC) {
	                    /* the decomposition is out of order with respect to the
                         *  preceding text 
                         */
	                    destIndex+=length;
	                    trailCC=mergeOrdered(dest,reorderStartIndex, 
                                          reorderSplit,p, pStart,pStart+length);
	                } else {
	                    /* just append the decomposition */
	                    do {
	                        dest[destIndex++]=p[pStart++];
	                    } while(--length>0);
	                }
	            }
	        } else {
	            /* buffer overflow */
	            /* keep incrementing the destIndex for preflighting */
	            destIndex+=length;
	        }
	
	        prevCC=trailCC;
	        if(prevCC==0) {
	            reorderStartIndex=destIndex;
	        }
	    }
	
	    outTrailCC[0]=prevCC;

	    return destIndex;
	}
	
	/* make NFC & NFKC ------------------------------------------------------ */
	private static final class NextCombiningArgs{
		char[] source;
		int start;
		//int limit;
		char c;
		char c2;
		int/*unsigned*/ combiningIndex;
		char /*unsigned byte*/ cc;
	}
	
	/* get the composition properties of the next character */
	private static int /*unsigned*/	getNextCombining(NextCombiningArgs args,
                                                    int limit,
                                                    UnicodeSet nx) {
	    long/*unsigned*/ norm32; 
        int combineFlags;
	    /* get properties */
	    args.c=args.source[args.start++];
	    norm32=getNorm32(args.c);
	    
	    /* preset output values for most characters */
        args.c2=0;
		args.combiningIndex=0;
		args.cc=0;
		
	    if((norm32&(CC_MASK|COMBINES_ANY))==0) {
	        return 0;
	    } else {
	        if(isNorm32Regular(norm32)) {
	            /* set cc etc. below */
	        } else if(isNorm32HangulOrJamo(norm32)) {
	            /* a compatibility decomposition contained Jamos */
	            args.combiningIndex=(int)((UNSIGNED_INT_MASK)&(0xfff0|
                                                        (norm32>>EXTRA_SHIFT)));
	            return (int)(norm32&COMBINES_ANY);
	        } else {
	            /* c is a lead surrogate, get the real norm32 */
	            if(args.start!=limit && UTF16.isTrailSurrogate(args.c2=
                                                     args.source[args.start])) {
	                ++args.start;
	                norm32=getNorm32FromSurrogatePair(norm32, args.c2);
	            } else {
	                args.c2=0;
	                return 0;
	            }
	        }
	        
	        if(nx_contains(nx, args.c, args.c2)) {
	            return 0; /* excluded: norm32==0 */
	        }
	
	        args.cc= (char)(byte)(norm32>>CC_SHIFT);
        
	        combineFlags=(int)(norm32&COMBINES_ANY);
	        if(combineFlags!=0) {
                int index = getExtraDataIndex(norm32);
	            args.combiningIndex=index>0 ? extraData[(index-1)] :0;
	        }
	
	        return combineFlags;
	    }
	}
	
	/*
	 * given a composition-result starter (c, c2) - which means its cc==0,
	 * it combines forward, it has extra data, its norm32!=0,
	 * it is not a Hangul or Jamo,
	 * get just its combineFwdIndex
	 *
	 * norm32(c) is special if and only if c2!=0
	 */
	private static int/*unsigned*/ getCombiningIndexFromStarter(char c,char c2){
	    long/*unsigned*/ norm32;
	
	    norm32=getNorm32(c);
	    if(c2!=0) {
	        norm32=getNorm32FromSurrogatePair(norm32, c2);
	    }
	    return extraData[(getExtraDataIndex(norm32)-1)];
	}
	
	/*
	 * Find the recomposition result for
	 * a forward-combining character
	 * (specified with a pointer to its part of the combiningTable[])
	 * and a backward-combining character
	 * (specified with its combineBackIndex).
	 *
	 * If these two characters combine, then set (value, value2)
	 * with the code unit(s) of the composition character.
	 *
	 * Return value:
	 * 0    do not combine
	 * 1    combine
	 * >1   combine, and the composition is a forward-combining starter
	 *
	 * See unormimp.h for a description of the composition table format.
	 */
	private static int/*unsigned*/ combine(char[]table,int tableStart, 
								   int/*unsinged*/ combineBackIndex,
	         					   int[] outValues) {
	    int/*unsigned*/ key;
	    int value,value2;
	    
		if(outValues.length<2){
			throw new IllegalArgumentException();
		}
		
	    /* search in the starter's composition table */
	    for(;;) {
	        key=table[tableStart++];
	        if(key>=combineBackIndex) {
	            break;
	        }
	        tableStart+= ((table[tableStart]&0x8000) != 0)? 2 : 1;
	    }
	
	    /* mask off bit 15, the last-entry-in-the-list flag */
	    if((key&0x7fff)==combineBackIndex) {
	        /* found! combine! */
	        value=table[tableStart];
	
	        /* is the composition a starter that combines forward? */
	        key=(int)((UNSIGNED_INT_MASK)&((value&0x2000)+1));
	
	        /* get the composition result code point from the variable-length 
             * result value 
             */
	        if((value&0x8000) != 0) {
	            if((value&0x4000) != 0) {
	                /* surrogate pair composition result */
	                value=(int)((UNSIGNED_INT_MASK)&((value&0x3ff)|0xd800));
	                value2=table[tableStart+1];
	            } else {
	                /* BMP composition result U+2000..U+ffff */
	                value=table[tableStart+1];
	                value2=0;
	            }
	        } else {
	            /* BMP composition result U+0000..U+1fff */
	            value&=0x1fff;
	            value2=0;
	        }
            outValues[0]=value;
            outValues[1]=value2;	
	        return key;
	    } else {
	        /* not found */
	        return 0;
	    }
	}
	
	
	private static final class RecomposeArgs{
		char[] source;
		int start;
		int limit;
	}
    /*
     * recompose the characters in [p..limit[
     * (which is in NFD - decomposed and canonically ordered),
     * adjust limit, and return the trailing cc
     *
     * since for NFKC we may get Jamos in decompositions, we need to
     * recompose those too
     *
     * note that recomposition never lengthens the text:
     * any character consists of either one or two code units;
     * a composition may contain at most one more code unit than the original 
     * starter, while the combining mark that is removed has at least one code 
     * unit
     */
    private static char/*unsigned byte*/ recompose(RecomposeArgs args, UnicodeSet nx) {
        int  remove, q, r;
        int /*unsigned*/ combineFlags;
        int /*unsigned*/ combineFwdIndex, combineBackIndex;
        int /*unsigned*/ result, value=0, value2=0;
        int /*unsigned byte*/  prevCC;
        boolean starterIsSupplementary;
    	int starter;
    	int[] outValues = new int[2];
        starter=-1;                   /* no starter */
        combineFwdIndex=0;            /* will not be used until starter!=NULL */
        starterIsSupplementary=false; /* will not be used until starter!=NULL */
        prevCC=0;
        
        NextCombiningArgs ncArg = new NextCombiningArgs();
        ncArg.source  = args.source;
        
        ncArg.cc      =0;
        ncArg.c2      =0;    

        for(;;) {
            ncArg.start = args.start;
            combineFlags=getNextCombining(ncArg,args.limit,nx);
            combineBackIndex=ncArg.combiningIndex;
            args.start = ncArg.start;
                        
            if(((combineFlags&COMBINES_BACK)!=0) && starter!=-1) {
                if((combineBackIndex&0x8000)!=0) {
                    /* c is a Jamo V/T, see if we can compose it with the 
                     * previous character 
                     */
                    remove=-1; /* NULL while no Hangul composition */
                    ncArg.c2=args.source[starter];
                    if(combineBackIndex==0xfff2) {
                        /* Jamo V, compose with previous Jamo L and following 
                         * Jamo T 
                         */
                        ncArg.c2=(char)(ncArg.c2-JAMO_L_BASE);
                        if(ncArg.c2<JAMO_L_COUNT) {
                            remove=args.start-1;
                            ncArg.c=(char)(HANGUL_BASE+(ncArg.c2*JAMO_V_COUNT+
                                           (ncArg.c-JAMO_V_BASE))*JAMO_T_COUNT);
                            if(args.start!=args.limit && 
                                        (ncArg.c2=(char)(args.source[args.start]
                                         -JAMO_T_BASE))<JAMO_T_COUNT) {
                                ++args.start;
                                ncArg.c+=ncArg.c2;
                            }
                            if(!nx_contains(nx, ncArg.c)) {
                            	args.source[starter]=ncArg.c;
                           	} else {
	                            /* excluded */
	                            if(!isHangulWithoutJamoT(ncArg.c)) {
	                                --args.start; /* undo the ++args.start from reading the Jamo T */
	                            }
	                            /* c is modified but not used any more -- c=*(p-1); -- re-read the Jamo V/T */
	                            remove=args.start;
	                        }
                        }

                    }
    
                    if(remove!=-1) {
                        /* remove the Jamo(s) */
                        q=remove;
                        r=args.start;
                        while(r<args.limit) {
                            args.source[q++]=args.source[r++];
                        }
                        args.start=remove;
                        args.limit=q;
                    }
    
                    ncArg.c2=0; /* c2 held *starter temporarily */
    
                    /*
                     * now: cc==0 and the combining index does not include 
                     * "forward" -> the rest of the loop body will reset starter
                     * to NULL; technically, a composed Hangul syllable is a 
                     * starter, but it does not combine forward now that we have
                     * consumed all eligible Jamos; for Jamo V/T, combineFlags 
                     * does not contain _NORM_COMBINES_FWD
                     */
    
                } else if(
                    /* the starter is not a Jamo V/T and */
                    !((combineFwdIndex&0x8000)!=0) &&
                    /* the combining mark is not blocked and */
                    (prevCC<ncArg.cc || prevCC==0) &&
                    /* the starter and the combining mark (c, c2) do combine */
                    0!=(result=combine(combiningTable,combineFwdIndex, 
                                       combineBackIndex, outValues)) &&
                    /* the composition result is not excluded */
                	!nx_contains(nx, (char)value, (char)value2)
                ) {
                	value=outValues[0];
                	value2=outValues[1];
                    /* replace the starter with the composition, remove the 
                     * combining mark 
                     */
                    remove= ncArg.c2==0 ? args.start-1 : args.start-2; /* index to the combining mark */
    
                    /* replace the starter with the composition */
                    args.source[starter]=(char)value;
                    if(starterIsSupplementary) {
                        if(value2!=0) {
                            /* both are supplementary */
                            args.source[starter+1]=(char)value2;
                        } else {
                            /* the composition is shorter than the starter, 
                             * move the intermediate characters forward one */
                            starterIsSupplementary=false;
                            q=starter+1;
                            r=q+1;
                            while(r<remove) {
                                args.source[q++]=args.source[r++];
                            }
                            --remove;
                        }
                    } else if(value2!=0) {
                        /* the composition is longer than the starter, 
                         * move the intermediate characters back one */
                        starterIsSupplementary=true;
                        /* temporarily increment for the loop boundary */
                        ++starter; 
                        q=remove;
                        r=++remove;
                        while(starter<q) {
                            args.source[--r]=args.source[--q];
                        }
                        args.source[starter]=(char)value2;
                        --starter; /* undo the temporary increment */
                    /* } else { both are on the BMP, nothing more to do */
                    }
    
                    /* remove the combining mark by moving the following text 
                     * over it */
                    if(remove<args.start) {
                        q=remove;
                        r=args.start;
                        while(r<args.limit) {
                            args.source[q++]=args.source[r++];
                        }
                        args.start=remove;
                        args.limit=q;
                    }
    
                    /* keep prevCC because we removed the combining mark */
    
                    /* done? */
                    if(args.start==args.limit) {
                        return (char)prevCC;
                    }
    
                    /* is the composition a starter that combines forward? */
                    if(result>1) {
                       combineFwdIndex=getCombiningIndexFromStarter((char)value,
                                                                  (char)value2);
                    } else {
                       starter=-1;
                    }
    
                    /* we combined and set prevCC, continue with looking for 
                     * compositions */
                    continue;
                }
            }
    
            /* no combination this time */
            prevCC=ncArg.cc;
            if(args.start==args.limit) {
                return (char)prevCC;
            }
    
            /* if (c, c2) did not combine, then check if it is a starter */
            if(ncArg.cc==0) {
                /* found a new starter; combineFlags==0 if (c, c2) is excluded */
                if((combineFlags&COMBINES_FWD)!=0) {
                    /* it may combine with something, prepare for it */
                    if(ncArg.c2==0) {
                        starterIsSupplementary=false;
                        starter=args.start-1;
                    } else {
                        starterIsSupplementary=false;
                        starter=args.start-2;
                    }
                    combineFwdIndex=combineBackIndex;
                } else {
                    /* it will not combine with anything */
                    starter=-1;
                }
            }
        }
    }
   
    // find the last true starter between src[start]....src[current] going 
    // backwards and return its index
    private static int findPreviousStarter(char[]src, int srcStart, int current, 
                                          int/*unsigned*/ ccOrQCMask, 
                                          int/*unsigned*/ decompQCMask,
                                          char minNoMaybe) { 
       long norm32; 
       PrevArgs args = new PrevArgs();
       args.src = src;
       args.start = srcStart;
       args.current = current;
       
       while(args.start<args.current) { 
           norm32= getPrevNorm32(args, minNoMaybe, ccOrQCMask|decompQCMask); 
           if(isTrueStarter(norm32, ccOrQCMask, decompQCMask)) { 
               break; 
           } 
       } 
       return args.current; 
    }
	
    /* find the first true starter in [src..limit[ and return the 
     * pointer to it 
     */
	private static int/*index*/	findNextStarter(char[] src,int start,int limit,
	                 				            int/*unsigned*/ qcMask, 
	                 				            int/*unsigned*/ decompQCMask, 
	                 				            char minNoMaybe) {
	    int p;
	    long/*unsigned*/ norm32; 
        int ccOrQCMask;
	    char c, c2;
	
	    ccOrQCMask=CC_MASK|qcMask;
	    
		DecomposeArgs decompArgs = new DecomposeArgs();

	    for(;;) {
	        if(start==limit) {
	            break; /* end of string */
	        }
	        c=src[start];
	        if(c<minNoMaybe) {
	            break; /* catches NUL terminater, too */
	        }
	
	        norm32=getNorm32(c);
	        if((norm32&ccOrQCMask)==0) {
	            break; /* true starter */
	        }
	
	        if(isNorm32LeadSurrogate(norm32)) {
	            /* c is a lead surrogate, get the real norm32 */
	            if((start+1)==limit || 
                                   !UTF16.isTrailSurrogate(c2=(src[start+1]))){
                    /* unmatched first surrogate: counts as a true starter */                  
	                break; 
	            }
	            norm32=getNorm32FromSurrogatePair(norm32, c2);
	
	            if((norm32&ccOrQCMask)==0) {
	                break; /* true starter */
	            }
	        } else {
	            c2=0;
	        }
	
	        /* (c, c2) is not a true starter but its decomposition may be */
	        if((norm32&decompQCMask)!=0) {
	            /* (c, c2) decomposes, get everything from the variable-length
                 *  extra data */
	            p=decompose(norm32, decompQCMask, decompArgs);
	
	            /* get the first character's norm32 to check if it is a true 
                 * starter */
	            if(decompArgs.cc==0 && (getNorm32(extraData,p, qcMask)&qcMask)==0) {
	                break; /* true starter */
	            }
	        }
	
	        start+= c2==0 ? 1 : 2; /* not a true starter, continue */
	    }
	
	    return start;
	}
	
    
	private static final class ComposePartArgs{
		int prevCC;
        int length;   /* length of decomposed part */
	}
	    
 	/* decompose and recompose [prevStarter..src[ */
	private static char[] composePart(ComposePartArgs args, 
                                      int prevStarter, 
				       	              char[] src, int start, int limit,
	             			          int/*unsigned*/ qcMask,
	             			          UnicodeSet nx) {
	    int recomposeLimit;
        boolean compat =((qcMask&QC_NFKC)!=0);
        
	    /* decompose [prevStarter..src[ */
        int[] outTrailCC = new int[1];
        char[] buffer = new char[(limit-prevStarter)*MAX_BUFFER_SIZE];

        for(;;){
            args.length=decompose(src,prevStarter,(start),
                                      buffer,0,buffer.length, 
                                      compat,outTrailCC,nx);
            if(args.length<=buffer.length){
                break;
            }else{
                buffer = new char[args.length];
            }
        } 
	
	    /* recompose the decomposition */
	    recomposeLimit=args.length;
	  	
	    if(args.length>=2) {
	        RecomposeArgs rcArgs = new RecomposeArgs();
	        rcArgs.source	= buffer;
	        rcArgs.start    = 0;
	        rcArgs.limit	= recomposeLimit; 
	        args.prevCC=recompose(rcArgs,nx);
	        recomposeLimit = rcArgs.limit;
	    }
        
	    /* return with a pointer to the recomposition and its length */
	    args.length=recomposeLimit;
	    return buffer;
	}
    
	private static boolean composeHangul(char prev, char c,
								         long/*unsigned*/ norm32, 
								         char[] src,int[] srcIndex, int limit,
	               				         boolean compat, 
                                         char[] dest,int destIndex,
                                         UnicodeSet nx) {
	    int start=srcIndex[0];
	    if(isJamoVTNorm32JamoV(norm32)) {
	        /* c is a Jamo V, compose with previous Jamo L and 
             * following Jamo T */
	        prev=(char)(prev-JAMO_L_BASE);
	        if(prev<JAMO_L_COUNT) {
	            c=(char)(HANGUL_BASE+(prev*JAMO_V_COUNT+
                                                 (c-JAMO_V_BASE))*JAMO_T_COUNT);
	
	            /* check if the next character is a Jamo T (normal or 
                 * compatibility) */
	            if(start!=limit) {
	                char next, t;
	
	                next=src[start];
	                if((t=(char)(next-JAMO_T_BASE))<JAMO_T_COUNT) {
	                    /* normal Jamo T */
	                    ++start;
	                    c+=t;
	                } else if(compat) {
	                    /* if NFKC, then check for compatibility Jamo T 
                         * (BMP only) */
	                    norm32=getNorm32(next);
	                    if(isNorm32Regular(norm32) && ((norm32&QC_NFKD)!=0)) {
	                        int p /*index into extra data array*/;
	                        DecomposeArgs dcArgs = new DecomposeArgs();
	                        p=decompose(norm32, QC_NFKD, dcArgs);
	                        if(dcArgs.length==1 && 
                                   (t=(char)(extraData[p]-JAMO_T_BASE))
                                                   <JAMO_T_COUNT) {
	                            /* compatibility Jamo T */
	                            ++start;
	                            c+=t;
	                        }
	                    }
	                }
	            }
				if(nx_contains(nx, c)) {
	                if(!isHangulWithoutJamoT(c)) {
	                    --start; /* undo ++start from reading the Jamo T */
	                }
	                return false;
	            }
                dest[destIndex]=c;
                srcIndex[0]=start;
	            return true;
	        }
	    } else if(isHangulWithoutJamoT(prev)) {
	        /* c is a Jamo T, compose with previous Hangul LV that does not 
             * contain a Jamo T */
            c=(char)(prev+(c-JAMO_T_BASE));
	        if(nx_contains(nx, c)) {
	            return false;
	        }
            dest[destIndex]=c;
	        srcIndex[0]=start;
	        return true;
	    }
	    return false;
	}
    /*
    public static int compose(char[] src, char[] dest,boolean compat, UnicodeSet nx){
        return compose(src,0,src.length,dest,0,dest.length,compat, nx);
    }
    */
    
    public static int compose(char[] src, int srcIndex, int srcLimit,
                              char[] dest,int destIndex,int destLimit,
                              boolean compat,UnicodeSet nx) {
        
        int prevSrc, prevStarter;
        long/*unsigned*/ norm32; 
        int ccOrQCMask, qcMask;
        int  reorderStartIndex, length;
        char c, c2, minNoMaybe;
        int/*unsigned byte*/ cc, prevCC;
        int[] ioIndex = new int[1];
        
        if(!compat) {
            minNoMaybe=(char)indexes[INDEX_MIN_NFC_NO_MAYBE];
            qcMask=QC_NFC;
        } else {
            minNoMaybe=(char)indexes[INDEX_MIN_NFKC_NO_MAYBE];
            qcMask=QC_NFKC;
        }
    
        /*
         * prevStarter points to the last character before the current one
         * that is a "true" starter with cc==0 and quick check "yes".
         *
         * prevStarter will be used instead of looking for a true starter
         * while incrementally decomposing [prevStarter..prevSrc[
         * in _composePart(). Having a good prevStarter allows to just decompose
         * the entire [prevStarter..prevSrc[.
         *
         * When _composePart() backs out from prevSrc back to prevStarter,
         * then it also backs out destIndex by the same amount.
         * Therefore, at all times, the (prevSrc-prevStarter) source units
         * must correspond 1:1 to destination units counted with destIndex,
         * except for reordering.
         * This is true for the qc "yes" characters copied in the fast loop,
         * and for pure reordering.
         * prevStarter must be set forward to src when this is not true:
         * In _composePart() and after composing a Hangul syllable.
         *
         * This mechanism relies on the assumption that the decomposition of a 
         * true starter also begins with a true starter. gennorm/store.c checks 
         * for this.
         */
        prevStarter=srcIndex;
    
        ccOrQCMask=CC_MASK|qcMask;
        /*destIndex=*/reorderStartIndex=0;/* ####TODO#### check this **/
        prevCC=0;
    
        /* avoid compiler warnings */
        norm32=0;
        c=0;
    
        for(;;) {
            /* count code units below the minimum or with irrelevant data for 
             * the quick check */
            prevSrc=srcIndex;

            while(srcIndex!=srcLimit && ((c=src[srcIndex])<minNoMaybe || 
                     ((norm32=getNorm32(c))&ccOrQCMask)==0)) {
                prevCC=0;
                ++srcIndex;
            }

    
            /* copy these code units all at once */
            if(srcIndex!=prevSrc) {
                length=(int)(srcIndex-prevSrc);
                if((destIndex+length)<=destLimit) {
                    System.arraycopy(src,prevSrc,dest,destIndex,length);
                }
                destIndex+=length;
                reorderStartIndex=destIndex;
    
                /* set prevStarter to the last character in the quick check 
                 * loop */
                prevStarter=srcIndex-1;
                if(UTF16.isTrailSurrogate(src[prevStarter]) && 
                    prevSrc<prevStarter && 
                    UTF16.isLeadSurrogate(src[(prevStarter-1)])) {
                    --prevStarter;
                }
    
                prevSrc=srcIndex;
            }
    
            /* end of source reached? */
            if(srcIndex==srcLimit) {
                break;
            }
    
            /* c already contains *src and norm32 is set for it, increment src*/
            ++srcIndex;
    
            /*
             * source buffer pointers:
             *
             *  all done      quick check   current char  not yet
             *                "yes" but     (c, c2)       processed
             *                may combine
             *                forward
             * [-------------[-------------[-------------[-------------[
             * |             |             |             |             |
             * start         prevStarter   prevSrc       src           limit
             *
             *
             * destination buffer pointers and indexes:
             *
             *  all done      might take    not filled yet
             *                characters for
             *                reordering
             * [-------------[-------------[-------------[
             * |             |             |             |
             * dest      reorderStartIndex destIndex     destCapacity
             */
    
            /* check one above-minimum, relevant code unit */
            /*
             * norm32 is for c=*(src-1), and the quick check flag is "no" or 
             * "maybe", and/or cc!=0
             * check for Jamo V/T, then for surrogates and regular characters
             * c is not a Hangul syllable or Jamo L because
             * they are not marked with no/maybe for NFC & NFKC(and their cc==0)
             */
            if(isNorm32HangulOrJamo(norm32)) {
                /*
                 * c is a Jamo V/T:
                 * try to compose with the previous character, Jamo V also with 
                 * a following Jamo T, and set values here right now in case we 
                 * just continue with the main loop
                 */
                prevCC=cc=0;
                reorderStartIndex=destIndex;
                ioIndex[0]=srcIndex;
                if( 
                	destIndex>0 &&
                    composeHangul(src[(prevSrc-1)], c, norm32,src, ioIndex,
                                  srcLimit, compat, dest,
                                  destIndex<=destLimit ? destIndex-1: 0,
                                  nx)
                ) {
                    srcIndex=ioIndex[0];
                    prevStarter=srcIndex;
                    continue;
                }
                
                srcIndex = ioIndex[0];
    
                /* the Jamo V/T did not compose into a Hangul syllable, just 
                 * append to dest */
                c2=0;
                length=1;
                prevStarter=prevSrc;
            } else {
                if(isNorm32Regular(norm32)) {
                    c2=0;
                    length=1;
                } else {
                    /* c is a lead surrogate, get the real norm32 */
                    if(srcIndex!=srcLimit &&
                                     UTF16.isTrailSurrogate(c2=src[srcIndex])) {
                        ++srcIndex;
                        length=2;
                        norm32=getNorm32FromSurrogatePair(norm32, c2);
                    } else {
                        /* c is an unpaired lead surrogate, nothing to do */
                        c2=0;
                        length=1;
                        norm32=0;
                    }
                }
                ComposePartArgs args =new ComposePartArgs();
                
                /* we are looking at the character (c, c2) at [prevSrc..src[ */
                if(nx_contains(nx, c, c2)) {
	                /* excluded: norm32==0 */
	                cc=0;
            	} else if((norm32&qcMask)==0) {
                    cc=(int)((UNSIGNED_BYTE_MASK)&(norm32>>CC_SHIFT));
                } else {
                    char[] p;
    
                    /*
                     * find appropriate boundaries around this character,
                     * decompose the source text from between the boundaries,
                     * and recompose it
                     *
                     * this puts the intermediate text into the side buffer because
                     * it might be longer than the recomposition end result,
                     * or the destination buffer may be too short or missing
                     *
                     * note that destIndex may be adjusted backwards to account
                     * for source text that passed the quick check but needed to
                     * take part in the recomposition
                     */
                    int decompQCMask=(qcMask<<2)&0xf; /* decomposition quick check mask */
                    /*
		             * find the last true starter in [prevStarter..src[
		             * it is either the decomposition of the current character (at prevSrc),
		             * or prevStarter
		             */
		            if(isTrueStarter(norm32, CC_MASK|qcMask, decompQCMask)) {
		                prevStarter=prevSrc;
		            } else {
		                /* adjust destIndex: back out what had been copied with qc "yes" */
		                destIndex-=prevSrc-prevStarter;
		            }
		        
		            /* find the next true starter in [src..limit[ */
		            srcIndex=findNextStarter(src, srcIndex,srcLimit, qcMask, 
                                               decompQCMask, minNoMaybe);
                    //args.prevStarter = prevStarter;
                    args.prevCC	= prevCC;                    
                    //args.destIndex = destIndex;
                    args.length = length;
                    p=composePart(args,prevStarter,src,srcIndex,srcLimit,qcMask,nx);
                        
                    if(p==null) {
                        /* an error occurred (out of memory) */
                        break;
                    }
                    
                    prevCC      = args.prevCC;
                    length      = args.length;
                    
                    /* append the recomposed buffer contents to the destination 
                     * buffer */
                    if((destIndex+args.length)<=destLimit) {
                        int i=0;
                        while(i<args.length) {
                            dest[destIndex++]=p[i++];
                            --length;
                        }
                    } else {
                        /* buffer overflow */
                        /* keep incrementing the destIndex for preflighting */
                        destIndex+=length;
                    }
    
                    prevStarter=srcIndex;
                    continue;
                }
            }
    
            /* append the single code point (c, c2) to the destination buffer */
            if((destIndex+length)<=destLimit) {
                if(cc!=0 && cc<prevCC) {
                    /* (c, c2) is out of order with respect to the preceding 
                     * text */
                    int reorderSplit= destIndex;
                    destIndex+=length;
                    prevCC=insertOrdered(dest,reorderStartIndex, reorderSplit, 
                                         destIndex, c, c2, cc);
                } else {
                    /* just append (c, c2) */
                    dest[destIndex++]=c;
                    if(c2!=0) {
                        dest[destIndex++]=c2;
                    }
                    prevCC=cc;
                }
            } else {
                /* buffer overflow */
                /* keep incrementing the destIndex for preflighting */
                destIndex+=length;
                prevCC=cc;
            }
        }

        return destIndex;
    }
	/* make FCD --------------------------------------------------------------*/
	
	private static int/*index*/ findSafeFCD(char[] src, int start, int limit, 
                                            char fcd16) {
	    char c, c2;
	
	    /*
	     * find the first position in [src..limit[ after some cc==0 according 
         * to FCD data
	     *
	     * at the beginning of the loop, we have fcd16 from before src
	     *
	     * stop at positions:
	     * - after trail cc==0
	     * - at the end of the source
	     * - before lead cc==0
	     */
	    for(;;) {
	        /* stop if trail cc==0 for the previous character */
	        if((fcd16&0xff)==0) {
	            break;
	        }
	
	        /* get c=*src - stop at end of string */
	        if(start==limit) {
	            break;
	        }
	        c=src[start];
	
	        /* stop if lead cc==0 for this character */
	        if(c<MIN_WITH_LEAD_CC || (fcd16=getFCD16(c))==0) {
	            break; /* catches terminating NUL, too */
	        }
	
	        if(!UTF16.isLeadSurrogate(c)) {
	            if(fcd16<=0xff) {
	                break;
	            }
	            ++start;
	        } else if(start+1!=limit && 
                                    (UTF16.isTrailSurrogate(c2=src[start+1]))) {
	            /* c is a lead surrogate, get the real fcd16 */
	            fcd16=getFCD16FromSurrogatePair(fcd16, c2);
	            if(fcd16<=0xff) {
	                break;
	            }
	            start+=2;
	        } else {
	            /* c is an unpaired first surrogate, lead cc==0 */
	            break;
	        }
	    }
	
	    return start;
	}
	
	private static int/*unsigned byte*/ decomposeFCD(char[] src, 
                                                     int start,int decompLimit,
	                                                 char[] dest, 
                                                     int[] destIndexArr,
                                                     UnicodeSet nx) {
	    char[] p=null;
        int pStart=-1;
        
	    long /*unsigned int*/ norm32;
	    int reorderStartIndex;
	    char c, c2;
        int/*unsigned byte*/ prevCC;
        DecomposeArgs args = new DecomposeArgs();
        int destIndex = destIndexArr[0];
	    /*
	     * canonically decompose [src..decompLimit[
	     *
	     * all characters in this range have some non-zero cc,
	     * directly or in decomposition,
	     * so that we do not need to check in the following for quick-check 
         * limits etc.
	     *
	     * there _are_ _no_ Hangul syllables or Jamos in here because they are 
         * FCD-safe (cc==0)!
	     *
	     * we also do not need to check for c==0 because we have an established 
         * decompLimit
	     */
	    reorderStartIndex=destIndex;
	    prevCC=0;

	    while(start<decompLimit) {
	        c=src[start++];
	        norm32=getNorm32(c);
	        if(isNorm32Regular(norm32)) {
	            c2=0;
	            args.length=1;
	        } else {
	            /*
	             * reminder: this function is called with [src..decompLimit[
	             * not containing any Hangul/Jamo characters,
	             * therefore the only specials are lead surrogates
	             */
	            /* c is a lead surrogate, get the real norm32 */
	            if(start!=decompLimit && UTF16.isTrailSurrogate(c2=src[start])){
	                ++start;
	                args.length=2;
	                norm32=getNorm32FromSurrogatePair(norm32, c2);
	            } else {
	                c2=0;
	                args.length=1;
	                norm32=0;
	            }
	        }
	
	        /* get the decomposition and the lead and trail cc's */
	        if(nx_contains(nx, c, c2)) {
	            /* excluded: norm32==0 */
	            args.cc=args.trailCC=0;
	            p=null;
        	} else if((norm32&QC_NFD)==0) {
	            /* c does not decompose */
	            args.cc=args.trailCC=(int)((UNSIGNED_BYTE_MASK)&
                                                            (norm32>>CC_SHIFT));
	            p=null;
	        } else {
	            /* c decomposes, get everything from the variable-length extra 
                 * data */
	            pStart=decompose(norm32, args);
	            p=extraData;
                if(args.length==1) {
	                /* fastpath a single code unit from decomposition */
	                c=p[pStart];
	                c2=0;
	                p=null;
	            }
	        }
	
	        /* append the decomposition to the destination buffer, assume 
             * length>0 */
	        if((destIndex+args.length)<=dest.length) {
	            int reorderSplit=destIndex;
	            if(p==null) {
	                /* fastpath: single code point */
	                if(args.cc!=0 && args.cc<prevCC) {
	                    /* (c, c2) is out of order with respect to the preceding
                         *  text */
	                    destIndex+=args.length;
	                    args.trailCC=insertOrdered(dest,reorderStartIndex, 
                                                   reorderSplit, destIndex, 
                                                   c, c2, args.cc);
	                } else {
	                    /* just append (c, c2) */
	                    dest[destIndex++]=c;
	                    if(c2!=0) {
	                        dest[destIndex++]=c2;
	                    }
	                }
	            } else {
	                /* general: multiple code points (ordered by themselves) 
                     * from decomposition */
	                if(args.cc!=0 && args.cc<prevCC) {
	                    /* the decomposition is out of order with respect to 
                         * the preceding text */
	                    destIndex+=args.length;
	                    args.trailCC=mergeOrdered(dest,reorderStartIndex, 
                                                  reorderSplit, p, pStart,
                                                  pStart+args.length);
	                } else {
	                    /* just append the decomposition */
	                    do {
	                        dest[destIndex++]=p[pStart++];
	                    } while(--args.length>0);
	                }
	            }
	        } else {
	            /* buffer overflow */
	            /* keep incrementing the destIndex for preflighting */
	            destIndex+=args.length;
	        }
	
	        prevCC=args.trailCC;
	        if(prevCC==0) {
	            reorderStartIndex=destIndex;
	        }
	    }
	    destIndexArr[0]=destIndex;
	    return prevCC;
	}
	
	public static int makeFCD(char[] src,  int srcStart,  int srcLimit,
                              char[] dest, int destStart, int destLimit,
                              UnicodeSet nx) {
                           
	    int prevSrc, decompStart;
	    int destIndex, length;
	    char c, c2;
	    int /* unsigned int*/ fcd16;
	    int prevCC, cc;
	
	    /* initialize */
	    decompStart=srcStart;
	    destIndex=destStart;
	    prevCC=0;
	    c=0;
	    fcd16=0;
		int[] destIndexArr = new int[1];
        destIndexArr[0]=destIndex;
        
	    for(;;) {
	        /* skip a run of code units below the minimum or with irrelevant 
             * data for the FCD check */
	        prevSrc=srcStart;

            for(;;) {
                if(srcStart==srcLimit) {
                    break;
                } else if((c=src[srcStart])<MIN_WITH_LEAD_CC) {
                    prevCC=(int)-c;
                } else if((fcd16=getFCD16(c))==0) {
                    prevCC=0;
                } else {
                    break;
                }
                ++srcStart;
            }

	
	        /*
	         * prevCC has values from the following ranges:
	         * 0..0xff - the previous trail combining class
	         * <0      - the negative value of the previous code unit;
	         *           that code unit was <_NORM_MIN_WITH_LEAD_CC and its 
             *           getFCD16()
	         *           was deferred so that average text is checked faster
	         */
	
	        /* copy these code units all at once */
	        if(srcStart!=prevSrc) {
	            length=(int)(srcStart-prevSrc);
	            if((destIndex+length)<=destLimit) {
                    System.arraycopy(src,prevSrc,dest,destIndex,length);
	            }
	            destIndex+=length;
	            prevSrc=srcStart;
	
	            /* prevCC<0 is only possible from the above loop, i.e., only if
                 *  prevSrc<src */
	            if(prevCC<0) {
	                /* the previous character was <_NORM_MIN_WITH_LEAD_CC, we 
                     * need to get its trail cc */
	                if(!nx_contains(nx, (int)-prevCC)) {
	                    prevCC=(int)(getFCD16((int)-prevCC)&0xff);
	                } else {
	                    prevCC=0; /* excluded: fcd16==0 */
	                }
	                /*
	                 * set a pointer to this below-U+0300 character;
	                 * if prevCC==0 then it will moved to after this character 
                     * below
	                 */
	                decompStart=prevSrc-1;
	            }
	        }
	        /*
	         * now:
	         * prevSrc==src - used later to adjust destIndex before 
             *          decomposition
	         * prevCC>=0
	         */
	
	        /* end of source reached? */
	        if(srcStart==srcLimit) {
	            break;
	        }
	
	        /* set a pointer to after the last source position where prevCC==0*/
	        if(prevCC==0) {
	            decompStart=prevSrc;
	        }
	
	        /* c already contains *src and fcd16 is set for it, increment src */
	        ++srcStart;
	
	        /* check one above-minimum, relevant code unit */
	        if(UTF16.isLeadSurrogate(c)) {
	            /* c is a lead surrogate, get the real fcd16 */
	            if(srcStart!=srcLimit && 
                                     UTF16.isTrailSurrogate(c2=src[srcStart])) {
	                ++srcStart;
	                fcd16=getFCD16FromSurrogatePair((char)fcd16, c2);
	            } else {
	                c2=0;
	                fcd16=0;
	            }
	        } else {
	            c2=0;
	        }
	
	        /* we are looking at the character (c, c2) at [prevSrc..src[ */
	        if(nx_contains(nx, c, c2)) {
	            fcd16=0; /* excluded: fcd16==0 */
	        }
	        /* check the combining order, get the lead cc */
	        cc=(int)(fcd16>>8);
	        if(cc==0 || cc>=prevCC) {
	            /* the order is ok */
	            if(cc==0) {
	                decompStart=prevSrc;
	            }
	            prevCC=(int)(fcd16&0xff);
	
	            /* just append (c, c2) */
	            length= c2==0 ? 1 : 2;
	            if((destIndex+length)<=destLimit) {
	                dest[destIndex++]=c;
	                if(c2!=0) {
	                    dest[destIndex++]=c2;
	                }
	            } else {
	                destIndex+=length;
	            }
	        } else {
	            /*
	             * back out the part of the source that we copied already but
	             * is now going to be decomposed;
	             * prevSrc is set to after what was copied
	             */
	            destIndex-=(int)(prevSrc-decompStart);
	
	            /*
	             * find the part of the source that needs to be decomposed;
	             * to be safe and simple, decompose to before the next character
                 * with lead cc==0
	             */
	            srcStart=findSafeFCD(src,srcStart, srcLimit, (char)fcd16);
	
	            /*
	             * the source text does not fulfill the conditions for FCD;
	             * decompose and reorder a limited piece of the text
	             */
                destIndexArr[0] = destIndex;
	            prevCC=decomposeFCD(src,decompStart, srcStart,dest, 
                                    destIndexArr,nx);
	            decompStart=srcStart;
                destIndex=destIndexArr[0];
	        }
	    }
        
        return destIndex;
	
	}

	public static int getCombiningClass(int c) {
	    long norm32;
	    norm32=getNorm32(c);
        return (char)((norm32>>CC_SHIFT)&0xFF);
	}
	
	public static boolean isFullCompositionExclusion(int c) {
	    if(isFormatVersion_2_1) {
	        int aux =AuxTrieImpl.auxTrie.getCodePointValue(c);
	        return (boolean)((aux & AUX_COMP_EX_MASK)!=0);
	    } else {
	        return false;
	    }
	}
	
	public static boolean isCanonSafeStart(int c) {
	    if(isFormatVersion_2_1) {
	        int aux = AuxTrieImpl.auxTrie.getCodePointValue(c);
	        return (boolean)((aux & AUX_UNSAFE_MASK)==0);
	    } else {
	        return false;
	    }
	}
	
	public static boolean getCanonStartSet(int c, USerializedSet fillSet) {

	    if(fillSet!=null && canonStartSets!=null) {
	 		/*
	         * binary search for c
	         *
	         * There are two search tables,
	         * one for BMP code points and one for supplementary ones.
	         * See unormimp.h for details.
	         */
	        char[] table;
	        int i=0, start, limit;
	        
            int[] indexes = (int[]) canonStartSets[CANON_SET_INDICIES_INDEX];
            char[] startSets = (char[]) canonStartSets[CANON_SET_START_SETS_INDEX];
            
	        if(c<=0xffff) {
	            table=(char[]) canonStartSets[CANON_SET_BMP_TABLE_INDEX];
	            start=0;
	            limit=table.length;
	
	            /* each entry is a pair { c, result } */
	            while(start<limit-2) {
	                i=(char)(((start+limit)/4)*2); 
	                if(c<table[i]) {
	                    limit=i;
	                } else {
	                    start=i;
	                }
	            }
	            //System.out.println(i);
	            /* found? */
	            if(c==table[start]) {
	                i=table[start+1];
	                if((i & CANON_SET_BMP_MASK)==CANON_SET_BMP_IS_INDEX) {
	                    /* result 01xxxxxx xxxxxx contains index x to a 
                         * USerializedSet */
	                    i&=(CANON_SET_MAX_CANON_SETS-1);
	                    return fillSet.getSet(startSets,(i-indexes.length));
	                } else {
	                    /* other result values are BMP code points for 
                         * single-code point sets */
	                    fillSet.setToOne(i);
	                    return true;
	                }
	            }
	        } else {
	            char high, low, h,j=0;
	
	            table=(char[]) canonStartSets[CANON_SET_SUPP_TABLE_INDEX];
	            start=0;
	            limit=table.length;
	
	            high=(char)(c>>16);
	            low=(char)c;
	
	            /* each entry is a triplet { high(c), low(c), result } */
	            while(start<limit-3) {
                    /* (start+limit)/2 and address triplets */
	                i=(char)(((start+limit)/6)*3);
	                j=(char)(table[i]&0x1f); /* high word */
                    int tableVal = table[i+1];
                    int lowInt = low;
                    if(high<j || ((tableVal>lowInt) && (high==j))) {
                        limit=i;
                    } else {
                        start=i;
                    }
                    
                    //System.err.println("\t((high==j) && (table[i+1]>low)) == " + ((high==j) && (tableVal>lowInt)) );
                    
                    // KLUDGE: IBM JIT in 1.4.0 is sooo broken
					// The below lines make TestExhaustive pass
                    if(ICUDebug.enabled()){
	                    System.err.println("\t\t j = " + Utility.hex(j,4) +
	                                       "\t i = " + Utility.hex(i,4) +
	                                       "\t high = "+ Utility.hex(high)  +
	                                       "\t low = "  + Utility.hex(lowInt,4)   +
	                                       "\t table[i+1]: "+ Utility.hex(tableVal,4) 
	                                       );
                    }
                   
                }

	            /* found? */
	            h=table[start];

                //System.err.println("c: \\U"+ Integer.toHexString(c)+" i : "+Integer.toHexString(i) +" h : " + Integer.toHexString(h));
                int tableVal1 = table[start+1];
                int lowInt = low;

	            if(high==(h&0x1f) && lowInt==tableVal1) {
                    int tableVal2 = table[start+2];
	                i=tableVal2;
	                if((h&0x8000)==0) {
	                    /* the result is an index to a USerializedSet */
	                    return fillSet.getSet(startSets,(i-indexes.length));
	                } else {
	                    /*
	                     * single-code point set {x} in
                         * triplet { 100xxxxx 000hhhhh  llllllll llllllll  xxxxxxxx xxxxxxxx }
	                     */
	                    //i|=((int)h & 0x1f00)<<8; /* add high bits from high(c) */
                        int temp = ((int)h & 0x1f00)<<8;
                        i|=temp; /* add high bits from high(c) */
	                    fillSet.setToOne((int)i);
	                    return true;
	                }
	            }
	        }
	    }
	
	    return false; /* not found */
	}
    
	public static int getFC_NFKC_Closure(int c, char[] dest) {
        
        int destCapacity;
         
        if(dest==null ) {
            destCapacity=0;
        }else{
            destCapacity = dest.length;
        }
        
        int aux =AuxTrieImpl.auxTrie.getCodePointValue(c);

        aux&= AUX_FNC_MASK;
        if(aux!=0) {
            int s;
            int index=aux; 
            int length;
            
            s =extraData[index];
            if(s<0xff00) {
                /* s points to the single-unit string */
                length=1;
            } else {
                length=s&0xff;
                ++index;
            }
            if(0<length && length<=destCapacity) {
                System.arraycopy(extraData,index,dest,0,length);
            }
            return length;
        } else {
            return 0;
        }
    }


    /* Is c an NF<mode>-skippable code point? See unormimp.h. */
    public static boolean isNFSkippable(int c, Normalizer.Mode mode, long mask) {
        long /*unsigned int*/ norm32;
        mask = mask & UNSIGNED_INT_MASK;
        char aux;
   
        /* check conditions (a)..(e), see unormimp.h */
        norm32 = getNorm32(c);

        if((norm32&mask)!=0) {
            return false; /* fails (a)..(e), not skippable */
        }
    
        if(mode == Normalizer.NFD || mode == Normalizer.NFKD || mode == Normalizer.NONE){
            return true; /* NF*D, passed (a)..(c), is skippable */
        }
        /* check conditions (a)..(e), see unormimp.h */

        /* NF*C/FCC, passed (a)..(e) */
        if((norm32& QC_NFD)==0) {
            return true; /* no canonical decomposition, is skippable */
        }
    
        /* check Hangul syllables algorithmically */
        if(isNorm32HangulOrJamo(norm32)) {
            /* Jamo passed (a)..(e) above, must be Hangul */
            return !isHangulWithoutJamoT((char)c); /* LVT are skippable, LV are not */
        }
    
        /* if(mode<=UNORM_NFKC) { -- enable when implementing FCC */
        /* NF*C, test (f) flag */
        if(!isFormatVersion_2_2) {
            return false; /* no (f) data, say not skippable to be safe */
        }
    

        aux = AuxTrieImpl.auxTrie.getCodePointValue(c);
        return (aux&AUX_NFC_SKIP_F_MASK)==0; /* TRUE=skippable if the (f) flag is not set */
    
        /* } else { FCC, test fcd<=1 instead of the above } */
    }
    
    /*
        private static final boolean
    _enumPropertyStartsRange(const void *context, UChar32 start, UChar32 limit, uint32_t value) {
        // add the start code point to the USet 
        uset_add((USet *)context, start);
        return TRUE;
    }
    */

    public static UnicodeSet addPropertyStarts(UnicodeSet set) {
        int c;
       
        /* add the start code point of each same-value range of each trie */
        //utrie_enum(&normTrie, NULL, _enumPropertyStartsRange, set);
        TrieIterator normIter = new TrieIterator(NormTrieImpl.normTrie);
        RangeValueIterator.Element normResult = new RangeValueIterator.Element();
        
        while(normIter.next(normResult)){
            set.add(normResult.start);
        }
        
        //utrie_enum(&fcdTrie, NULL, _enumPropertyStartsRange, set);
        TrieIterator fcdIter  = new TrieIterator(FCDTrieImpl.fcdTrie);
        RangeValueIterator.Element fcdResult = new RangeValueIterator.Element();

        while(fcdIter.next(fcdResult)){
            set.add(fcdResult.start);
        }
        
        if(isFormatVersion_2_1){
            //utrie_enum(&auxTrie, NULL, _enumPropertyStartsRange, set);
            TrieIterator auxIter  = new TrieIterator(AuxTrieImpl.auxTrie);
            RangeValueIterator.Element auxResult = new RangeValueIterator.Element();
            while(auxIter.next(auxResult)){
                set.add(auxResult.start);
            }
        }
        /* add Hangul LV syllables and LV+1 because of skippables */
        for(c=HANGUL_BASE; c<HANGUL_BASE+HANGUL_COUNT; c+=JAMO_T_COUNT) {
            set.add(c);
            set.add(c+1);
        }
        set.add(HANGUL_BASE+HANGUL_COUNT); /* add Hangul+1 to continue with other properties */
        return set; // for chaining
    }
    /**
	 * Internal API, used by collation code.
	 * Get access to the internal FCD trie table to be able to perform
	 * incremental, per-code unit, FCD checks in collation.
	 * One pointer is sufficient because the trie index values are offset
	 * by the index size, so that the same pointer is used to access the trie 
     * data.
	 * @internal
	 */
    ///CLOVER:OFF
	public CharTrie getFCDTrie(){
		return FCDTrieImpl.fcdTrie;
	}
    ///CLOVER:ON


    
   /* compare canonically equivalent ---------------------------------------- */

	/*
	 * Compare two strings for canonical equivalence.
	 * Further options include case-insensitive comparison and
	 * code point order (as opposed to code unit order).
	 *
	 * In this function, canonical equivalence is optional as well.
	 * If canonical equivalence is tested, then both strings must fulfill
	 * the FCD check.
	 *
	 * Semantically, this is equivalent to
	 *   strcmp[CodePointOrder](foldCase(NFD(s1)), foldCase(NFD(s2)))
	 * where code point order, NFD and foldCase are all optional.
	 *
	 * String comparisons almost always yield results before processing both 
     * strings completely.
	 * They are generally more efficient working incrementally instead of
	 * performing the sub-processing (strlen, normalization, case-folding)
	 * on the entire strings first.
	 *
	 * It is also unnecessary to not normalize identical characters.
	 *
	 * This function works in principle as follows:
	 *
	 * loop {
	 *   get one code unit c1 from s1 (-1 if end of source)
	 *   get one code unit c2 from s2 (-1 if end of source)
	 *
	 *   if(either string finished) {
	 *     return result;
	 *   }
	 *   if(c1==c2) {
	 *     continue;
	 *   }
	 *
	 *   // c1!=c2
	 *   try to decompose/case-fold c1/c2, and continue if one does;
	 *
	 *   // still c1!=c2 and neither decomposes/case-folds, return result
	 *   return c1-c2;
	 * }
	 *
	 * When a character decomposes, then the pointer for that source changes to
	 * the decomposition, pushing the previous pointer onto a stack.
	 * When the end of the decomposition is reached, then the code unit reader
	 * pops the previous source from the stack.
	 * (Same for case-folding.)
	 *
	 * This is complicated further by operating on variable-width UTF-16.
	 * The top part of the loop works on code units, while lookups for decomposition
	 * and case-folding need code points.
	 * Code points are assembled after the equality/end-of-source part.
	 * The source pointer is only advanced beyond all code units when the code point
	 * actually decomposes/case-folds.
	 *
	 * If we were on a trail surrogate unit when assembling a code point,
	 * and the code point decomposes/case-folds, then the decomposition/folding
	 * result must be compared with the part of the other string that corresponds to
	 * this string's lead surrogate.
	 * Since we only assemble a code point when hitting a trail unit when the
	 * preceding lead units were identical, we back up the other string by one unit
	 * in such a case.
	 *
	 * The optional code point order comparison at the end works with
	 * the same fix-up as the other code point order comparison functions.
	 * See ustring.c and the comment near the end of this function.
	 *
	 * Assumption: A decomposition or case-folding result string never contains
	 * a single surrogate. This is a safe assumption in the Unicode Standard.
	 * Therefore, we do not need to check for surrogate pairs across
	 * decomposition/case-folding boundaries.
	 * Further assumptions (see verifications tstnorm.cpp):
	 * The API function checks for FCD first, while the core function
	 * first case-folds and then decomposes. This requires that case-folding does not
	 * un-FCD any strings.
	 *
	 * The API function may also NFD the input and turn off decomposition.
	 * This requires that case-folding does not un-NFD strings either.
	 *
	 * TODO If any of the above two assumptions is violated,
	 * then this entire code must be re-thought.
	 * If this happens, then a simple solution is to case-fold both strings up front
	 * and to turn off UNORM_INPUT_IS_FCD.
	 * We already do this when not both strings are in FCD because makeFCD
	 * would be a partial NFD before the case folding, which does not work.
	 * Note that all of this is only a problem when case-folding _and_
	 * canonical equivalence come together.
     * 
	 * This function could be moved to a different source file, at increased cost
	 * for calling the decomposition access function.
	 */
	
	// stack element for previous-level source/decomposition pointers
	private static class CmpEquivLevel {
        char[] source;
	    int start;
        int s;
        int limit;
	}
    
	/**
	 * Get the canonical decomposition for one code point.
	 * @param c code point
	 * @param buffer out-only buffer for algorithmic decompositions of Hangul
	 * @param length out-only, takes the length of the decomposition, if any
	 * @return index into the extraData array, or 0 if none
	 * @internal
	 */
	 private static int decompose(int c, char[] buffer) {
	    
        long norm32;
	    int length=0;
	    norm32 = (long) ((UNSIGNED_INT_MASK) & NormTrieImpl.normTrie.getCodePointValue(c));
	    if((norm32 & QC_NFD)!=0) {
	        if(isNorm32HangulOrJamo(norm32)) {
	            /* Hangul syllable: decompose algorithmically */
	            char c2;
	
	            c-=HANGUL_BASE;
	
	            c2=(char)(c%JAMO_T_COUNT);
	            c/=JAMO_T_COUNT;
	            if(c2>0) {
	                buffer[2]=(char)(JAMO_T_BASE+c2);
	                length=3;
	            } else {
	                length=2;
	            }
	            buffer[1]=(char)(JAMO_V_BASE+c%JAMO_V_COUNT);
	            buffer[0]=(char)(JAMO_L_BASE+c/JAMO_V_COUNT);
	            return length;
	        } else {
	            /* normal decomposition */
	            DecomposeArgs  args = new DecomposeArgs();
	            int index = decompose(norm32, args);
                System.arraycopy(extraData,index,buffer,0,args.length);
                return args.length ;
	        }
	    } else {
	        return 0;
	    }
	}

    private static int foldCase(int c, char[] dest, int destStart, int destLimit,
                         		int options){
        String src = UTF16.valueOf(c);
        String foldedStr = UCharacter.foldCase(src,options);
        char[] foldedC = foldedStr.toCharArray();
        for(int i=0;i<foldedC.length;i++){
            if(destStart<destLimit){
                dest[destStart]=foldedC[i];
            }
            // always increment destStart so that we can return 
            // the required length
            destStart++;
        }
        return (c==UTF16.charAt(foldedStr,0)) ? -destStart : destStart;
    }
    
    /*
     private static int foldCase(char[] src,int srcStart,int srcLimit,
                                char[] dest, int destStart, int destLimit,
                                int options){
        String source =new String(src,srcStart,(srcLimit-srcStart));
        String foldedStr = UCharacter.foldCase(source,options);
        char[] foldedC = foldedStr.toCharArray();
        for(int i=0;i<foldedC.length;i++){
            if(destStart<destLimit){
                dest[destStart]=foldedC[i];
            }
            // always increment destStart so that we can return 
            // the required length
            destStart++;
            
        }
        return destStart;
    }
    */
    public static int cmpEquivFold(String s1, String s2,int options){
        return cmpEquivFold(s1.toCharArray(),0,s1.length(),
                            s2.toCharArray(),0,s2.length(),
                            options);
    }
    
    
	// internal function
    public static int cmpEquivFold(char[] s1, int s1Start,int s1Limit,
	                               char[] s2, int s2Start,int s2Limit,
	                               int options) {
	    // current-level start/limit - s1/s2 as current
	    int start1, start2, limit1, limit2;
	    char[] cSource1, cSource2;
        
        cSource1 = s1;
        cSource2 = s2;
	    // decomposition variables
	    int length;
	
	    // stacks of previous-level start/current/limit
	    CmpEquivLevel[] stack1 = new CmpEquivLevel[]{ 
                                                    new CmpEquivLevel(),
                                                    new CmpEquivLevel()
                                                  };
        CmpEquivLevel[] stack2 = new CmpEquivLevel[]{ 
                                                    new CmpEquivLevel(),
                                                    new CmpEquivLevel()
                                                  };
	
	    // decomposition buffers for Hangul
	    char[] decomp1 = new char[8];
        char[] decomp2 = new char[8];
	
	    // case folding buffers, only use current-level start/limit
	    char[] fold1 = new char[32];
        char[] fold2 = new char[32];
	
	    // track which is the current level per string
	    int level1, level2;
	
	    // current code units, and code points for lookups
	    int c1, c2;
        int cp1, cp2;
	
	    // no argument error checking because this itself is not an API
	
	    // assume that at least one of the options COMPARE_EQUIV and 
        // COMPARE_IGNORE_CASE is set
	    // otherwise this function must behave exactly as uprv_strCompare()
	    // not checking for that here makes testing this function easier

	
	    // initialize
	    start1=s1Start;
	    limit1=s1Limit;
	    
	    start2=s2Start;
	    limit2=s2Limit;
	    
	    level1=level2=0;
	    c1=c2=-1;
	    cp1=cp2=-1;
	    // comparison loop
	    for(;;) {
	        // here a code unit value of -1 means "get another code unit"
	        // below it will mean "this source is finished"
	
	        if(c1<0) {
	            // get next code unit from string 1, post-increment
	            for(;;) {
	                if(s1Start>=limit1) {
	                    if(level1==0) {
	                        c1=-1;
	                        break;
	                    }
	                } else {
                        c1=cSource1[s1Start];
	                    ++s1Start;
	                    break;
	                }
	
	                // reached end of level buffer, pop one level
	                do {
	                    --level1;
	                    start1=stack1[level1].start;
	                } while(start1==-1); //###### check this
	                s1Start=stack1[level1].s;
	                limit1=stack1[level1].limit;
                    cSource1=stack1[level1].source;
	            }
	        }
	
	        if(c2<0) {
	            // get next code unit from string 2, post-increment
	            for(;;) {                    
	                if(s2Start>=limit2) {
	                    if(level2==0) {
	                        c2=-1;
	                        break;
	                    }
	                } else {
                        c2=cSource2[s2Start];
	                    ++s2Start;
	                    break;
	                }
	
	                // reached end of level buffer, pop one level
	                do {
	                    --level2;
	                    start2=stack2[level2].start;
	                } while(start2==-1);
	                s2Start=stack2[level2].s;
	                limit2=stack2[level2].limit;
                    cSource2=stack2[level2].source;
	            }
	        }
	
	        // compare c1 and c2
	        // either variable c1, c2 is -1 only if the corresponding string 
            // is finished
	        if(c1==c2) {
	            if(c1<0) {
	                return 0;   // c1==c2==-1 indicating end of strings
	            }
	            c1=c2=-1;       // make us fetch new code units
	            continue;
	        } else if(c1<0) {
	            return -1;      // string 1 ends before string 2
	        } else if(c2<0) {
	            return 1;       // string 2 ends before string 1
	        }
	        // c1!=c2 && c1>=0 && c2>=0
	
	        // get complete code points for c1, c2 for lookups if either is a 
            // surrogate
            cp1=c1;
	        if(UTF16.isSurrogate((char)c1)) { 
	            char c;
	
	            if(UTF16.isLeadSurrogate((char)c1)) {
	                if(    s1Start!=limit1 && 
                           UTF16.isTrailSurrogate(c=cSource1[s1Start])
                      ) {
	                    // advance ++s1; only below if cp1 decomposes/case-folds
	                    cp1=UCharacterProperty.getRawSupplementary((char)c1, c);
	                }
	            } else /* isTrail(c1) */ {
	                if(    start1<=(s1Start-2) && 
                            UTF16.isLeadSurrogate(c=cSource1[(s1Start-2)])
                      ) {
	                    cp1=UCharacterProperty.getRawSupplementary(c, (char)c1);
	                }
	            }
	        }
	        cp2=c2;
	        if(UTF16.isSurrogate((char)c2)) {
	            char c;
	
	            if(UTF16.isLeadSurrogate((char)c2)) {
	                if(    s2Start!=limit2 && 
                           UTF16.isTrailSurrogate(c=cSource2[s2Start])
                      ) {
	                    // advance ++s2; only below if cp2 decomposes/case-folds
	                    cp2=UCharacterProperty.getRawSupplementary((char)c2, c);
	                }
	            } else /* isTrail(c2) */ {
	                if(    start2<=(s2Start-2) &&  
                           UTF16.isLeadSurrogate(c=cSource2[s2Start-2])
                      ) {
	                    cp2=UCharacterProperty.getRawSupplementary(c, (char)c2);
	                }
	            }
	        }
	
	        // go down one level for each string
	        // continue with the main loop as soon as there is a real change
	        if( level1<2 && ((options & Normalizer.COMPARE_IGNORE_CASE)!=0)&&
                (length=foldCase(cp1, fold1, 0,32,options))>=0
            ) {
                // cp1 case-folds to fold1[length]
                if(UTF16.isSurrogate((char)c1)) {
                    if(UTF16.isLeadSurrogate((char)c1)) {
                        // advance beyond source surrogate pair if it 
                        // case-folds
                        ++s1Start;
                    } else /* isTrail(c1) */ {
                        // we got a supplementary code point when hitting its 
                        // trail surrogate, therefore the lead surrogate must 
                        // have been the same as in the other string;
                        // compare this decomposition with the lead surrogate
                        // in the other string
                        --s2Start;
                        c2=cSource2[(s2Start-1)];
                    }
                }
    
                // push current level pointers
                stack1[0].start=start1;
                stack1[0].s=s1Start;
                stack1[0].limit=limit1;
                stack1[0].source=cSource1;
                ++level1;
    
                cSource1 = fold1;
                start1=s1Start=0;
                limit1=length;
    
                // get ready to read from decomposition, continue with loop
                c1=-1;
                continue;
            }
    
            if( level2<2 && ((options& Normalizer.COMPARE_IGNORE_CASE)!=0) &&
                (length=foldCase(cp2, fold2,0,32, options))>=0
            ) {
                // cp2 case-folds to fold2[length]
                if(UTF16.isSurrogate((char)c2)) {
                    if(UTF16.isLeadSurrogate((char)c2)) {
                        // advance beyond source surrogate pair if it 
                        // case-folds
                        ++s2Start;
                    } else /* isTrail(c2) */ {
                        // we got a supplementary code point when hitting its 
                        // trail surrogate, therefore the lead surrogate must 
                        // have been the same as in the other string;
                        // compare this decomposition with the lead surrogate 
                        // in the other string
                        --s1Start;
                        c1=cSource1[(s1Start-1)];
                    }
                }
    
                // push current level pointers
                stack2[0].start=start2;
                stack2[0].s=s2Start;
                stack2[0].limit=limit2;
                stack2[0].source=cSource2;
                ++level2;
                
                cSource2 = fold2;
                start2=s2Start=0;
                limit2=length;
    
                // get ready to read from decomposition, continue with loop
                c2=-1;
                continue;
            }
            
	        if( level1<2 && ((options&COMPARE_EQUIV)!=0) &&
	            0!=(length=decompose(cp1,decomp1))
	        ) {
	            // cp1 decomposes into p[length]
	            if(UTF16.isSurrogate((char)c1)) {
	                if(UTF16.isLeadSurrogate((char)c1)) {
	                    // advance beyond source surrogate pair if it 
                        //decomposes
	                    ++s1Start;
	                } else /* isTrail(c1) */ {
	                    // we got a supplementary code point when hitting 
                        // its trail surrogate, therefore the lead surrogate 
                        // must have been the same as in the other string;
	                    // compare this decomposition with the lead surrogate 
                        // in the other string
	                    --s2Start;
	                    c2=cSource2[(s2Start-1)];
	                }
	            }
	
	            // push current level pointers
                stack1[level1].start=start1;
	            stack1[level1].s=s1Start;
	            stack1[level1].limit=limit1;
                stack1[level1].source=cSource1;
	            ++level1;
	
	            // set next level pointers to decomposition
	            cSource1 = decomp1;
                start1=s1Start=0;
	            limit1=length;
	            
                // set empty intermediate level if skipped
                if(level1<2) {
                    stack1[level1++].start=-1;
                }
	            // get ready to read from decomposition, continue with loop
	            c1=-1;
	            continue;
	        }
	
	        if( level2<2 && ((options&COMPARE_EQUIV)!=0) &&
	            0!=(length=decompose(cp2, decomp2))
	        ) {
	            // cp2 decomposes into p[length]
	            if(UTF16.isSurrogate((char)c2)) {
	                if(UTF16.isLeadSurrogate((char)c2)) {
	                    // advance beyond source surrogate pair if it 
                        // decomposes
	                    ++s2Start;
	                } else /* isTrail(c2) */ {
	                    // we got a supplementary code point when hitting its 
                        // trail surrogate, therefore the lead surrogate must 
                        // have been the same as in the other string;
	                    // compare this decomposition with the lead surrogate 
                        // in the other string
	                    --s1Start;
	                    c1=cSource1[(s1Start-1)];
	                }
	            }
	
	            // push current level pointers
	            stack2[level2].start=start2;
	            stack2[level2].s=s2Start;
	            stack2[level2].limit=limit2;
                stack2[level2].source=cSource2;
	            ++level2;
	
	            // set next level pointers to decomposition
	            cSource2=decomp2;
                start2=s2Start=0;
	            limit2=length;
	            
                // set empty intermediate level if skipped
                if(level2<2) {
                    stack2[level2++].start=-1;
                }
	            
                // get ready to read from decomposition, continue with loop
	            c2=-1;
	            continue;
	        }
	
	
	        // no decomposition/case folding, max level for both sides:
	        // return difference result
	
	        // code point order comparison must not just return cp1-cp2
	        // because when single surrogates are present then the surrogate 
	        // pairs that formed cp1 and cp2 may be from different string 
            // indexes
	
	        // example: { d800 d800 dc01 } vs. { d800 dc00 }, compare at 
            // second code units
	        // c1=d800 cp1=10001 c2=dc00 cp2=10000
	        // cp1-cp2>0 but c1-c2<0 and in fact in UTF-32 
            // it is { d800 10001 } < { 10000 }
	        // therefore fix-up 
	
	        if(     c1>=0xd800 && c2>=0xd800 && 
                    ((options&Normalizer.COMPARE_CODE_POINT_ORDER)!=0)
              ) {
	            /* subtract 0x2800 from BMP code points to make them smaller 
                 * than supplementary ones */
	            if(
	                (    c1<=0xdbff && s1Start!=limit1 
                         && 
                         UTF16.isTrailSurrogate(cSource1[s1Start])
                    ) 
                     ||
	                (    UTF16.isTrailSurrogate((char)c1) && start1!=(s1Start-1) 
                         && 
                         UTF16.isLeadSurrogate(cSource1[(s1Start-2)])
                    )
	            ) {
	                /* part of a surrogate pair, leave >=d800 */
	            } else {
	                /* BMP code point - may be surrogate code point - 
                     * make <d800 */
	                c1-=0x2800;
	            }
	
	            if(
	                (    c2<=0xdbff && s2Start!=limit2 
                         && 
                         UTF16.isTrailSurrogate(cSource2[s2Start])
                    ) 
                     ||
	                (    UTF16.isTrailSurrogate((char)c2) && start2!=(s2Start-1) 
                         && 
                         UTF16.isLeadSurrogate(cSource2[(s2Start-2)])
                    )
	            ) {
	                /* part of a surrogate pair, leave >=d800 */
	            } else {
	                /* BMP code point - may be surrogate code point - 
                     * make <d800 */
	                c2-=0x2800;
	            }
	        }
	
	        return c1-c2;
	    }
	}
    private static int strCompare(char[] s1, int s1Start, int s1Limit,
                                  char[] s2, int s2Start, int s2Limit,
                                  boolean codePointOrder) {
                        
        int start1, start2, limit1, limit2;
 
        char c1, c2;
    
        /* setup for fix-up */
        start1=s1Start;
        start2=s2Start;
        
        int length1, length2;
        
        length1 = s1Limit - s1Start;
        length2 = s2Limit - s2Start;
            
        int lengthResult;

        if(length1<length2) {
            lengthResult=-1;
            limit1=start1+length1;
        } else if(length1==length2) {
            lengthResult=0;
            limit1=start1+length1;
        } else /* length1>length2 */ {
            lengthResult=1;
            limit1=start1+length2;
        }

        if(s1==s2) {
            return lengthResult;
        }

        for(;;) {
            /* check pseudo-limit */
            if(s1Start==limit1) {
                return lengthResult;
            }

            c1=s1[s1Start];
            c2=s2[s2Start];
            if(c1!=c2) {
                break;
            }
            ++s1Start;
            ++s2Start;
        }

        /* setup for fix-up */
        limit1=start1+length1;
        limit2=start2+length2;

    
        /* if both values are in or above the surrogate range, fix them up */
        if(c1>=0xd800 && c2>=0xd800 && codePointOrder) {
            /* subtract 0x2800 from BMP code points to make them smaller than
             *  supplementary ones */
            if(
                ( c1<=0xdbff && (s1Start+1)!=limit1 && 
                  UTF16.isTrailSurrogate(s1[(s1Start+1)])
                ) ||
                ( UTF16.isTrailSurrogate(c1) && start1!=s1Start && 
                  UTF16.isLeadSurrogate(s1[(s1Start-1)])
                )
            ) {
                /* part of a surrogate pair, leave >=d800 */
            } else {
                /* BMP code point - may be surrogate code point - make <d800 */
                c1-=0x2800;
            }
    
            if(
                ( c2<=0xdbff && (s2Start+1)!=limit2 && 
                  UTF16.isTrailSurrogate(s2[(s2Start+1)])
                ) ||
                ( UTF16.isTrailSurrogate(c2) && start2!=s2Start && 
                  UTF16.isLeadSurrogate(s2[(s2Start-1)])
                )
            ) {
                /* part of a surrogate pair, leave >=d800 */
            } else {
                /* BMP code point - may be surrogate code point - make <d800 */
                c2-=0x2800;
            }
        }
    
        /* now c1 and c2 are in UTF-32-compatible order */
        return (int)c1-(int)c2;
    }


	/*
	 * Status of tailored normalization
	 *
	 * This was done initially for investigation on Unicode public review issue 7
	 * (http://www.unicode.org/review/). See Jitterbug 2481.
	 * While the UTC at meeting #94 (2003mar) did not take up the issue, this is
	 * a permanent feature in ICU 2.6 in support of IDNA which requires true
	 * Unicode 3.2 normalization.
	 * (NormalizationCorrections are rolled into IDNA mapping tables.)
	 *
	 * Tailored normalization as implemented here allows to "normalize less"
	 * than full Unicode normalization would.
	 * Based internally on a UnicodeSet of code points that are
	 * "excluded from normalization", the normalization functions leave those
	 * code points alone ("inert"). This means that tailored normalization
	 * still transforms text into a canonically equivalent form.
	 * It does not add decompositions to code points that do not have any or
	 * change decomposition results.
	 *
	 * Any function that searches for a safe boundary has not been touched,
	 * which means that these functions will be over-pessimistic when
	 * exclusions are applied.
	 * This should not matter because subsequent checks and normalizations
	 * do apply the exclusions; only a little more of the text may be processed
	 * than necessary under exclusions.
	 *
	 * Normalization exclusions have the following effect on excluded code points c:
	 * - c is not decomposed
	 * - c is not a composition target
	 * - c does not combine forward or backward for composition
	 *   except that this is not implemented for Jamo
	 * - c is treated as having a combining class of 0
	 */
	 
	/* ### TODO prototype 
	 * Constants for the bit fields in the options bit set parameter. 
	 * These need not be public. 
	 * A user only needs to know the currently assigned values. 
	 * The number and positions of reserved bits per field can remain private. 
	 */ 
     private static final int OPTIONS_NX_MASK=0x1f;
     private static final int OPTIONS_UNICODE_MASK=0xe0; 
     private static final int OPTIONS_SETS_MASK=0xff;
     private static final int OPTIONS_UNICODE_SHIFT=5;  
     private static final UnicodeSet[] nxCache = new UnicodeSet[OPTIONS_SETS_MASK+1];
     
	/* Constants for options flags for normalization.*/

    /** 
     * Options bit 0, do not decompose Hangul syllables. 
     * @draft ICU 2.6 
     */
    private static final int NX_HANGUL = 1;
    /** 
     * Options bit 1, do not decompose CJK compatibility characters.
     * @draft ICU 2.6 
     */
    private static final int NX_CJK_COMPAT=2;
	/* normalization exclusion sets --------------------------------------------- */
	
	/*
	 * Normalization exclusion UnicodeSets are used for tailored normalization;
	 * see the comment near the beginning of this file.
	 *
	 * By specifying one or several sets of code points,
	 * those code points become inert for normalization.
	 */
	private static final synchronized UnicodeSet internalGetNXHangul() {
	    /* internal function, does not check for incoming U_FAILURE */
	
	    if(nxCache[NX_HANGUL]==null) {
	         nxCache[NX_HANGUL]=new UnicodeSet(0xac00, 0xd7a3);
	    }
	    return nxCache[NX_HANGUL];
	}
    
	private static final synchronized UnicodeSet internalGetNXCJKCompat() {
	    /* internal function, does not check for incoming U_FAILURE */
	
	    if(nxCache[NX_CJK_COMPAT]==null) {

	        /* build a set from [CJK Ideographs]&[has canonical decomposition] */
	        UnicodeSet set, hasDecomp;
	
	        set=new UnicodeSet("[:Ideographic:]");
	
	        /* start with an empty set for [has canonical decomposition] */
	        hasDecomp=new UnicodeSet();
	
	        /* iterate over all ideographs and remember which canonically decompose */
	        UnicodeSetIterator it = new UnicodeSetIterator(set);
	        int start, end;
	        long norm32;
	
	        while(it.nextRange() && (it.codepoint != UnicodeSetIterator.IS_STRING)) {
	            start=it.codepoint;
	            end=it.codepointEnd;
	            while(start<=end) {
	                norm32 = getNorm32(start);
	                if((norm32 & QC_NFD)>0) {
	                    hasDecomp.add(start);
	                }
	                ++start;
	            }
	        }
	
	        /* hasDecomp now contains all ideographs that decompose canonically */
 	        nxCache[NX_CJK_COMPAT]=hasDecomp;
         
	    }
	
	    return nxCache[NX_CJK_COMPAT];
	}
	
	private static final synchronized UnicodeSet internalGetNXUnicode(int options) {
	    options &= OPTIONS_UNICODE_MASK;
	    if(options==0) {
	        return null;
	    }
	
	    if(nxCache[options]==null) {
	        /* build a set with all code points that were not designated by the specified Unicode version */
	        UnicodeSet set = new UnicodeSet();

	        switch(options) {
	        case Normalizer.UNICODE_3_2:
	            set.applyPattern("[:^Age=3.2:]");
	            break;
	        default:
	            return null;
	        }
            
	        nxCache[options]=set;
	    }
	
	    return nxCache[options];
	}
	
	/* Get a decomposition exclusion set. The data must be loaded. */
	private static final synchronized UnicodeSet internalGetNX(int options) {
	    options&=OPTIONS_SETS_MASK;
	
	    if(nxCache[options]==null) {
	        /* return basic sets */	        
            if(options==NX_HANGUL) {
	            return internalGetNXHangul();
	        }
	        if(options==NX_CJK_COMPAT) {
	            return internalGetNXCJKCompat();
	        }
	        if((options & OPTIONS_UNICODE_MASK)!=0 && (options & OPTIONS_NX_MASK)==0) {
	            return internalGetNXUnicode(options);
	        }
	
	        /* build a set from multiple subsets */
	        UnicodeSet set;
	        UnicodeSet other;
	
	        set=new UnicodeSet();

	
	        if((options & NX_HANGUL)!=0 && null!=(other=internalGetNXHangul())) {
	            set.addAll(other);
	        }
	        if((options&NX_CJK_COMPAT)!=0 && null!=(other=internalGetNXCJKCompat())) {
	            set.addAll(other);
	        }
	        if((options&OPTIONS_UNICODE_MASK)!=0 && null!=(other=internalGetNXUnicode(options))) {
	            set.addAll(other);
	        }

   	        nxCache[options]=set;
        }
	    return nxCache[options];
	}
	
	public static final UnicodeSet getNX(int options) {
	    if((options&=OPTIONS_SETS_MASK)==0) {
	        /* incoming failure, or no decomposition exclusions requested */
	        return null;
	    } else {
	        return internalGetNX(options);
	    }
	}
	
	private static final boolean nx_contains(UnicodeSet nx, int c) {
	    return nx!=null && nx.contains(c);
	}
	
	private static final boolean nx_contains(UnicodeSet nx, char c, char c2) {
	    return nx!=null && nx.contains(c2==0 ? c : UCharacterProperty.getRawSupplementary(c, c2));
	}


}
