 /*
 *******************************************************************************
 * Copyright (C) 1996-2005, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
 
package com.ibm.icu.impl;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.MissingResourceException;

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

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

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

    public static final int QC_MASK=0x3f;

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

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

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

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


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


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

            byte[] fcdBytes = new byte[indexes[NormalizerImpl.INDEX_FCD_TRIE_SIZE]];
            byte[] auxBytes = new byte[indexes[NormalizerImpl.INDEX_AUX_TRIE_SIZE]];
            canonStartSets=new Object[NormalizerImpl.CANON_SET_MAX_CANON_SETS];
            
            fcdTrieImpl = new FCDTrieImpl();
            normTrieImpl = new NormTrieImpl();
            auxTrieImpl = new AuxTrieImpl();
                        
            // load the rest of the data data and initialize the data members
            reader.read(normBytes, fcdBytes,auxBytes, extraData, combiningTable, 
                        canonStartSets);
                                       
            NormTrieImpl.normTrie = new IntTrie( new ByteArrayInputStream(normBytes),normTrieImpl );
            FCDTrieImpl.fcdTrie   = new CharTrie( new ByteArrayInputStream(fcdBytes),fcdTrieImpl  );
            AuxTrieImpl.auxTrie   = new CharTrie( new ByteArrayInputStream(auxBytes),auxTrieImpl  );
            
            // we reached here without any exceptions so the data is fully 
            // loaded set the variable to true
            isDataLoaded = true;
            
            // get the data format version                           
            byte[] formatVersion = reader.getDataFormatVersion();
            
            isFormatVersion_2_1 =( formatVersion[0]>2 
                                    ||
                                   (formatVersion[0]==2 && formatVersion[1]>=1)
                                 );
            isFormatVersion_2_2 =( formatVersion[0]>2 
                                    ||
                                   (formatVersion[0]==2 && formatVersion[1]>=2)
                                 );
            unicodeVersion = reader.getUnicodeVersion();
            b.close();
        }
    }
        
    /* ---------------------------------------------------------------------- */
    
    /* Korean Hangul and Jamo constants */
    
    public static final int JAMO_L_BASE=0x1100;     /* "lead" jamo */
    public static final int JAMO_V_BASE=0x1161;     /* "vowel" jamo */
    public static final int JAMO_T_BASE=0x11a7;     /* "trail" jamo */
    
    public static final int HANGUL_BASE=0xac00;
    
    public static final int JAMO_L_COUNT=19;
    public static final int JAMO_V_COUNT=21;
    public static final int JAMO_T_COUNT=28;
    public  static final int HANGUL_COUNT=JAMO_L_COUNT*JAMO_V_COUNT*JAMO_T_COUNT;
    
    private static boolean isHangulWithoutJamoT(char c) {
        c-=HANGUL_BASE;
        return c<HANGUL_COUNT && c%JAMO_T_COUNT==0;
    }
    
    /* norm32 helpers */
    
    /* is this a norm32 with a regular index? */
    private static boolean isNorm32Regular(long norm32) {
        return norm32<MIN_SPECIAL;
    }
    
    /* is this a norm32 with a special index for a lead surrogate? */
    private static boolean isNorm32LeadSurrogate(long norm32) {
        return MIN_SPECIAL<=norm32 && norm32<SURROGATES_TOP;
    }
    
    /* is this a norm32 with a special index for a Hangul syllable or a Jamo? */
    private static boolean isNorm32HangulOrJamo(long norm32) {
        return norm32>=MIN_HANGUL;
    }
    
    /*
     * Given isNorm32HangulOrJamo(),
     * is this a Hangul syllable or a Jamo?
     */
     ///CLOVER:OFF
    private static  boolean isHangulJamoNorm32HangulOrJamoL(long norm32) {
        return norm32<MIN_JAMO_V;
    }
    ///CLOVER:ON
    
    /*
     * Given norm32 for Jamo V or T,
     * is this a Jamo V?
     */
    private static boolean isJamoVTNorm32JamoV(long norm32) {
        return norm32<JAMO_V_TOP;
    }
    
    /* data access primitives ----------------------------------------------- */
    
    public static long/*unsigned*/ getNorm32(char c) {
        return ((UNSIGNED_INT_MASK) & (NormTrieImpl.normTrie.getLeadValue(c)));
    }
    
    public static long/*unsigned*/ getNorm32FromSurrogatePair(long norm32, 
                                                               char c2) {
        /*
         * the surrogate index in norm32 stores only the number of the surrogate
         * index block see gennorm/store.c/getFoldedNormValue()
         */
        return ((UNSIGNED_INT_MASK) & 
                    NormTrieImpl.normTrie.getTrailValue((int)norm32, c2));
    }
    ///CLOVER:OFF
    private static long getNorm32(int c){
        return (UNSIGNED_INT_MASK&(NormTrieImpl.normTrie.getCodePointValue(c)));
    }
    
    private static long getNorm32(int c,int mask){
        long/*unsigned*/ norm32= getNorm32(UTF16.getLeadSurrogate(c));
        if(((norm32&mask)>0) && isNorm32LeadSurrogate(norm32)) {
            /* c is a lead surrogate, get the real norm32 */
            norm32=getNorm32FromSurrogatePair(norm32,UTF16.getTrailSurrogate(c));
        }
        return norm32; 
    }
    ///CLOVER:ON
    
    
    /*
     * get a norm32 from text with complete code points
     * (like from decompositions)
     */
    private static long/*unsigned*/ getNorm32(char[] p,int start,
                                              int/*unsigned*/ mask) {
        long/*unsigned*/ norm32= getNorm32(p[start]);
        if(((norm32&mask)>0) && isNorm32LeadSurrogate(norm32)) {
            /* *p is a lead surrogate, get the real norm32 */
            norm32=getNorm32FromSurrogatePair(norm32, p[start+1]);
        }
        return norm32;
    }
    public static VersionInfo getUnicodeVersion(){
        return VersionInfo.getInstance(unicodeVersion[0], unicodeVersion[1],
                                       unicodeVersion[2], unicodeVersion[3]);
    }
    public static char    getFCD16(char c) {
        return  FCDTrieImpl.fcdTrie.getLeadValue(c);
    }
    
    public static char getFCD16FromSurrogatePair(char fcd16, char c2) {
        /* the surrogate index in fcd16 is an absolute offset over the 
         * start of stage 1 
         * */
        return FCDTrieImpl.fcdTrie.getTrailValue(fcd16, c2);
    }
    public static int getFCD16(int c) {
        return  FCDTrieImpl.fcdTrie.getCodePointValue(c);
    }
        
    private static int getExtraDataIndex(long norm32) {
        return (int)(norm32>>EXTRA_SHIFT);
    }
    
    private static final class DecomposeArgs{
        int /*unsigned byte*/ cc;
        int /*unsigned byte*/ trailCC;
        int length;
    }
    /**
     * 
     * get the canonical or compatibility decomposition for one character 
     * 
     * @return index into the extraData array
     */
    private static int/*index*/ decompose(long/*unsigned*/ norm32, 
                                          int/*unsigned*/ qcMask, 
                                          DecomposeArgs args) {
        int p= getExtraDataIndex(norm32);
        args.length=extraData[p++];
    
        if((norm32&qcMask&QC_NFKD)!=0 && args.length>=0x100) {
            /* use compatibility decomposition, skip canonical data */
            p+=((args.length>>7)&1)+(args.length&DECOMP_LENGTH_MASK);
            args.length>>=8;
        }
    
        if((args.length&DECOMP_FLAG_LENGTH_HAS_CC)>0) {
            /* get the lead and trail cc's */
            char bothCCs=extraData[p++];
            args.cc=(UNSIGNED_BYTE_MASK) & (bothCCs>>8);
            args.trailCC=(UNSIGNED_BYTE_MASK) & bothCCs;
        } else {
            /* lead and trail cc's are both 0 */
            args.cc=args.trailCC=0;
        }
    
        args.length&=DECOMP_LENGTH_MASK;
        return p;
    }
    
       
    /**
     * get the canonical decomposition for one character 
     * @return index into the extraData array
     */
    private static int decompose(long/*unsigned*/ norm32, 
                                 DecomposeArgs args) {
                             
        int p= getExtraDataIndex(norm32);
        args.length=extraData[p++];
    
        if((args.length&DECOMP_FLAG_LENGTH_HAS_CC)>0) {
            /* get the lead and trail cc's */
            char bothCCs=extraData[p++];
            args.cc=(UNSIGNED_BYTE_MASK) & (bothCCs>>8);
            args.trailCC=(UNSIGNED_BYTE_MASK) & bothCCs;
        } else {
            /* lead and trail cc's are both 0 */
            args.cc=args.trailCC=0;
        }
    
        args.length&=DECOMP_LENGTH_MASK;
        return p;
    }
    
    
    private static final class NextCCArgs{
        char[] source;
        int next;
        int limit;
        char c;
        char c2;
    }
    
    /*
     * get the combining class of (c, c2)= args.source[args.next++]
     * before: args.next<args.limit  after: args.next<=args.limit
     * if only one code unit is used, then c2==0
     */
    private static int /*unsigned byte*/ getNextCC(NextCCArgs args) {
        long /*unsigned*/ norm32;
    
        args.c=args.source[args.next++];
        
        norm32= getNorm32(args.c);
        if((norm32 & CC_MASK)==0) {
            args.c2=0;
            return 0;
        } else {
            if(!isNorm32LeadSurrogate(norm32)) {
                args.c2=0;
            } else {
                /* c is a lead surrogate, get the real norm32 */
                if(args.next!=args.limit && 
                        UTF16.isTrailSurrogate(args.c2=args.source[args.next])){
                    ++args.next;
                    norm32=getNorm32FromSurrogatePair(norm32, args.c2);
                } else {
                    args.c2=0;
                    return 0;
                }
            }
    
            return (int)((UNSIGNED_BYTE_MASK) & (norm32>>CC_SHIFT));
        }
    }

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

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

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

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

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

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

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

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

            // prevCC has values from the following ranges:
            // 0..0xff -the previous trail combining class
            // <0      -the negative value of the previous code unit;
            //          that code unit was <MIN_WITH_LEAD_CC and its getFCD16()
            //          was deferred so that average text is checked faster
            //
    
            // check the combining order 
            cc=(int)(fcd16>>8);
            if(cc!=0) {
                if(prevCC<0) {
                    // the previous character was <_NORM_MIN_WITH_LEAD_CC, 
                    // we need to get its trail cc 
                    //
                    if(!nx_contains(nx, (int)-prevCC)) {
                        prevCC=(int)(FCDTrieImpl.fcdTrie.getBMPValue(
                                             (char)-prevCC)&0xff
                                             ); 
                    } else {
                        prevCC=0; /* excluded: fcd16==0 */
                    }
                                      
                }
    
                if(cc<prevCC) {
                    return false;
                }
            }
            prevCC=(int)(fcd16&0xff);
        }
    }
    
    public static Normalizer.QuickCheckResult quickCheck(char[] src,
                                                            int srcStart, 
                                                            int srcLimit,
                                                            int minNoMaybe,
                                                            int qcMask,
                                                            int options,
                                                            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,options,nx);
    
                    // compare the normalized version with the original 
                    if(0!=strCompare(buffer,0,args.length,src,prevStarter,srcStart, 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)((norm32>>CC_SHIFT)&0xff);
        
            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, int options, 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 
                     */
                    /* for the PRI #29 fix, check that there is no intervening combining mark */
                    if((options&BEFORE_PRI_29)!=0 || prevCC==0) {
                        remove=-1; /* NULL while no Hangul composition */
                        combineFlags=0;
                        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;
                                 } else {
                                     /* the result is an LV syllable, which is a starter (unlike LVT) */
                                     combineFlags=COMBINES_FWD;
                                }
                                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;
                                }
                            }

                        /*
                         * Normally, the following can not occur:
                         * Since the input is in NFD, there are no Hangul LV syllables that
                         * a Jamo T could combine with.
                         * All Jamo Ts are combined above when handling Jamo Vs.
                         *
                         * However, before the PRI #29 fix, this can occur due to
                         * an intervening combining mark between the Hangul LV and the Jamo T.
                         */
                        } else {
                            /* Jamo T, compose with previous Hangul that does not have a Jamo T */
                            if(isHangulWithoutJamoT(ncArg.c2)) {
                                ncArg.c2+=ncArg.c-JAMO_T_BASE;
                                if(!nx_contains(nx, ncArg.c2)) {
                                    remove=args.start-1;
                                    args.source[starter]=ncArg.c2;
                                }
                            }
                        }
        
                        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 */

                        if(combineFlags!=0) {
                            /*
                             * not starter=NULL because the composition is a Hangul LV syllable
                             * and might combine once more (but only before the PRI #29 fix)
                             */

                            /* done? */
                            if(args.start==args.limit) {
                                return (char)prevCC;
                            }

                            /* the composition is a Hangul LV syllable which is a starter that combines forward */
                            combineFwdIndex=0xfff0;

                            /* we combined; continue with looking for compositions */
                            continue;
                        }
                    }

                    /*
                     * 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 Hangul LV or Jamo V/T and */
                    !((combineFwdIndex&0x8000)!=0) &&
                    /* the combining mark is not blocked and */
                    ((options&BEFORE_PRI_29)!=0 ?
                        (prevCC!=ncArg.cc || prevCC==0) :
                        (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; 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;
                }
            } else if((options&OPTIONS_COMPOSE_CONTIGUOUS)!=0) {
                /* FCC: no discontiguous compositions; any intervening character blocks */
                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 options,
                                       UnicodeSet nx) {
        int recomposeLimit;
        boolean compat =((options&OPTIONS_COMPAT)!=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, options, 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,
                              int options,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((options&OPTIONS_COMPAT)!=0) {
            minNoMaybe=(char)indexes[INDEX_MIN_NFKC_NO_MAYBE];
            qcMask=QC_NFKC;
        } else {
            minNoMaybe=(char)indexes[INDEX_MIN_NFC_NO_MAYBE];
            qcMask=QC_NFC;
        }
    
        /*
         * 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, (options&OPTIONS_COMPAT)!=0, 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,options,nx);
                        
                    if(p==null) {
                        /* an error occurred (out of memory) */
                        break;
                    }
                    
                    prevCC      = args.prevCC;
                    length      = args.length;
                    
                    /* append the recomposed buffer contents to the destination 
                     * buffer */
                    if((destIndex+args.length)<=destLimit) {
                        int i=0;
                        while(i<args.length) {
                            dest[destIndex++]=p[i++];
                            --length;
                        }
                    } else {
                        /* buffer overflow */
                        /* keep incrementing the destIndex for preflighting */
                        destIndex+=length;
                    }
    
                    prevStarter=srcIndex;
                    continue;
                }
            }
    
            /* append the single code point (c, c2) to the destination buffer */
            if((destIndex+length)<=destLimit) {
                if(cc!=0 && cc<prevCC) {
                    /* (c, c2) is out of order with respect to the preceding 
                     * text */
                    int reorderSplit= destIndex;
                    destIndex+=length;
                    prevCC=insertOrdered(dest,reorderStartIndex, reorderSplit, 
                                         destIndex, c, c2, cc);
                } else {
                    /* just append (c, c2) */
                    dest[destIndex++]=c;
                    if(c2!=0) {
                        dest[destIndex++]=c2;
                    }
                    prevCC=cc;
                }
            } else {
                /* buffer overflow */
                /* keep incrementing the destIndex for preflighting */
                destIndex+=length;
                prevCC=cc;
            }
        }

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

        while(fcdIter.next(fcdResult)){
            set.add(fcdResult.start);
        }
        
        if(isFormatVersion_2_1){
            //utrie_enum(&auxTrie, NULL, _enumPropertyStartsRange, set);
            TrieIterator auxIter  = new TrieIterator(AuxTrieImpl.auxTrie);
            RangeValueIterator.Element auxResult = new RangeValueIterator.Element();
            while(auxIter.next(auxResult)){
                set.add(auxResult.start);
            }
        }
        /* add Hangul LV syllables and LV+1 because of skippables */
        for(c=HANGUL_BASE; c<HANGUL_BASE+HANGUL_COUNT; c+=JAMO_T_COUNT) {
            set.add(c);
            set.add(c+1);
        }
        set.add(HANGUL_BASE+HANGUL_COUNT); /* add Hangul+1 to continue with other properties */
        return set; // for chaining
    }

    /**
     * Internal API, used in UCharacter.getIntPropertyValue().
     * @internal
     * @param c code point
     * @param modeValue numeric value compatible with Mode
     * @return numeric value compatible with QuickCheck
     */
    public static final int quickCheck(int c, int modeValue) {
        final int qcMask[/*UNORM_MODE_COUNT*/]={
            0, 0, QC_NFD, QC_NFKD, QC_NFC, QC_NFKC
        };

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

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

    /**
     * Internal API, used by collation code.
     * Get access to the internal FCD trie table to be able to perform
     * incremental, per-code unit, FCD checks in collation.
     * One pointer is sufficient because the trie index values are offset
     * by the index size, so that the same pointer is used to access the trie 
     * data.
     * @internal
     */
    ///CLOVER:OFF
    public CharTrie getFCDTrie(){
        return FCDTrieImpl.fcdTrie;
    }
    ///CLOVER:ON


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

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

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

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

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

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

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

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

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

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


    /*
     * Status of tailored normalization
     *
     * This was done initially for investigation on Unicode public review issue 7
     * (http://www.unicode.org/review/). See Jitterbug 2481.
     * While the UTC at meeting #94 (2003mar) did not take up the issue, this is
     * a permanent feature in ICU 2.6 in support of IDNA which requires true
     * Unicode 3.2 normalization.
     * (NormalizationCorrections are rolled into IDNA mapping tables.)
     *
     * Tailored normalization as implemented here allows to "normalize less"
     * than full Unicode normalization would.
     * Based internally on a UnicodeSet of code points that are
     * "excluded from normalization", the normalization functions leave those
     * code points alone ("inert"). This means that tailored normalization
     * still transforms text into a canonically equivalent form.
     * It does not add decompositions to code points that do not have any or
     * change decomposition results.
     *
     * Any function that searches for a safe boundary has not been touched,
     * which means that these functions will be over-pessimistic when
     * exclusions are applied.
     * This should not matter because subsequent checks and normalizations
     * do apply the exclusions; only a little more of the text may be processed
     * than necessary under exclusions.
     *
     * Normalization exclusions have the following effect on excluded code points c:
     * - c is not decomposed
     * - c is not a composition target
     * - c does not combine forward or backward for composition
     *   except that this is not implemented for Jamo
     * - c is treated as having a combining class of 0
     */
     
    /* 
     * 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; 
    public  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;
    /**
     * Options bit 8, use buggy recomposition described in
     * Unicode Public Review Issue #29
     * at http://www.unicode.org/review/resolved-pri.html#pri29
     *
     * Used in IDNA implementation according to strict interpretation
     * of IDNA definition based on Unicode 3.2 which predates PRI #29.
     *
     * See ICU4C unormimp.h
     * 
     * @draft ICU 3.2
     */
    public static final int BEFORE_PRI_29=0x100;

    /*
     * The following options are used only in some composition functions.
     * They use bits 12 and up to preserve lower bits for the available options
     * space in unorm_compare() -
     * see documentation for UNORM_COMPARE_NORM_OPTIONS_SHIFT.
     */

    /** Options bit 12, for compatibility vs. canonical decomposition. */
    public static final int OPTIONS_COMPAT=0x1000;
    /** Options bit 13, no discontiguous composition (FCC vs. NFC). */
    public static final int OPTIONS_COMPOSE_CONTIGUOUS=0x2000;

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


}
