 /*
 *******************************************************************************
 * Copyright (C) 1996-2004, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
 
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.util.UResourceBundle;
import com.ibm.icu.util.VersionInfo;
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 = ICUResourceBundle.ICU_BUNDLE+"/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;
	    }
	}
		 
	/****************************************************/
	
	
	private static FCDTrieImpl fcdTrieImpl;
	private static NormTrieImpl normTrieImpl;
	private static AuxTrieImpl auxTrieImpl;
	private static int[] indexes;
	private static char[] combiningTable;
	private static char[] extraData;
	private static Object[] canonStartSets;
	
	private static boolean isDataLoaded;
	private static boolean isFormatVersion_2_1;
    private static boolean isFormatVersion_2_2;
    private static byte[] unicodeVersion;
    
	/**
     * 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 = ICUData.getRequiredStream(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)
                                 );
            unicodeVersion = reader.getUnicodeVersion();
            b.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 VersionInfo getUnicodeVersion(){
        return VersionInfo.getInstance(unicodeVersion[0], unicodeVersion[1],
                                       unicodeVersion[2], unicodeVersion[3]);
    }
	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 srcStart,int srcLimit,
								char[] dest,int destStart,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;
        int destIndex = destStart;
        int srcIndex = srcStart;
	    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 - destStart;
	}
	
	/* 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 srcStart, int srcLimit,
                              char[] dest,int destStart,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];
        int destIndex = destStart;
        int srcIndex = srcStart;
        
        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 - destStart;
    }
	/* 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 - destStart;
	
	}

	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 in UCharacter.getIntPropertyValue().
     * @internal
     * @param c code point
     * @param modeValue numeric value compatible with Mode
     * @return numeric value compatible with QuickCheck
     */
    public static final int quickCheck(int c, int modeValue) {
        final int qcMask[/*UNORM_MODE_COUNT*/]={
            0, 0, QC_NFD, QC_NFKD, QC_NFC, QC_NFKC
        };

        int norm32=(int)getNorm32(c)&qcMask[modeValue];

        if(norm32==0) {
            return 1; // YES
        } else if((norm32&QC_ANY_NO)!=0) {
            return 0; // NO
        } else /* _NORM_QC_ANY_MAYBE */ {
            return 2; // MAYBE;
        }
    }

    /**
	 * 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));
	}


}
