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

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

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

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

    public static final int QC_MASK=0x3f;

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

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

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

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


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


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

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

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

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

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

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

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

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

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

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

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

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

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

	
	public static int decompose(char[] src,int 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 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));
	}


}
