diff --git a/source/Makefile.in b/source/Makefile.in
index 24129d0..ab90d16 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -268,6 +268,8 @@
 
 ## icu4c0
 include icu4c0.mk
+-include Makefile.local
+
 
 samples/c0test/Makefile: $(top_srcdir)/samples/c0test/Makefile.in
 	CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
diff --git a/source/common/icu4c0.mk b/source/common/icu4c0.mk
index 90a1c90..d1df68c 100644
--- a/source/common/icu4c0.mk
+++ b/source/common/icu4c0.mk
@@ -20,13 +20,14 @@
 
 ifeq ($(VERSION),4.4.2)
 COMMON_DATA_OBJ=udata.o udatamem.o umapfile.o udataswp.o ucmndata.o
-COMMON_TRIE_OBJ=utrie2.o uchar.o ucase.o
+COMMON_TRIE_OBJ=utrie2.o uchar.o ucase.o utrie2_builder.o
 COMMON_UTIL_OBJ=putil.o uhash.o ustr_cnv.o ustring.o umutex.o cmemory.o utf_impl.o uinvchar.o ustrfmt.o uenum.o cstring.o ucln_cmn.o uinit.o umath.o icuplug.o uarrsort.o utrace.o utypes.o
 COMMON_UCNV_OBJ=ucnv.o ucnv2022.o ucnv_bld.o ucnv_cb.o ucnv_cnv.o ucnv_err.o ucnv_ext.o ucnv_io.o ucnv_lmb.o ucnv_set.o ucnv_u16.o ucnv_u32.o ucnv_u7.o ucnv_u8.o ucnvbocu.o ucnvdisp.o ucnvhz.o ucnvisci.o ucnvlat1.o ucnvmbcs.o ucnvscsu.o
 COMMON_LOC_OBJ=uloc_tag.o locmap.o uloc.o
 COMMON_RES_OBJ=uresbund.o uresdata.o 
 COMMON_STR_OBJ=ustrtrns.o
-COMMON_OBJ=$(COMMON_UCNV_OBJ) $(COMMON_UTIL_OBJ) $(COMMON_DATA_OBJ) $(COMMON_TRIE_OBJ) $(COMMON_LOC_OBJ) $(COMMON_RES_OBJ) $(COMMON_STR_OBJ)
+COMMON_NRM_OBJ=norm2.o
+COMMON_OBJ=$(COMMON_UCNV_OBJ) $(COMMON_UTIL_OBJ) $(COMMON_DATA_OBJ) $(COMMON_TRIE_OBJ) $(COMMON_LOC_OBJ) $(COMMON_RES_OBJ) $(COMMON_STR_OBJ) $(COMMON_NRM_OBJ)
 ICU4C0_VERSION=$(VERSION)
 endif
 
@@ -56,3 +57,5 @@
 #COMMON_SRC=$(COMMON_OBJ:%.o=$(ICU_COMMON)/%.c)
 
 endif
+
+-include icu4c0.local
diff --git a/source/common/norm2.c b/source/common/norm2.c
new file mode 100644
index 0000000..cf418bd
--- /dev/null
+++ b/source/common/norm2.c
@@ -0,0 +1,2216 @@
+/* look for TODO  or 'unimp'  */
+
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2009-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  normalizer2.cpp
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2009nov22
+*   created by: Markus W. Scherer
+*
+*   ported from normalizer2.cpp on 2011-feb-15 by srl into C
+*/
+
+#include "unicode/utypes.h"
+
+#include "unicode/unorm.h"
+#include "umutex.h"
+/*#include "normalizer2impl.h"*/
+#include "ucln_cmn.h"
+#include "uhash.h"
+#include "cmemory.h"
+#include "udatamem.h"
+
+#if  defined(ICU4C0)
+#ifndef UNORM_DEBUG
+/* #define UNORM_DEBUG 1 */
+#endif
+#ifdef UNORM_DEBUG
+#include <stdio.h>
+#endif
+
+#define UNORM_ENABLE_FCD 0  /* enables FCD and other modes. Not implemented. */
+#include "ustr_imp.h"
+#include "unicode/ustring.h"
+#include "norm2imp.h"
+
+#ifndef UNORM_DEBUG
+#include <stdio.h>
+#endif
+
+static UBool _unimp(UErrorCode *e, const char *f, int l) {
+  printf("%s:%d: ERROR: unimplemented!!!\n", f, l);
+  *e = U_REGEX_UNIMPLEMENTED;
+  return FALSE;
+}
+
+#define unimp(e)  _unimp(e,__FILE__,__LINE__)
+
+
+#define fcdTrie() (_this->newFCDTrie)
+#define getFCD16(c)  UTRIE2_GET16(_this->newFCDTrie, c)
+#define getFCD16FromSingleLead(c) UTRIE2_GET16_FROM_U16_SINGLE_LEAD(fcdTrie(), c)
+#define getFCD16FromSupplementary(c) UTRIE2_GET16_FROM_SUPP(fcdTrie(), c)
+#define getFCD16FromSurrogatePair(c,x) getFCD16FromSupplementary(U16_GET_SUPPLEMENTARY(c, x))
+#define getMapping(x) (_this->extraData+(x))
+#define getNorm16(x) (UTRIE2_GET16(_this->normTrie,(x)))
+#define isCompYesAndZeroCC(x) ((x)<_this->minNoNo)
+#define isMaybeOrNonZeroCC(norm16) ((norm16)>=_this->minMaybeYes)
+#define isDecompNoAlgorithmic(norm16) ((norm16)>=_this->limitNoNo)
+#define isInert(norm16) ((norm16)==0)
+#define isMaybe(norm16) (_this->minMaybeYes<=(norm16) && (norm16)<=JAMO_VT)
+#define mapAlgorithmic(c, norm16) ((c)+(norm16)-(_this->minMaybeYes-MAX_DELTA-1))
+
+
+/* some prototypes - not all */
+static UBool ReorderingBuffer_appendZeroCCStr(ReorderingBuffer *buffer, const UChar *s, const UChar *sLimit, UErrorCode *errorCode);
+
+static UBool
+Normalizer2_comp_compose(Normalizer2 *_this, const UChar *src, const UChar *limit,
+                         UBool onlyContiguous,
+                         UBool doCompose,
+                         ReorderingBuffer *buffer,
+                         UErrorCode *errorCode)  ;
+
+
+U_DRAFT const UNormalizer2 * U_EXPORT2
+unorm2_get2Instance(const char *packageName,
+                   const char *name,
+                   UNormalizationMode mode,
+                    UErrorCode *errorCode);
+
+static const UChar *
+Normalizer2_decomp_decompose(Normalizer2 *_this, const UChar *src, const UChar *limit,
+                           ReorderingBuffer *buffer,
+                             UErrorCode *errorCode);
+
+static const UChar *Normalizer2Impl_findPreviousCompBoundary(Normalizer2 *_this, const UChar *start, const UChar *p);
+
+static const UChar *Normalizer2Impl_findNextCompBoundary(Normalizer2 *_this, const UChar *p, const UChar *limit);
+
+/** end prototypes **/
+
+#ifdef UNORM_DEBUG
+#define MODENAME_STR \
+  "____\0" \
+  "NONE\0" \
+  "NFD \0" \
+  "NFKD\0" \
+  "NFC \0" \
+  "NFKC\0" \
+  "FCD \0" \
+  "!!!!\0"
+
+#define MODENAME(x)  (MODENAME_STR+((int)x)*5)
+
+#define MODE2NAME_STR \
+  "COMP\0" \
+  "DECM\0" \
+  "FCD \0" \
+  "FCC \0" \
+  "???1\0" \
+  "???2\0" \
+  "???3\0" \
+  "!!!!\0"
+
+#define MODE2NAME(x)  (MODE2NAME_STR+((int)x-(int)UNORM2_COMPOSE)*5)
+#endif
+
+/* ---- FACTORY ---- */
+
+
+static Normalizer2 **singletons = NULL;
+
+static UNormalizer2 *getSingleton(UNormalizationMode mode, const char *str, UErrorCode *errorCode) {
+  Normalizer2 *ret = NULL;
+  Normalizer2 *newOne = NULL;
+  Normalizer2 **theSingletons = NULL;
+  UMTX_CHECK(NULL,singletons,theSingletons);
+  if(theSingletons == NULL) {
+    Normalizer2 **list = (Normalizer2**)uprv_malloc(sizeof(Normalizer2*)*UNORM_MODE_COUNT);
+    uprv_memset(list, sizeof(Normalizer2*)*UNORM_MODE_COUNT,0);
+    umtx_lock(NULL);
+    if(singletons == NULL) {
+      singletons=list;
+      list=NULL;
+    }
+    umtx_unlock(NULL);
+    if(list!=NULL) {
+      uprv_free(list); /* someone beat us to it. */
+    }
+    if(singletons==NULL) {
+      *errorCode = U_MEMORY_ALLOCATION_ERROR;
+      return NULL;
+    }
+  }
+
+  UMTX_CHECK(NULL,(singletons[(int)mode]),ret);
+  if(ret!=NULL) {
+    return (UNormalizer2*)ret;
+  }
+  
+  /* make up */
+  newOne = (Normalizer2*)unorm2_get2Instance(NULL,str,mode,errorCode);
+  if(U_FAILURE(*errorCode)) {
+    unorm2_close((UNormalizer2*)newOne);
+    return NULL;
+  } else if(newOne==NULL) {
+    *errorCode = U_MEMORY_ALLOCATION_ERROR;
+    return NULL;
+  }
+  ret = newOne;
+  /* put it in the cache */
+  umtx_lock(NULL);
+  if(singletons[(int)mode]==NULL) {
+    singletons[(int)mode] = newOne;
+    newOne = NULL;
+  } else {
+    ret = singletons[(int)mode];
+  }
+  umtx_unlock(NULL);
+  if(newOne!=NULL) {
+    unorm2_close((UNormalizer2*)newOne);
+  }
+
+  return (UNormalizer2*)ret;
+}
+
+static const UNormalizer2 *
+Normalizer2Factory_getInstance(UNormalizationMode mode, UErrorCode *errorCode) {
+    if(U_FAILURE(*errorCode)) {
+        return NULL;
+    }
+    switch(mode) {
+#if UNORM_ENABLE_FCD
+    case UNORM_NFD:
+      return getSingleton(mode, "nfc", errorCode);
+    case UNORM_NFKD:
+      return getSingleton(mode, "nfkc", errorCode);
+#endif
+    case UNORM_NFC:
+      return getSingleton(mode, "nfc", errorCode);
+#if UNORM_ENABLE_FCD
+    case UNORM_NFKC:
+      return getSingleton(mode, "nfkc", errorCode);
+    case UNORM_FCD:
+      return getSingleton(mode, "nfc", errorCode);
+#endif
+    default:  /* UNORM_NONE */
+      *errorCode = U_REGEX_UNIMPLEMENTED; /* not implemented */
+#if defined(UNORM_DEBUG)
+      fprintf(stderr, "Loading noop for mode #%d=%s\n",(int)mode, MODENAME(mode));
+#endif
+    case UNORM_NONE:
+      return getSingleton(mode, NULL, errorCode);
+    }
+}
+
+/* INSTANCE */
+
+static UBool U_CALLCONV
+_isAcceptable(void *context,
+                              const char *type, const char *name,
+                              const UDataInfo *pInfo) {
+    if(
+        pInfo->size>=20 &&
+        pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
+        pInfo->charsetFamily==U_CHARSET_FAMILY &&
+        pInfo->dataFormat[0]==0x4e &&    /* dataFormat="Nrm2" */
+        pInfo->dataFormat[1]==0x72 &&
+        pInfo->dataFormat[2]==0x6d &&
+        pInfo->dataFormat[3]==0x32 &&
+        pInfo->formatVersion[0]==1
+    ) {
+        Normalizer2 *me=(Normalizer2 *)context;
+        uprv_memcpy(me->dataVersion, pInfo->dataVersion, 4);
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+static void Normalizer2_load(Normalizer2 *_this, const char *packageName, const char *name,  UErrorCode *errorCode) {
+  /* from normalizer2impl.cpp: Normalizr2Impl::load */
+  _this->memory=udata_openChoice(packageName, "nrm", name, _isAcceptable, _this, errorCode);
+
+  if(U_FAILURE(*errorCode)) {
+#if defined(UNORM_DEBUG)
+    fprintf(stderr, "%s:%d: error %s, can't open data %s/%s.%s\n", __FILE__, __LINE__, u_errorName(*errorCode), packageName?packageName:"<NULL>", name, "nrm");
+#endif
+    return;
+  }
+
+  {
+    const uint8_t *inBytes=(const uint8_t *)udata_getMemory(_this->memory);
+    const int32_t *inIndexes=(const int32_t *)inBytes;
+    int32_t indexesLength=inIndexes[IX_NORM_TRIE_OFFSET]/4;
+    if(indexesLength<=IX_MIN_MAYBE_YES) {
+      *errorCode=U_INVALID_FORMAT_ERROR;  /* Not enough indexes. */
+      return;
+    }
+    
+    _this->minDecompNoCP=inIndexes[IX_MIN_DECOMP_NO_CP];
+    _this->minCompNoMaybeCP=inIndexes[IX_MIN_COMP_NO_MAYBE_CP];
+
+    _this->minYesNo=inIndexes[IX_MIN_YES_NO];
+    _this->minNoNo=inIndexes[IX_MIN_NO_NO];
+    _this->limitNoNo=inIndexes[IX_LIMIT_NO_NO];
+    _this->minMaybeYes=inIndexes[IX_MIN_MAYBE_YES];
+
+    {
+      int32_t offset=inIndexes[IX_NORM_TRIE_OFFSET];
+      int32_t nextOffset=inIndexes[IX_EXTRA_DATA_OFFSET];
+      _this->normTrie=utrie2_openFromSerialized(UTRIE2_16_VALUE_BITS,
+                                                inBytes+offset, nextOffset-offset, NULL,
+                                                errorCode);
+      if(U_FAILURE(*errorCode)) {
+        return;
+      }
+
+      offset=nextOffset;
+      _this->maybeYesCompositions=(const uint16_t *)(inBytes+offset);
+      _this->extraData=_this->maybeYesCompositions+(MIN_NORMAL_MAYBE_YES-_this->minMaybeYes);
+    }
+  }
+}
+
+#if UNORM_ENABLE_FCD
+
+static void Normalizer2Impl_setFCD16FromNorm16(Normalizer2 *_this, UChar32 start, UChar32 end, uint16_t norm16,
+                                               UTrie2 *newFCDTrie, UErrorCode *errorCode)  {
+    /*  Only loops for 1:1 algorithmic mappings. */
+    for(;;) {
+        if(norm16>=MIN_NORMAL_MAYBE_YES) {
+            norm16&=0xff;
+            norm16|=norm16<<8;
+        } else if(norm16<=_this->minYesNo || _this->minMaybeYes<=norm16) {
+            /*  no decomposition or Hangul syllable, all zeros */
+            break;
+        } else if(_this->limitNoNo<=norm16) {
+            int32_t delta=norm16-(_this->minMaybeYes-MAX_DELTA-1);
+            if(start==end) {
+                start+=delta;
+                norm16=getNorm16(start);
+            } else {
+                /*  the same delta leads from different original characters to different mappings */
+                do {
+                    UChar32 c=start+delta;
+                    Normalizer2Impl_setFCD16FromNorm16(_this,c, c, getNorm16(c), newFCDTrie, errorCode);
+                } while(++start<=end);
+                break;
+            }
+        } else {
+            /*  c decomposes, get everything from the variable-length extra data */
+          const uint16_t *mapping= _this->extraData+norm16; /* getMapping(norm16); */
+            uint16_t firstUnit=*mapping;
+            if((firstUnit&MAPPING_LENGTH_MASK)==0) {
+                /*  A character that is deleted (maps to an empty string) must */
+                /*  get the worst-case lccc and tccc values because arbitrary */
+                /*  characters on both sides will become adjacent. */
+                norm16=0x1ff;
+            } else {
+                if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) {
+                    norm16=mapping[1]&0xff00;  /*  lccc */
+                } else {
+                    norm16=0;
+                }
+                norm16|=firstUnit>>8;  /*  tccc */
+            }
+        }
+        utrie2_setRange32(newFCDTrie, start, end, norm16, TRUE, errorCode);
+        break;
+    }
+}
+
+
+
+/* Collect (OR together) the FCD values for a range of supplementary characters, */
+/* for their lead surrogate code unit. */
+static UBool U_CALLCONV
+enumRangeOrValue(const void *context, UChar32 start, UChar32 end, uint32_t value) {
+    *((uint32_t *)context)|=value;
+    return TRUE;
+}
+
+
+/* Set the FCD value for a range of same-norm16 characters. */
+static UBool U_CALLCONV
+enumRangeHandler(void *context, UChar32 start, UChar32 end, uint32_t value) {
+  Normalizer2 *_this = (Normalizer2*)context;
+  if(value!=0) {
+    Normalizer2Impl_setFCD16FromNorm16(_this, start, end, (uint16_t)value, _this->newFCDTrie, &(_this->fcdErrorCode));
+  }
+  return (U_SUCCESS(_this->fcdErrorCode));
+}
+
+static UTrie2 *FCDTrieSingleton_createInstance(Normalizer2 *me, UErrorCode *errorCode) {
+    me->newFCDTrie=utrie2_open(0, 0, errorCode);
+    if(U_SUCCESS(*errorCode)) {
+      UChar lead;
+      utrie2_enum(me->normTrie, NULL, enumRangeHandler, me);
+      for(lead=0xd800; lead<0xdc00; ++lead) {
+        uint32_t oredValue=utrie2_get32(me->newFCDTrie, lead);
+        utrie2_enumForLeadSurrogate(me->newFCDTrie, lead, NULL, enumRangeOrValue, &oredValue);
+        if(oredValue!=0) {
+          /* Set a "bad" value for makeFCD() to break the quick check loop */
+          /* and look up the value for the supplementary code point. */
+          /* If there is any lccc, then set the worst-case lccc of 1. */
+          /* The ORed-together value's tccc is already the worst case. */
+          if(oredValue>0xff) {
+            oredValue=0x100|(oredValue&0xff);
+          }
+          utrie2_set32ForLeadSurrogateCodeUnit(me->newFCDTrie, lead, oredValue, errorCode);
+        }
+      }
+      utrie2_freeze(me->newFCDTrie, UTRIE2_16_VALUE_BITS, errorCode);
+      if(U_SUCCESS(*errorCode)) {
+        return me->newFCDTrie;
+      }
+    }
+    utrie2_close(me->newFCDTrie);
+    me->newFCDTrie=NULL;
+    return NULL;
+}
+
+#endif
+
+static  void U_CALLCONV Normalizer2_close(struct Normalizer2* _this) {
+#if UNORM_ENABLE_FCD
+  utrie2_close(_this->newFCDTrie);
+#endif
+  udata_close(_this->memory);
+  utrie2_close(_this->normTrie);
+}
+
+static uint8_t getCCFromYesOrMaybe(uint16_t norm16) {
+  return norm16>=MIN_NORMAL_MAYBE_YES ? (uint8_t)norm16 : 0;
+}
+static UBool isMostDecompYesAndZeroCC(Normalizer2* _this, uint16_t norm16)  {
+        return norm16<_this->minYesNo || norm16==MIN_NORMAL_MAYBE_YES || norm16==JAMO_VT;
+    }
+
+static UBool isDecompYes(Normalizer2* _this,uint16_t norm16)  { return norm16<_this->minYesNo || _this->minMaybeYes<=norm16; }
+
+static UNormalizationCheckResult U_CALLCONV Normalizer2_noop_quickCheck(struct Normalizer2* n, const UChar *s, int32_t length, UErrorCode *pErrorCode) {
+  return UNORM_YES; 
+}
+
+
+static int32_t Hangul_decompose(UChar32 c, UChar buffer[3]) {
+  c-=HANGUL_BASE;
+  {
+  UChar32 c2=c%JAMO_T_COUNT;
+  c/=JAMO_T_COUNT;
+  buffer[0]=(UChar)(JAMO_L_BASE+c/JAMO_V_COUNT);
+  buffer[1]=(UChar)(JAMO_V_BASE+c%JAMO_V_COUNT);
+  if(c2==0) {
+    return 2;
+  } else {
+    buffer[2]=(UChar)(JAMO_T_BASE+c2);
+    return 3;
+  }
+  }
+}
+
+static UChar *ReorderingBuffer_getLimit(ReorderingBuffer* buffer) {
+  return buffer->limit;
+}
+static UChar *ReorderingBuffer_getStart(ReorderingBuffer* buffer) {
+  return buffer->start;
+}
+static UBool ReorderingBuffer_isEmpty(ReorderingBuffer* buffer) {
+  return buffer->start==buffer->limit;
+}
+static void ReorderingBuffer_setLastChar(ReorderingBuffer* buffer, UChar c) {
+  *(buffer->limit-1)=c;
+}
+static void ReorderingBuffer_setReorderingLimit(ReorderingBuffer* buffer, UChar* newLimit) {
+  buffer->remainingCapacity+=(int32_t)(buffer->limit-newLimit);
+  buffer->reorderStart=buffer->limit=newLimit;
+  buffer->lastCC=0;
+}
+
+static void ReorderingBuffer_construct(ReorderingBuffer *buffer, Normalizer2 *n, UChar *dest, int32_t capacity) {
+  buffer->impl = n;
+  buffer->str = dest;
+  buffer->remainingCapacity=0;
+  buffer->lastCC=0;
+  buffer->limit = NULL;
+  buffer->reorderStart=NULL;
+  buffer->start=NULL;
+  buffer->capacity = 0;
+}
+
+static UBool ReorderingBuffer_resize(ReorderingBuffer *buffer, int32_t appendLength, UErrorCode *errorCode) {
+    int32_t reorderStartIndex=(int32_t)(buffer->reorderStart-buffer->start);
+    int32_t length=(int32_t)(buffer->limit-buffer->start);
+    /* str.releaseBuffer(length); */
+    int32_t newCapacity=length+appendLength;
+    int32_t doubleCapacity=2*buffer->capacity;
+    if(newCapacity<doubleCapacity) {
+        newCapacity=doubleCapacity;
+    }
+    if(newCapacity<256) {
+        newCapacity=256;
+    }
+    buffer->start=uprv_realloc(buffer->start,newCapacity);
+    if(buffer->start==NULL) {
+        /* getBuffer() already did str.setToBogus() */
+        *errorCode=U_MEMORY_ALLOCATION_ERROR;
+        return FALSE;
+    }
+    buffer->capacity = newCapacity;
+    buffer->reorderStart=buffer->start+reorderStartIndex;
+    buffer->limit=buffer->start+length;
+    buffer->remainingCapacity=buffer->capacity-length;
+    return TRUE;
+}
+
+static UBool ReorderingBuffer_equals(ReorderingBuffer *b, const UChar *oStart, const UChar *oLimit) {
+  int32_t length=(int32_t)(b->limit-b->start);
+  return
+    length==(int32_t)(oLimit-oStart) &&
+        0==u_memcmp(b->start, oStart, length);
+}
+
+static void ReorderingBuffer_remove(ReorderingBuffer *b) {
+  b->reorderStart=b->limit=b->start;
+  b->remainingCapacity=b->capacity;
+  b->lastCC=0;
+}
+
+static void ReorderingBuffer_writeCodePoint(UChar *p, UChar32 c) {
+  if(c<=0xffff) {
+    *p=(UChar)c;
+  } else {
+    p[0]=U16_LEAD(c);
+    p[1]=U16_TRAIL(c);
+  }
+}
+
+#define setIterator()   (buffer->codePointStart=buffer->limit)
+static void ReorderingBuffer_skipPrevious(ReorderingBuffer *buffer)
+{
+    buffer->codePointLimit=buffer->codePointStart;
+    {
+      UChar c=*--(buffer->codePointStart);
+      if(U16_IS_TRAIL(c) && buffer->start<buffer->codePointStart && U16_IS_LEAD(*(buffer->codePointStart-1))) {
+        --(buffer->codePointStart);
+      }
+    }
+}
+static uint8_t ReorderingBuffer_previousCC(ReorderingBuffer *buffer) {
+  Normalizer2 *_this = buffer->impl;
+  buffer->codePointLimit=buffer->codePointStart;
+    if(buffer->reorderStart>=buffer->codePointStart) {
+        return 0;
+    }
+    {
+      UChar32 c=*--(buffer->codePointStart);
+      if(c</* Normalizer2Impl::*/ MIN_CCC_LCCC_CP) {
+        return 0;
+      }
+      {
+        UChar c2;
+        if(U16_IS_TRAIL(c) && buffer->start<buffer->codePointStart && U16_IS_LEAD(c2=*(buffer->codePointStart-1))) {
+          --(buffer->codePointStart);
+          c=U16_GET_SUPPLEMENTARY(c2, c);
+        }
+      }
+      return getCCFromYesOrMaybe(/* _this. */getNorm16(c));
+    }
+}
+
+
+static void ReorderingBuffer_insert(ReorderingBuffer *buffer, UChar32 c, uint8_t cc) {
+    for(setIterator(), ReorderingBuffer_skipPrevious(buffer); ReorderingBuffer_previousCC(buffer)>cc;) {}
+    /* insert c at codePointLimit, after the character with prevCC<=cc */
+    {
+      UChar *q=buffer->limit;
+      {
+      UChar *r=buffer->limit+=U16_LENGTH(c);
+      do {
+        *--r=*--q;
+      } while(buffer->codePointLimit!=q);
+      ReorderingBuffer_writeCodePoint(q, c);
+      if(cc<=1) {
+        buffer->reorderStart=r;
+      }
+    }
+    }
+}
+
+
+static void ReorderingBuffer_removeSuffix(ReorderingBuffer *b, int32_t suffixLength) {
+    if(suffixLength<(b->limit-b->start)) {
+        b->limit-=suffixLength;
+        b->remainingCapacity+=suffixLength;
+    } else {
+        b->limit=b->start;
+        b->remainingCapacity=b->capacity;
+    }
+    b->lastCC=0;
+    b->reorderStart=b->limit;
+}
+
+static int32_t ReorderingBuffer_length(ReorderingBuffer *buffer) {
+  return (int32_t)(buffer->limit-buffer->start);
+}
+
+static uint8_t ReorderingBuffer_getLastCC(ReorderingBuffer *buffer) {
+  return buffer->lastCC;
+}
+
+static UBool ReorderingBuffer_appendSupplementary(ReorderingBuffer *buffer, UChar32 c, uint8_t cc, UErrorCode *errorCode) {
+  if(buffer->remainingCapacity<2 && !ReorderingBuffer_resize(buffer, 2, errorCode)) {
+        return FALSE;
+    }
+    if(buffer->lastCC<=cc || cc==0) {
+        buffer->limit[0]=U16_LEAD(c);
+        buffer->limit[1]=U16_TRAIL(c);
+        buffer->limit+=2;
+        buffer->lastCC=cc;
+        if(cc<=1) {
+            buffer->reorderStart=buffer->limit;
+        }
+    } else {
+      ReorderingBuffer_insert(buffer, c, cc);
+    }
+    buffer->remainingCapacity-=2;
+    return TRUE;
+}
+
+    /* s must be in NFD, otherwise change the implementation. */
+static UBool ReorderingBuffer_appendBMP(ReorderingBuffer *buffer, UChar c, uint8_t cc, UErrorCode *errorCode) {
+  if(buffer->remainingCapacity==0 && !ReorderingBuffer_resize(buffer, 1, errorCode)) {
+            return FALSE;
+        }
+        if(buffer->lastCC<=cc || cc==0) {
+          *(buffer->limit)++=c;
+            buffer->lastCC=cc;
+            if(cc<=1) {
+                buffer->reorderStart=buffer->limit;
+            }
+        } else {
+          ReorderingBuffer_insert(buffer, c, cc);
+        }
+        --(buffer->remainingCapacity);
+        return TRUE;
+    }
+
+static UBool ReorderingBuffer_append(ReorderingBuffer *buffer, UChar32 c, uint8_t cc, UErrorCode *errorCode) {
+  return (c<=0xffff) ?
+    ReorderingBuffer_appendBMP(buffer,(UChar)c, cc, errorCode) :
+    ReorderingBuffer_appendSupplementary(buffer,c, cc, errorCode);
+}
+
+
+
+
+
+
+
+
+
+static void ReorderingBuffer_close(ReorderingBuffer *buffer) {
+  if(buffer!=NULL && buffer->start!=NULL) {
+    uprv_free(buffer->start);
+  }
+}
+
+static UBool ReorderingBuffer_init(ReorderingBuffer *buffer, int32_t destCapacity, UErrorCode *pErrorCode) {
+  return TRUE; /* ? */
+}
+
+static int32_t ReorderingBuffer_extract(ReorderingBuffer *buffer, Normalizer2 *n, UChar *dest, int32_t capacity, UErrorCode *pErrorCode) {
+  /* u_strncpy(dest,src,tlen); */
+  int32_t length = buffer->limit - buffer->start;
+  return u_terminateUChars(dest,capacity,length,pErrorCode);
+}
+
+static UBool ReorderingBuffer_appendZeroCCStr(ReorderingBuffer *buffer, const UChar *s, const UChar *sLimit, UErrorCode *errorCode) {
+    int32_t length=(int32_t)(sLimit-s);
+    if(s==sLimit) {
+        return TRUE;
+    }
+    if(buffer->remainingCapacity<length && !ReorderingBuffer_resize(buffer, length, errorCode)) {
+        return FALSE;
+    }
+    u_memcpy(buffer->limit, s, length);
+    buffer->limit+=length;
+    buffer->remainingCapacity-=length;
+    buffer->lastCC=0;
+    buffer->reorderStart=buffer->limit;
+    return TRUE;
+}
+
+static UBool ReorderingBuffer_appendLeadTrail(ReorderingBuffer *buffer, const UChar *s, int32_t length,
+                               uint8_t leadCC, uint8_t trailCC,
+                               UErrorCode *errorCode) {
+    if(length==0) {
+        return TRUE;
+    }
+    if(buffer->remainingCapacity<length && !ReorderingBuffer_resize(buffer, length, errorCode)) {
+        return FALSE;
+    }
+    buffer->remainingCapacity-=length;
+    if(buffer->lastCC<=leadCC || leadCC==0) {
+        const UChar *sLimit=s+length;
+        if(trailCC<=1) {
+            buffer->reorderStart=buffer->limit+length;
+        } else if(leadCC<=1) {
+          buffer->reorderStart=buffer->limit+1;  /* Ok if not a code point boundary. */
+        }
+        do { *buffer->limit++=*s++; } while(s!=sLimit);
+        buffer->lastCC=trailCC;
+    } else {
+        int32_t i=0;
+        UChar32 c;
+        U16_NEXT(s, i, length, c);
+        ReorderingBuffer_insert(buffer, c, leadCC);  /* insert first code point */
+        while(i<length) {
+            U16_NEXT(s, i, length, c);
+            if(i<length) {
+                /* s must be in NFD, otherwise we need to use getCC(). */
+              Normalizer2 *_this = buffer->impl;
+                leadCC=getCCFromYesOrMaybe(getNorm16(c));
+            } else {
+                leadCC=trailCC;
+            }
+            ReorderingBuffer_append(buffer, c, leadCC, errorCode);
+        }
+    }
+    return TRUE;
+}
+
+
+
+
+#if 0
+    UBool isEmpty() const { return start==limit; }
+    int32_t length() const { return (int32_t)(limit-start); }
+    UChar *getStart() { return start; }
+    UChar *getLimit() { return limit; }
+    uint8_t getLastCC() const { return lastCC; }
+
+    UBool equals(const UChar *start, const UChar *limit) const;
+
+    /*  For Hangul composition, replacing the Leading consonant Jamo with the syllable. */
+    void setLastChar(UChar c) {
+        *(limit-1)=c;
+    }
+
+    UBool append(UChar32 c, uint8_t cc, UErrorCode &errorCode) {
+        return (c<=0xffff) ?
+            appendBMP((UChar)c, cc, errorCode) :
+            appendSupplementary(c, cc, errorCode);
+    }
+    /*  s must be in NFD, otherwise change the implementation. */
+    UBool append(const UChar *s, int32_t length,
+                 uint8_t leadCC, uint8_t trailCC,
+                 UErrorCode &errorCode);
+    UBool appendBMP(UChar c, uint8_t cc, UErrorCode &errorCode) {
+        if(remainingCapacity==0 && !resize(1, errorCode)) {
+            return FALSE;
+        }
+        if(lastCC<=cc || cc==0) {
+            *limit++=c;
+            lastCC=cc;
+            if(cc<=1) {
+                reorderStart=limit;
+            }
+        } else {
+            insert(c, cc);
+        }
+        --remainingCapacity;
+        return TRUE;
+    }
+    UBool appendZeroCC(UChar32 c, UErrorCode &errorCode);
+    UBool appendZeroCC(const UChar *s, const UChar *sLimit, UErrorCode &errorCode);
+    void remove();
+    void removeSuffix(int32_t suffixLength);
+    void setReorderingLimit(UChar *newLimit) {
+        remainingCapacity+=(int32_t)(limit-newLimit);
+        reorderStart=limit=newLimit;
+        lastCC=0;
+    }
+    UBool appendSupplementary(UChar32 c, uint8_t cc, UErrorCode &errorCode);
+    void insert(UChar32 c, uint8_t cc);
+    static void writeCodePoint(UChar *p, UChar32 c) {
+        if(c<=0xffff) {
+            *p=(UChar)c;
+        } else {
+            p[0]=U16_LEAD(c);
+            p[1]=U16_TRAIL(c);
+        }
+    }
+    UBool resize(int32_t appendLength, UErrorCode &errorCode);
+
+    const Normalizer2Impl &impl;
+    UnicodeString &str;
+    UChar *start, *reorderStart, *limit;
+    int32_t remainingCapacity;
+    uint8_t lastCC;
+
+    /*  private backward iterator */
+    void setIterator() { codePointStart=limit; }
+    void skipPrevious();  /*  Requires start<codePointStart. */
+    uint8_t previousCC();  /*  Returns 0 if there is no previous character. */
+
+    UChar *codePointStart, *codePointLimit;
+
+#endif
+
+
+
+static int32_t U_CALLCONV Normalizer2_comp_normalize (struct Normalizer2 *_this,
+                                                 const UChar *src, int32_t length,
+                                                 UChar *dest, int32_t capacity,
+                                                 UErrorCode *pErrorCode) {
+  int32_t tlen = length;
+  ReorderingBuffer buffer;
+
+  if(U_FAILURE(*pErrorCode)) {
+/* #if defined(UNORM_DEBUG) */
+/*     fprintf(stderr,"normalize noop: err %s\n", u_errorName(*pErrorCode)); */
+/* #endif */
+    return 0;
+  }
+  if(tlen == -1) {
+    tlen = u_strlen(src);
+  }
+  if(capacity<length) {
+    tlen = capacity;
+  }
+  
+  ReorderingBuffer_construct(&buffer, _this, dest, capacity);
+  if(ReorderingBuffer_init(&buffer, length, pErrorCode)) {
+    Normalizer2_comp_compose(_this, src, length>=0 ? src+length : NULL, _this->onlyContiguous, TRUE, &buffer, pErrorCode);
+  }
+  
+  tlen =  ReorderingBuffer_extract(&buffer, _this, dest, capacity, pErrorCode);
+  ReorderingBuffer_close(&buffer);
+  return tlen;
+}
+
+static int32_t U_CALLCONV Normalizer2_noop_normalize (struct Normalizer2 *n,
+                                                 const UChar *src, int32_t length,
+                                                 UChar *dest, int32_t capacity,
+                                                 UErrorCode *pErrorCode) {
+  int32_t tlen = length;
+
+  if(U_FAILURE(*pErrorCode)) {
+/* #if defined(UNORM_DEBUG) */
+/*     fprintf(stderr,"normalize noop: err %s\n", u_errorName(*pErrorCode)); */
+/* #endif */
+    return 0;
+  }
+  if(tlen == -1) {
+    tlen = u_strlen(src);
+  }
+  if(capacity<length) {
+    tlen = capacity;
+  }
+  u_strncpy(dest,src,tlen);
+  return u_terminateUChars(dest,capacity,length,pErrorCode);
+}
+
+static const UChar *
+Normalizer2_fcd_copyLowPrefixFromNulTerminated(Normalizer2 *_this, const UChar *src,
+                                                UChar32 minNeedDataCP,
+                                                ReorderingBuffer *buffer,
+                                                UErrorCode *errorCode)  {
+    /*  Make some effort to support NUL-terminated strings reasonably. */
+    /*  Take the part of the fast quick check loop that does not look up */
+    /*  data and check the first part of the string. */
+    /*  After this prefix, determine the string length to simplify the rest */
+    /*  of the code. */
+    UChar c;
+    const UChar *prevSrc=src;
+    while((c=*src++)<minNeedDataCP && c!=0) {}
+    /*  Back out the last character for full processing. */
+    /*  Copy this prefix. */
+    if(--src!=prevSrc) {
+        if(buffer!=NULL) {
+          unimp(errorCode); /* buffer->appendZeroCC(prevSrc, src, errorCode); */
+        }
+    }
+    return src;
+}
+
+static const uint16_t *Normalizer2_getCompositionsListForDecompYes(Normalizer2 *_this, uint16_t norm16)  {
+        if(norm16==0 || MIN_NORMAL_MAYBE_YES<=norm16) {
+            return NULL;
+        } else if(norm16<_this->minMaybeYes) {
+            return _this->extraData+norm16;  /*  for yesYes; if Jamo L: harmless empty list */
+        } else {
+            return _this->maybeYesCompositions+norm16-_this->minMaybeYes;
+        }
+    }
+static    const uint16_t *Normalizer2_getCompositionsListForComposite(Normalizer2 *_this, uint16_t norm16)  {
+        const uint16_t *list=_this->extraData+norm16;  /*  composite has both mapping & compositions list */
+        return list+  /*  mapping pointer */
+            1+  /*  +1 to skip the first unit with the mapping lenth */
+            (*list&MAPPING_LENGTH_MASK)+  /*  + mapping length */
+            ((*list>>7)&1);  /*  +1 if MAPPING_HAS_CCC_LCCC_WORD */
+    }
+
+
+#if UNORM_ENABLE_FCD
+
+/*  Dual functionality: */
+/*  buffer!=NULL: normalize */
+/*  buffer==NULL: isNormalized/quickCheck/spanQuickCheckYes */
+const UChar *
+Normalizer2_fcd_makeFCD(Normalizer2 *_this, const UChar *src, const UChar *limit,
+                         ReorderingBuffer *buffer,
+                         UErrorCode *errorCode) {
+    const UChar *prevBoundary=src;
+    const UChar *prevSrc;
+    UChar32 c=0;
+    int32_t prevFCD16=0;
+    uint16_t fcd16=0;
+
+    const UTrie2 *trie=_this->newFCDTrie;
+  if(limit==NULL) {
+    src=Normalizer2_fcd_copyLowPrefixFromNulTerminated(_this,src, MIN_CCC_LCCC_CP, buffer, errorCode);
+    if(U_FAILURE(*errorCode)) {
+      return src;
+    }
+    limit=u_strchr(src, 0);
+  }
+
+    /*  Note: In this function we use buffer->appendZeroCC() because we track */
+    /*  the lead and trail combining classes here, rather than leaving it to */
+    /*  the ReorderingBuffer. */
+    /*  The exception is the call to decomposeShort() which uses the buffer */
+    /*  in the normal way. */
+
+
+    /*  Tracks the last FCD-safe boundary, before lccc=0 or after properly-ordered tccc<=1. */
+    /*  Similar to the prevBoundary in the compose() implementation. */
+    for(;;) {
+        /*  count code units with lccc==0 */
+        for(prevSrc=src; src!=limit;) {
+            if((c=*src)<MIN_CCC_LCCC_CP) {
+                prevFCD16=~c;
+                ++src;
+            } else if((fcd16=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(trie, c))<=0xff) {
+                prevFCD16=fcd16;
+                ++src;
+            } else if(!U16_IS_SURROGATE(c)) {
+                break;
+            } else {
+                UChar c2;
+                if(U16_IS_SURROGATE_LEAD(c)) {
+                    if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
+                        c=U16_GET_SUPPLEMENTARY(c, c2);
+                    }
+                } else /* trail surrogate */ {
+                    if(prevSrc<src && U16_IS_LEAD(c2=*(src-1))) {
+                        --src;
+                        c=U16_GET_SUPPLEMENTARY(c2, c);
+                    }
+                }
+                if((fcd16=getFCD16(c))<=0xff) {
+                    prevFCD16=fcd16;
+                    src+=U16_LENGTH(c);
+                } else {
+                    break;
+                }
+            }
+        }
+        /*  copy these code units all at once */
+        if(src!=prevSrc) {
+          if(buffer!=NULL && unimp(errorCode) /* !buffer->appendZeroCC(prevSrc, src, errorCode) */) {
+                break;
+            }
+            if(src==limit) {
+                break;
+            }
+            prevBoundary=src;
+            /*  We know that the previous character's lccc==0. */
+            if(prevFCD16<0) {
+                /*  Fetching the fcd16 value was deferred for this below-U+0300 code point. */
+                prevFCD16=getFCD16FromSingleLead((UChar)~prevFCD16);
+                if(prevFCD16>1) {
+                    --prevBoundary;
+                }
+            } else {
+                const UChar *p=src-1;
+                if(U16_IS_TRAIL(*p) && prevSrc<p && U16_IS_LEAD(*(p-1))) {
+                    --p;
+                    /*  Need to fetch the previous character's FCD value because */
+                    /*  prevFCD16 was just for the trail surrogate code point. */
+                    prevFCD16=getFCD16FromSurrogatePair(p[0], p[1]);
+                    /*  Still known to have lccc==0 because its lead surrogate unit had lccc==0. */
+                }
+                if(prevFCD16>1) {
+                    prevBoundary=p;
+                }
+            }
+            /*  The start of the current character (c). */
+            prevSrc=src;
+        } else if(src==limit) {
+            break;
+        }
+
+        src+=U16_LENGTH(c);
+        /*  The current character (c) at [prevSrc..src[ has a non-zero lead combining class. */
+        /*  Check for proper order, and decompose locally if necessary. */
+        if((prevFCD16&0xff)<=(fcd16>>8)) {
+            /*  proper order: prev tccc <= current lccc */
+            if((fcd16&0xff)<=1) {
+                prevBoundary=src;
+            }
+            if(buffer!=NULL && unimp(errorCode) /* !buffer->appendZeroCC(c, errorCode) */) {
+                break;
+            }
+            prevFCD16=fcd16;
+            continue;
+        } else if(buffer==NULL) {
+            return prevBoundary;  /*  quick check "no" */
+        } else {
+          unimp(errorCode);
+#if 0
+            /*
+             * Back out the part of the source that we copied or appended
+             * already but is now going to be decomposed.
+             * prevSrc is set to after what was copied/appended.
+             */
+            buffer->removeSuffix((int32_t)(prevSrc-prevBoundary));
+            /*
+             * Find the part of the source that needs to be decomposed,
+             * up to the next safe boundary.
+             */
+            src=findNextFCDBoundary(src, limit);
+            /*
+             * The source text does not fulfill the conditions for FCD.
+             * Decompose and reorder a limited piece of the text.
+             */
+            if(!decomposeShort(prevBoundary, src, *buffer, errorCode)) {
+                break;
+            }
+            prevBoundary=src;
+            prevFCD16=0;
+#endif
+        }
+    }
+    return src;
+}
+
+#endif
+
+static UBool Normalizer2Impl_decomposeChar(Normalizer2 *_this, UChar32 c, uint16_t norm16,
+                                 ReorderingBuffer *buffer,
+                                 UErrorCode *errorCode)  {
+    /* Only loops for 1:1 algorithmic mappings. */
+    for(;;) {
+        /* get the decomposition and the lead and trail cc's */
+      if(isDecompYes(_this,norm16)) {
+            /* c does not decompose */
+          return ReorderingBuffer_append(buffer, c, getCCFromYesOrMaybe(norm16), errorCode);
+        } else if(isHangul(norm16)) {
+            /* Hangul syllable: decompose algorithmically */
+            UChar jamos[3];
+            return ReorderingBuffer_appendZeroCCStr(buffer, jamos, jamos+Hangul_decompose(c, jamos), errorCode);
+        } else if(isDecompNoAlgorithmic(norm16)) {
+            c=mapAlgorithmic(c, norm16);
+            norm16=getNorm16(c);
+        } else {
+            /* c decomposes, get everything from the variable-length extra data */
+          const uint16_t *mapping;
+          uint16_t firstUnit;
+            int32_t length;
+            uint8_t leadCC, trailCC;
+
+            mapping=getMapping(norm16);
+            firstUnit=*mapping++;
+            length=firstUnit&MAPPING_LENGTH_MASK;
+            trailCC=(uint8_t)(firstUnit>>8);
+            if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) {
+                leadCC=(uint8_t)(*mapping++>>8);
+            } else {
+                leadCC=0;
+            }
+            return ReorderingBuffer_appendLeadTrail(buffer, (const UChar *)mapping, length, leadCC, trailCC, errorCode);
+        }
+    }
+}
+
+
+/*  Dual functionality: */
+/*  buffer!=NULL: normalize */
+/*  buffer==NULL: isNormalized/spanQuickCheckYes */
+static const UChar *
+Normalizer2_decomp_decompose(Normalizer2 *_this, const UChar *src, const UChar *limit,
+                           ReorderingBuffer *buffer,
+                           UErrorCode *errorCode) {
+    /*  only for quick check */
+    const UChar *prevBoundary=src;
+    uint8_t prevCC=0;
+    const UChar *prevSrc;
+    UChar32 c=0;
+    uint16_t norm16=0;
+    UChar32 minNoCP=_this->minDecompNoCP;
+    if(limit==NULL) {
+      src=Normalizer2_fcd_copyLowPrefixFromNulTerminated(_this, src, minNoCP, buffer, errorCode);
+      if(U_FAILURE(*errorCode)) {
+            return src;
+        }
+        limit=u_strchr(src, 0);
+    }
+
+    for(;;) {
+        /*  count code units below the minimum or with irrelevant data for the quick check */
+        for(prevSrc=src; src!=limit;) {
+            if( (c=*src)<minNoCP ||
+                isMostDecompYesAndZeroCC(_this, norm16=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(_this->normTrie, c))
+            ) {
+                ++src;
+            } else if(!U16_IS_SURROGATE(c)) {
+                break;
+            } else {
+                UChar c2;
+                if(U16_IS_SURROGATE_LEAD(c)) {
+                    if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
+                        c=U16_GET_SUPPLEMENTARY(c, c2);
+                    }
+                } else /* trail surrogate */ {
+                    if(prevSrc<src && U16_IS_LEAD(c2=*(src-1))) {
+                        --src;
+                        c=U16_GET_SUPPLEMENTARY(c2, c);
+                    }
+                }
+                if(isMostDecompYesAndZeroCC(_this, norm16=getNorm16(c))) {
+                    src+=U16_LENGTH(c);
+                } else {
+                    break;
+                }
+            }
+        }
+        /*  copy these code units all at once */
+        if(src!=prevSrc) {
+          if(buffer!=NULL && unimp(errorCode)) {
+                /* if(!buffer->appendZeroCC(prevSrc, src, errorCode)) { */
+                /*     break; */
+                /* } */
+            } else {
+                prevCC=0;
+                prevBoundary=src;
+            }
+        }
+        if(src==limit) {
+            break;
+        }
+
+        /*  Check one above-minimum, relevant code point. */
+        src+=U16_LENGTH(c);
+        if(buffer!=NULL && unimp(errorCode)) {
+            /* if(!decompose(c, norm16, *buffer, errorCode)) { */
+            /*     break; */
+            /* } */
+        } else {
+          if(isDecompYes(_this,norm16)) {
+                uint8_t cc=getCCFromYesOrMaybe(norm16);
+                if(prevCC<=cc || cc==0) {
+                    prevCC=cc;
+                    if(cc<=1) {
+                        prevBoundary=src;
+                    }
+                    continue;
+                }
+            }
+            return prevBoundary;  /*  "no" or cc out of order */
+        }
+    }
+    return src;
+}
+
+
+
+static uint8_t Normalizer2_getTrailCCFromCompYesAndZeroCC(Normalizer2 *_this, const UChar *cpStart, const UChar *cpLimit)  {
+    UChar32 c;
+    uint16_t prevNorm16;
+    if(cpStart==(cpLimit-1)) {
+        c=*cpStart;
+    } else {
+        c=U16_GET_SUPPLEMENTARY(cpStart[0], cpStart[1]);
+    }
+    prevNorm16=getNorm16(c);
+    if(prevNorm16<=_this->minYesNo) {
+      return 0;  /* yesYes and Hangul LV/LVT have ccc=tccc=0 */
+    } else {
+      return (uint8_t)(*getMapping(prevNorm16)>>8);  /* tccc from yesNo */
+    }
+}
+
+
+static void Normalizer2Impl_composeAndAppend(Normalizer2 *_this, const UChar *src, const UChar *limit,
+                                       UBool doCompose,
+                                       UBool onlyContiguous,
+                                       ReorderingBuffer *buffer,
+                                       UErrorCode *errorCode)  {
+    if(!ReorderingBuffer_isEmpty(buffer)) {
+      const UChar *firstStarterInSrc=Normalizer2Impl_findNextCompBoundary(_this,src, limit);
+        if(src!=firstStarterInSrc) {
+          const UChar *lastStarterInDest=Normalizer2Impl_findPreviousCompBoundary(_this, ReorderingBuffer_getStart(buffer),
+                                                                    ReorderingBuffer_getLimit(buffer));
+#if 1
+          unimp(errorCode); 
+#else
+          /* TODO! */
+            UnicodeString middle(lastStarterInDest,
+                                 (int32_t)(buffer.getLimit()-lastStarterInDest));
+            buffer.removeSuffix((int32_t)(buffer.getLimit()-lastStarterInDest));
+            middle.append(src, (int32_t)(firstStarterInSrc-src));
+            const UChar *middleStart=middle.getBuffer();
+            compose(middleStart, middleStart+middle.length(), onlyContiguous,
+                    TRUE, buffer, errorCode);
+#endif
+            if(U_FAILURE(*errorCode)) {
+                return;
+            }
+            src=firstStarterInSrc;
+        }
+    }
+    if(doCompose) {
+      Normalizer2_comp_compose(_this, src, limit, onlyContiguous, TRUE, buffer, errorCode);
+    } else {
+      ReorderingBuffer_appendZeroCCStr(buffer, src, limit, errorCode);
+    }
+}
+
+/**
+ * Does c have a composition boundary before it?
+ * True if its decomposition begins with a character that has
+ * ccc=0 && NFC_QC=Yes (isCompYesAndZeroCC()).
+ * As a shortcut, this is true if c itself has ccc=0 && NFC_QC=Yes
+ * (isCompYesAndZeroCC()) so we need not decompose.
+ */
+static UBool Normalizer2Impl_hasCompBoundaryBefore(Normalizer2 *_this, UChar32 c, uint16_t norm16) {
+    for(;;) {
+        if(isCompYesAndZeroCC(norm16)) {
+            return TRUE;
+        } else if(isMaybeOrNonZeroCC(norm16)) {
+            return FALSE;
+        } else if(isDecompNoAlgorithmic(norm16)) {
+            c=mapAlgorithmic(c, norm16);
+            norm16=getNorm16(c);
+        } else {
+            /*  c decomposes, get everything from the variable-length extra data */
+            int32_t i=0;
+            UChar32 c;
+            const uint16_t *mapping=getMapping(norm16);
+            {
+              uint16_t firstUnit=*mapping++;
+              if((firstUnit&MAPPING_LENGTH_MASK)==0) {
+                return FALSE;
+              }
+              if((firstUnit&MAPPING_HAS_CCC_LCCC_WORD) && (*mapping++&0xff00)) {
+                return FALSE;  /*  non-zero leadCC */
+              }
+              U16_NEXT_UNSAFE(mapping, i, c);
+              return isCompYesAndZeroCC(getNorm16(c));
+            }
+        }
+    }
+}
+
+static UBool Normalizer2Impl_hasCompBoundaryAfter(Normalizer2 *_this, UChar32 c, UBool onlyContiguous, UBool testInert)  {
+    for(;;) {
+        uint16_t norm16=getNorm16(c);
+        if(isInert(norm16)) {
+            return TRUE;
+        } else if(norm16<=_this->minYesNo) {
+            /*  Hangul LVT (==minYesNo) has a boundary after it. */
+            /*  Hangul LV and non-inert yesYes characters combine forward. */
+          return isHangul(norm16) && !/*Hangul::*/isHangulWithoutJamoT((UChar)c);
+        } else if(norm16>= (testInert ? _this->minNoNo : _this->minMaybeYes)) {
+            return FALSE;
+        } else if(isDecompNoAlgorithmic(norm16)) {
+            c=mapAlgorithmic(c, norm16);
+        } else {
+            /*  c decomposes, get everything from the variable-length extra data. */
+            /*  If testInert, then c must be a yesNo character which has lccc=0, */
+            /*  otherwise it could be a noNo. */
+            const uint16_t *mapping=getMapping(norm16);
+            {
+              uint16_t firstUnit=*mapping;
+              /*  TRUE if */
+              /*       c is not deleted, and */
+              /*       it and its decomposition do not combine forward, and it has a starter, and */
+              /*       if FCC then trailCC<=1 */
+              return
+                (firstUnit&MAPPING_LENGTH_MASK)!=0 &&
+                (firstUnit&(MAPPING_PLUS_COMPOSITION_LIST|MAPPING_NO_COMP_BOUNDARY_AFTER))==0 &&
+                (!_this->onlyContiguous || firstUnit<=0x1ff);
+            }
+        }
+    }
+}
+
+typedef struct {
+    const UTrie2 *trie;
+    const UChar *codePointStart, *codePointLimit;
+    UChar32 codePoint;
+    const UChar *start;
+  
+}  BackwardsUTrie2StringIterator;
+
+static void BackwardsUTrie2StringIterator_init(BackwardsUTrie2StringIterator *iter, const UTrie2*t, const UChar *s, const UChar *p) {
+  iter->trie = t;
+  iter->codePointStart=p;
+  iter->codePointLimit=p;
+  iter->codePoint=U_SENTINEL;
+  iter->start=s;
+}
+
+static uint16_t BackwardsUTrie2StringIterator_previous16(BackwardsUTrie2StringIterator *iter) {
+    uint16_t result;
+    iter->codePointLimit=iter->codePointStart;
+    if(iter->start>=iter->codePointStart) {
+        iter->codePoint=U_SENTINEL;
+        return 0;
+    }
+    UTRIE2_U16_PREV16(iter->trie, iter->start, iter->codePointStart, iter->codePoint, result);
+    return result;
+}
+
+typedef struct {
+    const UTrie2 *trie;
+    const UChar *codePointStart, *codePointLimit;
+    UChar32 codePoint;
+    const UChar *limit;
+  
+}  ForwardUTrie2StringIterator;
+
+static void ForwardUTrie2StringIterator_init(ForwardUTrie2StringIterator *iter, const UTrie2*t, const UChar *p, const UChar *l) {
+  iter->trie = t;
+  iter->codePointStart=p;
+  iter->codePointLimit=p;
+  iter->codePoint=U_SENTINEL;
+  iter->limit=l;
+}
+
+static uint16_t ForwardUTrie2StringIterator_next16(ForwardUTrie2StringIterator *iter) {
+    uint16_t result;
+    iter->codePointStart=iter->codePointLimit;
+    if(iter->limit == iter->codePointLimit) {
+        iter->codePoint=U_SENTINEL;
+        return 0;
+    }
+    UTRIE2_U16_NEXT16(iter->trie, iter->codePointLimit, iter->limit, iter->codePoint, result);
+    return result;
+}
+
+static const UChar *Normalizer2Impl_findPreviousCompBoundary(Normalizer2 *_this, const UChar *start, const UChar *p) {
+  BackwardsUTrie2StringIterator iter;
+  uint16_t norm16;
+  BackwardsUTrie2StringIterator_init(&iter, _this->normTrie, start, p);
+    do {
+        norm16=BackwardsUTrie2StringIterator_previous16(&iter);
+    } while(!Normalizer2Impl_hasCompBoundaryBefore(_this, iter.codePoint, norm16));
+    /*  We could also test hasCompBoundaryAfter() and return iter.codePointLimit, */
+    /*  but that's probably not worth the extra cost. */
+    return iter.codePointStart;
+}
+
+static const UChar *Normalizer2Impl_findNextCompBoundary(Normalizer2 *_this, const UChar *p, const UChar *limit)  {
+    uint16_t norm16;
+    ForwardUTrie2StringIterator iter;
+
+    ForwardUTrie2StringIterator_init(&iter, _this->normTrie, p, limit);
+    do {
+        norm16=ForwardUTrie2StringIterator_next16(&iter);
+    } while(!Normalizer2Impl_hasCompBoundaryBefore(_this, iter.codePoint, norm16));
+    return iter.codePointStart;
+}
+
+
+/*
+ * Finds the recomposition result for
+ * a forward-combining "lead" character,
+ * specified with a pointer to its compositions list,
+ * and a backward-combining "trail" character.
+ *
+ * If the lead and trail characters combine, then this function returns
+ * the following "compositeAndFwd" value:
+ * Bits 21..1  composite character
+ * Bit      0  set if the composite is a forward-combining starter
+ * otherwise it returns -1.
+ *
+ * The compositions list has (trail, compositeAndFwd) pair entries,
+ * encoded as either pairs or triples of 16-bit units.
+ * The last entry has the high bit of its first unit set.
+ *
+ * The list is sorted by ascending trail characters (there are no duplicates).
+ * A linear search is used.
+ *
+ * See normalizer2impl.h for a more detailed description
+ * of the compositions list format.
+ */
+static int32_t Normalizer2Impl_combine(Normalizer2 *_this, const uint16_t *list, UChar32 trail) {
+    uint16_t key1, firstUnit;
+    if(trail<COMP_1_TRAIL_LIMIT) {
+        /*  trail character is 0..33FF */
+        /*  result entry may have 2 or 3 units */
+        key1=(uint16_t)(trail<<1);
+        while(key1>(firstUnit=*list)) {
+            list+=2+(firstUnit&COMP_1_TRIPLE);
+        }
+        if(key1==(firstUnit&COMP_1_TRAIL_MASK)) {
+            if(firstUnit&COMP_1_TRIPLE) {
+                return ((int32_t)list[1]<<16)|list[2];
+            } else {
+                return list[1];
+            }
+        }
+    } else {
+        /*  trail character is 3400..10FFFF */
+        /*  result entry has 3 units */
+        uint16_t secondUnit;
+        uint16_t key2;
+        key1=(uint16_t)(COMP_1_TRAIL_LIMIT+
+                        ((trail>>COMP_1_TRAIL_SHIFT))&
+                         ~COMP_1_TRIPLE);
+
+        key2 =(uint16_t)(trail<<COMP_2_TRAIL_SHIFT);
+        for(;;) {
+            if(key1>(firstUnit=*list)) {
+                list+=2+(firstUnit&COMP_1_TRIPLE);
+            } else if(key1==(firstUnit&COMP_1_TRAIL_MASK)) {
+                if(key2>(secondUnit=list[1])) {
+                    if(firstUnit&COMP_1_LAST_TUPLE) {
+                        break;
+                    } else {
+                        list+=3;
+                    }
+                } else if(key2==(secondUnit&COMP_2_TRAIL_MASK)) {
+                    return ((int32_t)(secondUnit&~COMP_2_TRAIL_MASK)<<16)|list[2];
+                } else {
+                    break;
+                }
+            } else {
+                break;
+            }
+        }
+    }
+    return -1;
+}
+
+
+/*
+ * Recomposes the buffer text starting at recomposeStartIndex
+ * (which is in NFD - decomposed and canonically ordered),
+ * and truncates the buffer contents.
+ *
+ * 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.
+ */
+static void Normalizer2Impl_recompose(Normalizer2 *_this, ReorderingBuffer *buffer, int32_t recomposeStartIndex,
+                                UBool onlyContiguous) {
+  UChar *p;
+  UChar *limit;
+  UChar *starter, *pRemove, *q, *r;
+  const uint16_t *compositionsList;
+  UChar32 c, compositeAndFwd;
+  uint16_t norm16;
+  uint8_t cc, prevCC;
+  UBool starterIsSupplementary;
+  
+  
+  p=ReorderingBuffer_getStart(buffer)+recomposeStartIndex;
+  limit=ReorderingBuffer_getLimit(buffer);
+  
+
+    if(p==limit) {
+        return;
+    }
+
+    /*  Some of the following variables are not used until we have a forward-combining starter */
+    /*  and are only initialized now to avoid compiler warnings. */
+    compositionsList=NULL;  /*  used as indicator for whether we have a forward-combining starter */
+    starter=NULL;
+    starterIsSupplementary=FALSE;
+    prevCC=0;
+
+    for(;;) {
+        UTRIE2_U16_NEXT16(_this->normTrie, p, limit, c, norm16);
+        cc=getCCFromYesOrMaybe(norm16);
+        if( /*  this character combines backward and */
+            isMaybe(norm16) &&
+            /*  we have seen a starter that combines forward and */
+            compositionsList!=NULL &&
+            /*  the backward-combining character is not blocked */
+            (prevCC<cc || prevCC==0)
+        ) {
+            if(isJamoVT(norm16)) {
+                /*  c is a Jamo V/T, see if we can compose it with the previous character. */
+                if(c</*Hangul::*/JAMO_T_BASE) {
+                    /*  c is a Jamo Vowel, compose with previous Jamo L and following Jamo T. */
+                    UChar prev=(UChar)(*starter-/*Hangul::*/JAMO_L_BASE);
+                    if(prev</*Hangul::*/JAMO_L_COUNT) {
+                        UChar t;
+                        UChar syllable=(UChar)
+                            (/*Hangul::*/HANGUL_BASE+
+                             (prev*/*Hangul::*/JAMO_V_COUNT+(c-/*Hangul::*/JAMO_V_BASE))*
+                             /*Hangul::*/JAMO_T_COUNT);
+                        pRemove=p-1;
+                        if(p!=limit && (t=(UChar)(*p-/*Hangul::*/JAMO_T_BASE))</*Hangul::*/JAMO_T_COUNT) {
+                            ++p;
+                            syllable+=t;  /*  The next character was a Jamo T. */
+                        }
+                        *starter=syllable;
+                        /*  remove the Jamo V/T */
+                        q=pRemove;
+                        r=p;
+                        while(r<limit) {
+                            *q++=*r++;
+                        }
+                        limit=q;
+                        p=pRemove;
+                    }
+                }
+                /*
+                 * No "else" for Jamo T:
+                 * 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.
+                 */
+                if(p==limit) {
+                    break;
+                }
+                compositionsList=NULL;
+                continue;
+            } else if((compositeAndFwd=Normalizer2Impl_combine(_this, compositionsList, c))>=0) {
+                /*  The starter and the combining mark (c) do combine. */
+              UChar32 composite;
+
+              composite =compositeAndFwd>>1;
+
+                /*  Replace the starter with the composite, remove the combining mark. */
+                pRemove=p-U16_LENGTH(c);  /*  pRemove & p: start & limit of the combining mark */
+                if(starterIsSupplementary) {
+                    if(U_IS_SUPPLEMENTARY(composite)) {
+                        /*  both are supplementary */
+                        starter[0]=U16_LEAD(composite);
+                        starter[1]=U16_TRAIL(composite);
+                    } else {
+                        *starter=(UChar)composite;
+                        /*  The composite is shorter than the starter, */
+                        /*  move the intermediate characters forward one. */
+                        starterIsSupplementary=FALSE;
+                        q=starter+1;
+                        r=q+1;
+                        while(r<pRemove) {
+                            *q++=*r++;
+                        }
+                        --pRemove;
+                    }
+                } else if(U_IS_SUPPLEMENTARY(composite)) {
+                    /*  The composite is longer than the starter, */
+                    /*  move the intermediate characters back one. */
+                    starterIsSupplementary=TRUE;
+                    ++starter;  /*  temporarily increment for the loop boundary */
+                    q=pRemove;
+                    r=++pRemove;
+                    while(starter<q) {
+                        *--r=*--q;
+                    }
+                    *starter=U16_TRAIL(composite);
+                    *--starter=U16_LEAD(composite);  /*  undo the temporary increment */
+                } else {
+                    /*  both are on the BMP */
+                    *starter=(UChar)composite;
+                }
+
+                /* remove the combining mark by moving the following text over it */
+                if(pRemove<p) {
+                    q=pRemove;
+                    r=p;
+                    while(r<limit) {
+                        *q++=*r++;
+                    }
+                    limit=q;
+                    p=pRemove;
+                }
+                /*  Keep prevCC because we removed the combining mark. */
+
+                if(p==limit) {
+                    break;
+                }
+                /*  Is the composite a starter that combines forward? */
+                if(compositeAndFwd&1) {
+                    compositionsList=
+                      Normalizer2_getCompositionsListForComposite(_this, getNorm16(composite));
+                } else {
+                    compositionsList=NULL;
+                }
+
+                /*  We combined; continue with looking for compositions. */
+                continue;
+            }
+        }
+
+        /*  no combination this time */
+        prevCC=cc;
+        if(p==limit) {
+            break;
+        }
+
+        /*  If c did not combine, then check if it is a starter. */
+        if(cc==0) {
+            /*  Found a new starter. */
+          if((compositionsList=Normalizer2_getCompositionsListForDecompYes(_this, norm16))!=NULL) {
+                /*  It may combine with something, prepare for it. */
+                if(U_IS_BMP(c)) {
+                    starterIsSupplementary=FALSE;
+                    starter=p-1;
+                } else {
+                    starterIsSupplementary=TRUE;
+                    starter=p-2;
+                }
+            }
+        } else if(onlyContiguous) {
+            /*  FCC: no discontiguous compositions; any intervening character blocks. */
+            compositionsList=NULL;
+        }
+    }
+    ReorderingBuffer_setReorderingLimit(buffer, limit);
+}
+
+/* Decompose a short piece of text which is likely to contain characters that */
+/* fail the quick check loop and/or where the quick check loop's overhead */
+/* is unlikely to be amortized. */
+/* Called by the compose() and makeFCD() implementations. */
+static UBool Normalizer2Impl_decomposeShort(Normalizer2 *_this, const UChar *src, const UChar *limit,
+                                      ReorderingBuffer *buffer,
+                                      UErrorCode *errorCode)  {
+    while(src<limit) {
+        UChar32 c;
+        uint16_t norm16;
+        UTRIE2_U16_NEXT16(_this->normTrie, src, limit, c, norm16);
+        if(!Normalizer2Impl_decomposeChar(_this, c, norm16, buffer, errorCode)) {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+
+/*  Very similar to composeQuickCheck(): Make the same changes in both places if relevant. */
+/*  doCompose: normalize */
+/*  !doCompose: isNormalized (buffer must be empty and initialized) */
+static UBool
+Normalizer2_comp_compose(Normalizer2 *_this, const UChar *src, const UChar *limit,
+                         UBool onlyContiguous,
+                         UBool doCompose,
+                         ReorderingBuffer *buffer,
+                         UErrorCode *errorCode)  {
+    /*
+     * prevBoundary points to the last character before the current one
+     * that has a composition boundary before it with ccc==0 and quick check "yes".
+     * Keeping track of prevBoundary saves us looking for a composition boundary
+     * when we find a "no" or "maybe".
+     *
+     * When we back out from prevSrc back to prevBoundary,
+     * then we also remove those same characters (which had been simply copied
+     * or canonically-order-inserted) from the ReorderingBuffer.
+     * Therefore, at all times, the [prevBoundary..prevSrc[ source units
+     * must correspond 1:1 to destination units at the end of the destination buffer.
+     */
+
+  const UChar *prevBoundary=src;
+  const UChar *prevSrc;
+  UChar32 c=0;
+  uint16_t norm16=0;
+
+    /*  only for isNormalized */
+  uint8_t prevCC=0;
+  UChar32 minNoMaybeCP=_this->minCompNoMaybeCP;
+  
+    if(limit==NULL) {
+        UErrorCode errorCode2=U_ZERO_ERROR;
+        src=Normalizer2_fcd_copyLowPrefixFromNulTerminated(_this, src, minNoMaybeCP, NULL, &errorCode2);
+        limit=u_strchr(src, 0);
+    }
+
+
+    for(;;) {
+        int32_t recomposeStartIndex;
+        /*  count code units below the minimum or with irrelevant data for the quick check */
+        for(prevSrc=src; src!=limit;) {
+            if( (c=*src)<minNoMaybeCP ||
+                isCompYesAndZeroCC(norm16=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(_this->normTrie, c))
+            ) {
+                ++src;
+            } else if(!U16_IS_SURROGATE(c)) {
+                break;
+            } else {
+                UChar c2;
+                if(U16_IS_SURROGATE_LEAD(c)) {
+                    if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
+                        c=U16_GET_SUPPLEMENTARY(c, c2);
+                    }
+                } else /* trail surrogate */ {
+                    if(prevSrc<src && U16_IS_LEAD(c2=*(src-1))) {
+                        --src;
+                        c=U16_GET_SUPPLEMENTARY(c2, c);
+                    }
+                }
+                if(isCompYesAndZeroCC(norm16=getNorm16(c))) {
+                    src+=U16_LENGTH(c);
+                } else {
+                    break;
+                }
+            }
+        }
+        /*  copy these code units all at once */
+        if(src!=prevSrc) {
+            if(doCompose) {
+              if(!ReorderingBuffer_appendZeroCCStr(buffer, prevSrc, src, errorCode)) {
+                    break;
+                }
+            } else {
+                prevCC=0;
+            }
+            if(src==limit) {
+                break;
+            }
+            /*  Set prevBoundary to the last character in the quick check loop. */
+            prevBoundary=src-1;
+            if( U16_IS_TRAIL(*prevBoundary) && prevSrc<prevBoundary &&
+                U16_IS_LEAD(*(prevBoundary-1))
+            ) {
+                --prevBoundary;
+            }
+            /*  The start of the current character (c). */
+            prevSrc=src;
+        } else if(src==limit) {
+            break;
+        }
+
+        src+=U16_LENGTH(c);
+        /*
+         * isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo.
+         * c is either a "noNo" (has a mapping) or a "maybeYes" (combines backward)
+         * or has ccc!=0.
+         * Check for Jamo V/T, then for regular characters.
+         * c is not a Hangul syllable or Jamo L because those have "yes" properties.
+         */
+        if(isJamoVT(norm16) && prevBoundary!=prevSrc) {
+            UBool needToDecompose=FALSE;
+            UChar prev=*(prevSrc-1);
+            if(c</* Hangul:: */JAMO_T_BASE) {
+                /*  c is a Jamo Vowel, compose with previous Jamo L and following Jamo T. */
+                prev=(UChar)(prev-/* Hangul:: */JAMO_L_BASE);
+                if(prev</* Hangul:: */JAMO_L_COUNT) {
+                    UChar t;
+                    UChar syllable=(UChar)
+                        (/* Hangul:: */HANGUL_BASE+
+                         (prev*/* Hangul:: */JAMO_V_COUNT+(c-/* Hangul:: */JAMO_V_BASE))*
+                         /* Hangul:: */JAMO_T_COUNT);
+                    if(!doCompose) {
+                        return FALSE;
+                    }
+                    if(src!=limit && (t=(UChar)(*src-/* Hangul:: */JAMO_T_BASE))</* Hangul:: */JAMO_T_COUNT) {
+                        ++src;
+                        syllable+=t;  /*  The next character was a Jamo T. */
+                        prevBoundary=src;
+                        ReorderingBuffer_setLastChar(buffer,syllable);
+                        continue;
+                    }
+                    /*  If we see L+V+x where x!=T then we drop to the slow path, */
+                    /*  decompose and recompose. */
+                    /*  This is to deal with NFKC finding normal L and V but a */
+                    /*  compatibility variant of a T. We need to either fully compose that */
+                    /*  combination here (which would complicate the code and may not work */
+                    /*  with strange custom data) or use the slow path -- or else our replacing */
+                    /*  two input characters (L+V) with one output character (LV syllable) */
+                    /*  would violate the invariant that [prevBoundary..prevSrc[ has the same */
+                    /*  length as what we appended to the buffer since prevBoundary. */
+                    needToDecompose=TRUE;
+                }
+            } else if(/* Hangul:: */isHangulWithoutJamoT(prev)) {
+                /*  c is a Jamo Trailing consonant, */
+                /*  compose with previous Hangul LV that does not contain a Jamo T. */
+                if(!doCompose) {
+                    return FALSE;
+                }
+                ReorderingBuffer_setLastChar(buffer, (UChar)(prev+c-/* Hangul:: */JAMO_T_BASE));
+                prevBoundary=src;
+                continue;
+            }
+            if(!needToDecompose) {
+                /*  The Jamo V/T did not compose into a Hangul syllable. */
+                if(doCompose) {
+                  if(!ReorderingBuffer_appendBMP(buffer, (UChar)c, 0, errorCode)) {
+                        break;
+                    }
+                } else {
+                    prevCC=0;
+                }
+                continue;
+            }
+        }
+        /*
+         * Source buffer pointers:
+         *
+         *  all done      quick check   current char  not yet
+         *                "yes" but     (c)           processed
+         *                may combine
+         *                forward
+         * [-------------[-------------[-------------[-------------[
+         * |             |             |             |             |
+         * orig. src     prevBoundary  prevSrc       src           limit
+         *
+         *
+         * Destination buffer pointers inside the ReorderingBuffer:
+         *
+         *  all done      might take    not filled yet
+         *                characters for
+         *                reordering
+         * [-------------[-------------[-------------[
+         * |             |             |             |
+         * start         reorderStart  limit         |
+         *                             +remainingCap.+
+         */
+        if(norm16>=MIN_YES_YES_WITH_CC) {
+            uint8_t cc=(uint8_t)norm16;  /*  cc!=0 */
+            if( onlyContiguous &&  /*  FCC */
+                (doCompose ? ReorderingBuffer_getLastCC(buffer) : prevCC)==0 &&
+                prevBoundary<prevSrc &&
+                /*  ReorderingBuffer_getLastCC(buffer)==0 && prevBoundary<prevSrc tell us that */
+                /*  [prevBoundary..prevSrc[ (which is exactly one character under these conditions) */
+                /*  passed the quick check "yes && ccc==0" test. */
+                /*  Check whether the last character was a "yesYes" or a "yesNo". */
+                /*  If a "yesNo", then we get its trailing ccc from its */
+                /*  mapping and check for canonical order. */
+                /*  All other cases are ok. */
+                Normalizer2_getTrailCCFromCompYesAndZeroCC(_this,prevBoundary, prevSrc)>cc
+            ) {
+                /*  Fails FCD test, need to decompose and contiguously recompose. */
+                if(!doCompose) {
+                    return FALSE;
+                }
+            } else if(doCompose) {
+              if(!ReorderingBuffer_append(buffer, c, cc, errorCode)) {
+                    break;
+                }
+                continue;
+            } else if(prevCC<=cc) {
+                prevCC=cc;
+                continue;
+            } else {
+                return FALSE;
+            }
+        } else if(!doCompose && !isMaybeOrNonZeroCC(norm16)) {
+            return FALSE;
+        }
+
+        /*
+         * Find appropriate boundaries around this character,
+         * decompose the source text from between the boundaries,
+         * and recompose it.
+         *
+         * We may need to remove the last few characters from the ReorderingBuffer
+         * to account for source text that was copied or appended
+         * but needs to take part in the recomposition.
+         */
+
+        /*
+         * Find the last composition boundary in [prevBoundary..src[.
+         * It is either the decomposition of the current character (at prevSrc),
+         * or prevBoundary.
+         */
+        if(Normalizer2Impl_hasCompBoundaryBefore(_this,c, norm16)) {
+            prevBoundary=prevSrc;
+        } else if(doCompose) {
+            ReorderingBuffer_removeSuffix(buffer, (int32_t)(prevSrc-prevBoundary));
+        }
+
+        /*  Find the next composition boundary in [src..limit[ - */
+        /*  modifies src to point to the next starter. */
+        src=(UChar *)Normalizer2Impl_findNextCompBoundary(_this,src, limit);
+
+        /*  Decompose [prevBoundary..src[ into the buffer and then recompose that part of it. */
+          recomposeStartIndex=ReorderingBuffer_length(buffer);
+          if(!Normalizer2Impl_decomposeShort(_this, prevBoundary, src, buffer, errorCode)) {
+            break;
+        }
+          Normalizer2Impl_recompose(_this, buffer, recomposeStartIndex, _this->onlyContiguous);
+        if(!doCompose) {
+            if(!ReorderingBuffer_equals(buffer, prevBoundary, src)) {
+                return FALSE;
+            }
+            ReorderingBuffer_remove(buffer);
+            prevCC=0;
+        }
+
+        /*  Move to the next starter. We never need to look back before this point again. */
+        prevBoundary=src;
+    }
+    return TRUE;
+}
+
+
+/*  Very similar to compose(): Make the same changes in both places if relevant. */
+/*  pQCResult==NULL: spanQuickCheckYes */
+/*  pQCResult!=NULL: quickCheck (*pQCResult must be UNORM_YES) */
+static const UChar *
+Normalizer2_comp_composeQuickCheck(Normalizer2 *_this, const UChar *src, const UChar *limit,
+                                   UBool onlyContiguous,
+                                   UNormalizationCheckResult *pQCResult)  {
+    /*
+     * prevBoundary points to the last character before the current one
+     * that has a composition boundary before it with ccc==0 and quick check "yes".
+     */
+    const UChar *prevBoundary=src;
+    const UChar *prevSrc;
+    UChar32 c=0;
+    uint16_t norm16=0;
+    uint8_t prevCC=0;
+    UChar32 minNoMaybeCP=_this->minCompNoMaybeCP;
+
+    if(limit==NULL) {
+        UErrorCode errorCode=U_ZERO_ERROR;
+        src=Normalizer2_fcd_copyLowPrefixFromNulTerminated(_this, src, minNoMaybeCP, NULL, &errorCode);
+        limit=u_strchr(src, 0);
+    }
+
+
+    for(;;) {
+        /*  count code units below the minimum or with irrelevant data for the quick check */
+        for(prevSrc=src;;) {
+            if(src==limit) {
+                return src;
+            }
+            if( (c=*src)<minNoMaybeCP ||
+                isCompYesAndZeroCC(norm16=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(_this->normTrie, c))
+            ) {
+                ++src;
+            } else if(!U16_IS_SURROGATE(c)) {
+                break;
+            } else {
+                UChar c2;
+                if(U16_IS_SURROGATE_LEAD(c)) {
+                    if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
+                        c=U16_GET_SUPPLEMENTARY(c, c2);
+                    }
+                } else /* trail surrogate */ {
+                    if(prevSrc<src && U16_IS_LEAD(c2=*(src-1))) {
+                        --src;
+                        c=U16_GET_SUPPLEMENTARY(c2, c);
+                    }
+                }
+                if(isCompYesAndZeroCC(norm16=getNorm16(c))) {
+                    src+=U16_LENGTH(c);
+                } else {
+                    break;
+                }
+            }
+        }
+        if(src!=prevSrc) {
+            /*  Set prevBoundary to the last character in the quick check loop. */
+            prevBoundary=src-1;
+            if( U16_IS_TRAIL(*prevBoundary) && prevSrc<prevBoundary &&
+                U16_IS_LEAD(*(prevBoundary-1))
+            ) {
+                --prevBoundary;
+            }
+            prevCC=0;
+            /*  The start of the current character (c). */
+            prevSrc=src;
+        }
+
+        src+=U16_LENGTH(c);
+        /*
+         * isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo.
+         * c is either a "noNo" (has a mapping) or a "maybeYes" (combines backward)
+         * or has ccc!=0.
+         */
+        if(isMaybeOrNonZeroCC(norm16)) {
+            uint8_t cc=getCCFromYesOrMaybe(norm16);
+            if( onlyContiguous &&  /*  FCC */
+                cc!=0 &&
+                prevCC==0 &&
+                prevBoundary<prevSrc &&
+                /*  prevCC==0 && prevBoundary<prevSrc tell us that */
+                /*  [prevBoundary..prevSrc[ (which is exactly one character under these conditions) */
+                /*  passed the quick check "yes && ccc==0" test. */
+                /*  Check whether the last character was a "yesYes" or a "yesNo". */
+                /*  If a "yesNo", then we get its trailing ccc from its */
+                /*  mapping and check for canonical order. */
+                /*  All other cases are ok. */
+                Normalizer2_getTrailCCFromCompYesAndZeroCC(_this,prevBoundary, prevSrc)>cc
+            ) {
+                /*  Fails FCD test. */
+            } else if(prevCC<=cc || cc==0) {
+                prevCC=cc;
+                if(norm16<MIN_YES_YES_WITH_CC) {
+                    if(pQCResult!=NULL) {
+                        *pQCResult=UNORM_MAYBE;
+                    } else {
+                        return prevBoundary;
+                    }
+                }
+                continue;
+            }
+        }
+        if(pQCResult!=NULL) {
+            *pQCResult=UNORM_NO;
+        }
+        return prevBoundary;
+    }
+}
+
+
+#if UNORM_ENABLE_FCD
+static UChar* Normalizer2_fcd_spanQuickCheckYes(struct Normalizer2* n, const UChar *s, const UChar* limit, UErrorCode *pErrorCode) {
+  return Normalizer2_fcd_makeFCD(n, s, limit, NULL, pErrorCode);
+}
+
+static UChar* Normalizer2_decomp_spanQuickCheckYes(struct Normalizer2* n, const UChar *s, const UChar* limit, UErrorCode *pErrorCode) {
+  return Normalizer2_decomp_decompose(n, s, limit, NULL, pErrorCode);
+}
+#endif
+static const UChar* Normalizer2_comp_spanQuickCheckYes(struct Normalizer2* n, const UChar *s, const UChar* limit, UErrorCode *pErrorCode) {
+  return Normalizer2_comp_composeQuickCheck(n, s, limit, n->onlyContiguous, NULL);
+}
+
+#if UNORM_ENABLE_FCD
+static UBool Normalizer2_fcd_isNormalized(struct Normalizer2* n, const UChar *s, int32_t length, UErrorCode *pErrorCode) {
+  return((s+length)==Normalizer2_fcd_spanQuickCheckYes(n,s,s+length,pErrorCode));
+}
+static UBool Normalizer2_decomp_isNormalized(struct Normalizer2* n, const UChar *s, int32_t length, UErrorCode *pErrorCode) {
+  return((s+length)==Normalizer2_decomp_spanQuickCheckYes(n,s,s+length,pErrorCode));
+}
+#endif
+
+#if 0
+static UBool Normalizer2_comp_isNormalized(struct Normalizer2* n, const UChar *s, int32_t length, UErrorCode *pErrorCode) {
+  return((s+length)==Normalizer2_comp_spanQuickCheckYes(n,s,s+length,pErrorCode));
+}
+#endif
+
+
+#if UNORM_ENABLE_FCD
+static UNormalizationCheckResult U_CALLCONV Normalizer2_fcd_quickCheck(struct Normalizer2* n, const UChar *s, int32_t length, UErrorCode *pErrorCode) {
+  return Normalizer2_fcd_isNormalized(n, s, length, pErrorCode)?UNORM_YES:UNORM_NO;
+}
+#endif
+
+#if UNORM_ENABLE_FCD
+static UNormalizationCheckResult U_CALLCONV Normalizer2_decomp_quickCheck(struct Normalizer2* n, const UChar *s, int32_t length, UErrorCode *pErrorCode) {
+  return Normalizer2_decomp_isNormalized(n, s, length, pErrorCode)?UNORM_YES:UNORM_NO;
+}
+#endif
+static UNormalizationCheckResult U_CALLCONV Normalizer2_comp_quickCheck(struct Normalizer2* n, const UChar *s, int32_t length, UErrorCode *pErrorCode) {
+  UNormalizationCheckResult qcResult=UNORM_YES;
+  Normalizer2_comp_composeQuickCheck(n, s, s+length, n->onlyContiguous, &qcResult);
+  return qcResult;
+}
+
+
+
+
+U_DRAFT const UNormalizer2 * U_EXPORT2
+unorm2_get2Instance(const char *packageName,
+                   const char *name,
+                   UNormalizationMode mode,
+                   UErrorCode *errorCode) {
+  Normalizer2 *_this = NULL;
+  if(U_FAILURE(*errorCode)) {
+    return NULL;
+  }
+  _this =  uprv_malloc(sizeof(Normalizer2));
+  if(_this==NULL) {
+    *errorCode = U_MEMORY_ALLOCATION_ERROR;
+    goto cleanup;
+  }
+  uprv_memset(_this,sizeof(Normalizer2),0); /* zero out */
+
+  if(name == NULL) {
+    /* no-op */
+    _this->quickCheck = Normalizer2_noop_quickCheck;
+    _this->normalize  = Normalizer2_noop_normalize;
+  } else {
+    Normalizer2_load(_this, packageName, name, errorCode); 
+    
+    _this->mode = mode;
+
+    /* Set up functions */
+    _this->close = Normalizer2_close;
+
+    _this->onlyContiguous = FALSE; /* maybe true for FCC? */
+
+    switch(mode) {
+#if UNORM_ENABLE_FCD
+    case UNORM_FCD:
+      {
+        FCDTrieSingleton_createInstance(_this, errorCode);
+        _this->quickCheck = Normalizer2_fcd_quickCheck;
+        _this->normalize = Normalizer2_noop_normalize;        
+      }
+      break;
+    case UNORM_NFD:
+      {
+        _this->quickCheck = Normalizer2_decomp_quickCheck;
+        _this->normalize = Normalizer2_noop_normalize;        
+      }
+      break;
+#endif
+    case UNORM_NFC:
+      {
+        _this->quickCheck = Normalizer2_comp_quickCheck;
+        _this->normalize = Normalizer2_comp_normalize;      
+#if defined(UNORM_DEBUG)
+        fprintf(stderr, "setting NFC for mode=%s\n", MODENAME(mode));
+#endif
+      }
+      break;
+    default:
+      {
+        _this->quickCheck = Normalizer2_noop_quickCheck;
+        _this->normalize = Normalizer2_noop_normalize;
+      }
+      break;
+    }
+
+    if(_this->normalize == Normalizer2_noop_normalize) {
+#if defined(UNORM_DEBUG)
+      fprintf(stderr, "IMP: using noop for %d=%s [name=%s] normalize\n", (int)mode, MODENAME(mode),name);
+#endif
+    }
+    if(_this->quickCheck == Normalizer2_noop_quickCheck) {
+#if defined(UNORM_DEBUG)
+      fprintf(stderr, "IMP: using noop for %d=%s [name=%s] quickCheck\n", (int)mode, MODENAME(mode),name);
+#endif
+    }
+    
+
+  }
+  
+  if(U_FAILURE(*errorCode)) {
+    goto cleanup;
+  }
+  
+  return (UNormalizer2*)_this;
+ cleanup:
+  if(_this !=NULL) {
+    unorm2_close((UNormalizer2*)_this);
+    /* uprv_free(_this);*/
+  }
+  return NULL;
+}
+U_DRAFT const UNormalizer2 * U_EXPORT2
+unorm2_getInstance(const char *packageName,
+                   const char *name,
+                   UNormalization2Mode mode,
+                   UErrorCode *errorCode) {
+  if(U_FAILURE(*errorCode)) return NULL;
+  switch(mode) {
+  case UNORM2_COMPOSE:
+#if defined(UNORM_DEBUG)
+    printf("using UNORM_NFC for: unorm2_getInstance(%s,%s,%s...\n", 
+           packageName,name,MODE2NAME(mode));
+#endif
+    return unorm2_get2Instance(packageName,name,UNORM_NFC, errorCode);
+  default:
+#if defined(UNORM_DEBUG)
+    printf("Unimplemented: unorm2_getInstance(%s,%s,%s...\n", 
+           packageName,name,MODE2NAME(mode));
+#endif
+    *errorCode = U_REGEX_UNIMPLEMENTED;
+    return NULL;
+  }
+}
+
+
+U_DRAFT void U_EXPORT2
+unorm2_close(UNormalizer2 *norm2) {
+  Normalizer2 *norm = (Normalizer2*)norm2;
+  if(norm==NULL) return;
+  if((norm->close)!=NULL) norm->close(norm);
+  uprv_free(norm2);
+}
+
+
+U_DRAFT UNormalizationCheckResult U_EXPORT2
+unorm2_quickCheck(const UNormalizer2 *norm2,
+                  const UChar *s, int32_t length,
+                  UErrorCode *pErrorCode) {
+  Normalizer2 *norm = (Normalizer2*)norm2;
+    if(U_FAILURE(*pErrorCode)) {
+        return UNORM_NO;
+    }
+    if(s==NULL || length<-1) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return UNORM_NO;
+    }
+  return norm->quickCheck(norm, s, length, pErrorCode);
+}
+
+
+U_DRAFT int32_t U_EXPORT2
+unorm2_normalize(const UNormalizer2 *norm2,
+                 const UChar *src, int32_t length,
+                 UChar *dest, int32_t capacity,
+                 UErrorCode *pErrorCode) {
+  Normalizer2 *norm = (Normalizer2*)norm2;
+  if(U_FAILURE(*pErrorCode)) {
+    return 0;
+  }
+  if(src==NULL || length<-1 || capacity<0 || (dest==NULL && capacity>0) || src==dest) {
+    *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+    return 0;
+  }
+  return norm->normalize(norm,src,length,dest,capacity,pErrorCode);
+}
+
+
+
+/** UNORM  { for tests.. } */
+
+
+
+U_CAPI UNormalizationCheckResult U_EXPORT2
+unorm_quickCheck(const UChar *src,
+                 int32_t srcLength, 
+                 UNormalizationMode mode,
+                 UErrorCode *pErrorCode) {
+  const UNormalizer2 *n2= Normalizer2Factory_getInstance(mode, pErrorCode); 
+  return unorm2_quickCheck(n2, src, srcLength, pErrorCode);
+}
+
+/** Public API for normalizing. */
+U_CAPI int32_t U_EXPORT2
+unorm_normalize(const UChar *src, int32_t srcLength,
+                UNormalizationMode mode, int32_t options,
+                UChar *dest, int32_t destCapacity,
+                UErrorCode *pErrorCode) {
+  const UNormalizer2 *n2= Normalizer2Factory_getInstance(mode, pErrorCode); 
+  /* if(options&UNORM_UNICODE_3_2) { */
+  /*   FilteredNormalizer2 fn2(*n2, *uniset_getUnicode32Instance(*pErrorCode)); */
+  /*   return unorm2_normalize((const UNormalizer2 *)&fn2, */
+  /*                           src, srcLength, dest, destCapacity, pErrorCode); */
+  /* } else */ {
+    return unorm2_normalize(n2,
+                            src, srcLength, dest, destCapacity, pErrorCode);
+  }
+}
+
+
+
+
+#endif
diff --git a/source/common/norm2imp.h b/source/common/norm2imp.h
new file mode 100644
index 0000000..12b8937
--- /dev/null
+++ b/source/common/norm2imp.h
@@ -0,0 +1,157 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2009-2011, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  normalizer2impl.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2009nov22
+*   created by: Markus W. Scherer
+*   modified by Steven R. Loomis
+*/
+
+#include "utrie2.h"
+
+#ifndef _NORM2IMP
+#define _NORM2IMP
+
+typedef struct Normalizer2  {
+  void (U_EXPORT2 *close) (struct Normalizer2* n);
+  UNormalizationCheckResult (U_EXPORT2 *quickCheck) (struct Normalizer2* n, const UChar *s, int32_t length, UErrorCode *pErrorCode);
+  int32_t (U_EXPORT2 *normalize) (struct Normalizer2 *n,
+                                  const UChar *src, int32_t length,
+                                  UChar *dest, int32_t capacity,
+                                  UErrorCode *pErrorCode);
+
+  /* from normalizer2impl.h */
+  UDataMemory *memory;
+  UVersionInfo dataVersion;
+
+  /* Code point thresholds for quick check codes. */
+  UChar32 minDecompNoCP;
+  UChar32 minCompNoMaybeCP;
+
+  /* Norm16 value thresholds for quick check combinations and types of extra data. */
+  uint16_t minYesNo;
+  uint16_t minNoNo;
+  uint16_t limitNoNo;
+  uint16_t minMaybeYes;
+
+  UTrie2 *normTrie;
+  const uint16_t *maybeYesCompositions;
+  const uint16_t *extraData;  /* mappings and/or compositions for yesYes, yesNo & noNo characters */
+
+#if UNORM_ENABLE_FCD
+  /* FCD only */
+  UTrie2 *newFCDTrie;
+  UErrorCode fcdErrorCode;
+#endif
+
+  UBool onlyContiguous; /* FCD vs FCC? */
+
+
+  /* ICU4C0 */
+  UNormalization2Mode mode;
+} Normalizer2;
+
+
+typedef struct {
+  UChar *start, *reorderStart, *limit;
+  int32_t capacity, remainingCapacity;
+  uint8_t lastCC;
+  Normalizer2 *impl;
+  UChar *str;
+  UChar *codePointStart, *codePointLimit;
+  
+} ReorderingBuffer;
+
+
+    enum {
+        MIN_CCC_LCCC_CP=0x300
+    };
+
+    enum {
+        MIN_YES_YES_WITH_CC=0xff01,
+        JAMO_VT=0xff00,
+        MIN_NORMAL_MAYBE_YES=0xfe00,
+        JAMO_L=1,
+        MAX_DELTA=0x40
+    };
+
+    enum {
+      /* Byte offsets from the start of the data, after the generic header. */
+        IX_NORM_TRIE_OFFSET,
+        IX_EXTRA_DATA_OFFSET,
+        IX_RESERVED2_OFFSET,
+        IX_RESERVED3_OFFSET,
+        IX_RESERVED4_OFFSET,
+        IX_RESERVED5_OFFSET,
+        IX_RESERVED6_OFFSET,
+        IX_TOTAL_SIZE,
+
+        /* Code point thresholds for quick check codes. */
+        IX_MIN_DECOMP_NO_CP,
+        IX_MIN_COMP_NO_MAYBE_CP,
+
+        /* Norm16 value thresholds for quick check combinations and types of extra data. */
+        IX_MIN_YES_NO,
+        IX_MIN_NO_NO,
+        IX_LIMIT_NO_NO,
+        IX_MIN_MAYBE_YES,
+
+        IX_RESERVED14,
+        IX_RESERVED15,
+        IX_COUNT
+    };
+
+    enum {
+        MAPPING_HAS_CCC_LCCC_WORD=0x80,
+        MAPPING_PLUS_COMPOSITION_LIST=0x40,
+        MAPPING_NO_COMP_BOUNDARY_AFTER=0x20,
+        MAPPING_LENGTH_MASK=0x1f
+    };
+
+    enum {
+        COMP_1_LAST_TUPLE=0x8000,
+        COMP_1_TRIPLE=1,
+        COMP_1_TRAIL_LIMIT=0x3400,
+        COMP_1_TRAIL_MASK=0x7ffe,
+        COMP_1_TRAIL_SHIFT=9,  /* 10-1 for the "triple" bit */
+        COMP_2_TRAIL_SHIFT=6,
+        COMP_2_TRAIL_MASK=0xffc0
+    };
+
+    /* Korean Hangul and Jamo constants */
+    enum {
+        JAMO_L_BASE=0x1100,     /* "lead" jamo */
+        JAMO_V_BASE=0x1161,     /* "vowel" jamo */
+        JAMO_T_BASE=0x11a7,     /* "trail" jamo */
+
+        HANGUL_BASE=0xac00,
+
+        JAMO_L_COUNT=19,
+        JAMO_V_COUNT=21,
+        JAMO_T_COUNT=28,
+
+        JAMO_VT_COUNT=JAMO_V_COUNT*JAMO_T_COUNT,
+
+        HANGUL_COUNT=JAMO_L_COUNT*JAMO_V_COUNT*JAMO_T_COUNT,
+        HANGUL_LIMIT=HANGUL_BASE+HANGUL_COUNT
+    };
+
+#define isHangul(c) (HANGUL_BASE<=c && c<HANGUL_LIMIT)
+
+#define isHangulWithoutJamoTBase(c) (c<HANGUL_COUNT && c%JAMO_T_COUNT==0)
+#define isHangulWithoutJamoT(c) isHangulWithoutJamoTBase(c-HANGUL_BASE)
+#define isJamoL(c)  ((uint32_t)(c-JAMO_L_BASE)<JAMO_L_COUNT)
+#define isJamoV(c)  ((uint32_t)(c-JAMO_V_BASE)<JAMO_V_COUNT)
+#define isJamoVT(norm16)  ( (norm16)==JAMO_VT )
+
+
+
+#endif
diff --git a/source/common/uloc.c b/source/common/uloc.c
index 4ab7d1e..a21d6bd 100644
--- a/source/common/uloc.c
+++ b/source/common/uloc.c
@@ -2056,7 +2056,7 @@
 /* ### Default locale **************************************************/
 
 #if defined(ICU4C0)
-char _locid[999] = { 0 };
+char _locid[999] = "en_US_POSIX";
 
 #if 0
 void locale_set_default_internal(const char *id)
@@ -2187,10 +2187,11 @@
 #endif
 
 const char  *locale_get_default() {
-  return _locid;
+  return "en_US_POSIX";
+  /*  return _locid; */
 }
 void locale_set_default(const char *id) {
-  strcpy(_locid, id);
+  /*  strcpy(_locid, id); */
 }
 #endif
 
diff --git a/source/common/unicode/uconfig.h b/source/common/unicode/uconfig.h
index f3ca51b..51704c9 100644
--- a/source/common/unicode/uconfig.h
+++ b/source/common/unicode/uconfig.h
@@ -46,6 +46,18 @@
 #include "uconfig_local.h"
 #endif
 
+#if defined(ICU4C0)
+#ifndef UCONFIG_NO_COLLATION
+#define UCONFIG_NO_COLLATION 1
+#endif
+#ifndef UCONFIG_NO_IDNA
+#   define UCONFIG_NO_IDNA 1
+#endif
+#ifndef UCONFIG_NO_TRANSLITERATION
+#   define UCONFIG_NO_TRANSLITERATION 1
+#endif
+#endif
+
 /**
  * \def UCONFIG_ONLY_COLLATION
  * This switch turns off modules that are not needed for collation.
@@ -139,7 +151,7 @@
  */
 #ifndef UCONFIG_NO_USET
 # define UCONFIG_NO_USET 0
-#elif UCONFIG_NO_USET
+#elif UCONFIG_NO_USET && !defined(ICU4C0)
 # ifndef UCONFIG_NO_NORMALIZATION
 #  define UCONFIG_NO_NORMALIZATION 1
 # elif !UCONFIG_NO_NORMALIZATION
diff --git a/source/common/utrie2_builder.c b/source/common/utrie2_builder.c
index fc13c5c..925abf2 100644
--- a/source/common/utrie2_builder.c
+++ b/source/common/utrie2_builder.c
@@ -405,6 +405,8 @@
     return context.trie;
 }
 
+
+#ifndef ICU4C0
 /* Almost the same as utrie2_cloneAsThawed() but copies a UTrie and freezes the clone. */
 U_CAPI UTrie2 * U_EXPORT2
 utrie2_fromUTrie(const UTrie *trie1, uint32_t errorValue, UErrorCode *pErrorCode) {
@@ -454,6 +456,7 @@
     }
     return context.trie;
 }
+#endif
 
 static U_INLINE UBool
 isInNullBlock(UNewTrie2 *trie, UChar32 c, UBool forLSCP) {
diff --git a/source/samples/c0test/Makefile.in b/source/samples/c0test/Makefile.in
index 563e5bf..b42e5c5 100644
--- a/source/samples/c0test/Makefile.in
+++ b/source/samples/c0test/Makefile.in
@@ -31,6 +31,12 @@
 
 DEPS = $(OBJECTS:.o=.d)
 
+
+-include Makefile.local
+
+
+
+
 ## List of phony targets
 .PHONY : all all-local install install-local clean clean-local \
 distclean distclean-local dist dist-local check check-local
@@ -77,3 +83,4 @@
 -include $(DEPS)
 endif
 endif
+
diff --git a/source/samples/c0test/c0test.c b/source/samples/c0test/c0test.c
index 5387ab0..c09be12 100644
--- a/source/samples/c0test/c0test.c
+++ b/source/samples/c0test/c0test.c
@@ -15,15 +15,483 @@
 
 #include "unicode/utypes.h"
 #include "unicode/uchar.h"
+#include "unicode/uloc.h"
+#include "unicode/unorm2.h"
+#include "unicode/unorm.h"
+#include "unicode/ucnv.h"
+#include "unicode/ucnv_cb.h"
+
+#include <stdio.h>
+#define log_data_err printf
+#define log_verbose printf
+#define log_err printf
+#define ERRMSG printf("%s:%d: error=%s\n", __FILE__,__LINE__,u_errorName(error))
+#if UCONFIG_NO_NORMALIZATION
+#error UCONFIG_NO_NORMALIZATION set
+#endif
+
+#ifndef LENGTHOF
+#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
+#endif
+
+static const char* res2str(UNormalizationCheckResult res) {
+  switch(res) {
+  case UNORM_YES: return "YES";
+  case UNORM_NO: return "NO";
+  case UNORM_MAYBE: return "MAYBE";
+  default: return "?";
+  }
+}
+
+
+static void TestQuickCheckResultNO() 
+{
+  const UChar CPNFD[] = {0x00C5, 0x0407, 0x1E00, 0x1F57, 0x220C, 
+                         0x30AE, 0xAC00, 0xD7A3, 0xFB36, 0xFB4E};
+  const UChar CPNFC[] = {0x0340, 0x0F93, 0x1F77, 0x1FBB, 0x1FEB, 
+                          0x2000, 0x232A, 0xF900, 0xFA1E, 0xFB4E};
+  const UChar CPNFKD[] = {0x00A0, 0x02E4, 0x1FDB, 0x24EA, 0x32FE, 
+                           0xAC00, 0xFB4E, 0xFA10, 0xFF3F, 0xFA2D};
+  const UChar CPNFKC[] = {0x00A0, 0x017F, 0x2000, 0x24EA, 0x32FE, 
+                           0x33FE, 0xFB4E, 0xFA10, 0xFF3F, 0xFA2D};
+
+
+  const int SIZE = 10;
+
+  int count = 0;
+  UErrorCode error = U_ZERO_ERROR;
+
+  for (; count < SIZE; count ++)
+  {
+    /* if (unorm_quickCheck(&(CPNFD[count]), 1, UNORM_NFD, &error) !=  */
+    /*                                                           UNORM_NO) */
+    /* { */
+    /*   log_err("ERROR in NFD quick check at U+%04x\n", CPNFD[count]); */
+    /*   return; */
+    /* } */
+    if (unorm_quickCheck(&(CPNFC[count]), 1, UNORM_NFC, &error) != 
+                                                              UNORM_NO)
+    {
+      log_err("ERROR in NFC quick check at U+%04x\n", CPNFC[count]);
+      return;
+    }
+    /* if (unorm_quickCheck(&(CPNFKD[count]), 1, UNORM_NFKD, &error) !=  */
+    /*                                                           UNORM_NO) */
+    /* { */
+    /*   log_err("ERROR in NFKD quick check at U+%04x\n", CPNFKD[count]); */
+    /*   return; */
+    /* } */
+    /* if (unorm_quickCheck(&(CPNFKC[count]), 1, UNORM_NFKC, &error) !=  */
+    /*                                                           UNORM_NO) */
+    /* { */
+    /*   log_err("ERROR in NFKC quick check at U+%04x\n", CPNFKC[count]); */
+    /*   return; */
+    /* } */
+  }
+}
+
+ 
+static void TestQuickCheckResultYES() 
+{
+  const UChar CPNFD[] = {0x00C6, 0x017F, 0x0F74, 0x1000, 0x1E9A, 
+                         0x2261, 0x3075, 0x4000, 0x5000, 0xF000};
+  const UChar CPNFC[] = {0x0400, 0x0540, 0x0901, 0x1000, 0x1500, 
+                         0x1E9A, 0x3000, 0x4000, 0x5000, 0xF000};
+  const UChar CPNFKD[] = {0x00AB, 0x02A0, 0x1000, 0x1027, 0x2FFB, 
+                          0x3FFF, 0x4FFF, 0xA000, 0xF000, 0xFA27};
+  const UChar CPNFKC[] = {0x00B0, 0x0100, 0x0200, 0x0A02, 0x1000, 
+                          0x2010, 0x3030, 0x4000, 0xA000, 0xFA0E};
+
+  const int SIZE = 10;
+  int count = 0;
+  UErrorCode error = U_ZERO_ERROR;
+
+  UChar cp = 0;
+  while (cp < 0xA0)
+  {
+    /* if (unorm_quickCheck(&cp, 1, UNORM_NFD, &error) != UNORM_YES) */
+    /* { */
+    /*   ERRMSG; */
+    /*   log_data_err("ERROR in NFD quick check at U+%04x - (Are you missing data?)\n", cp); */
+    /*   return; */
+    /* } */
+    if (unorm_quickCheck(&cp, 1, UNORM_NFC, &error) != 
+                                                             UNORM_YES)
+    {
+      ERRMSG;
+      log_err("ERROR in NFC quick check at U+%04x\n", cp);
+      return;
+    }
+    /* if (unorm_quickCheck(&cp, 1, UNORM_NFKD, &error) != UNORM_YES) */
+    /* { */
+    /*   ERRMSG; */
+    /*   log_err("ERROR in NFKD quick check at U+%04x\n", cp); */
+    /*   return; */
+    /* } */
+    /* if (unorm_quickCheck(&cp, 1, UNORM_NFKC, &error) !=  */
+    /*                                                          UNORM_YES) */
+    /* { */
+    /*   ERRMSG; */
+    /*   log_err("ERROR in NFKC quick check at U+%04x\n", cp); */
+    /*   return; */
+    /* } */
+    cp ++;
+  }
+
+  for (; count < SIZE; count ++)
+  {
+    /* if (unorm_quickCheck(&(CPNFD[count]), 1, UNORM_NFD, &error) !=  */
+    /*                                                          UNORM_YES) */
+    /* { */
+    /*   ERRMSG; */
+    /*   log_err("ERROR in NFD quick check at U+%04x\n", CPNFD[count]); */
+    /*   return; */
+    /* } */
+    if (unorm_quickCheck(&(CPNFC[count]), 1, UNORM_NFC, &error) 
+                                                          != UNORM_YES)
+    {
+      ERRMSG;
+      log_err("ERROR in NFC quick check at U+%04x\n", CPNFC[count]);
+      return;
+    }
+    /* if (unorm_quickCheck(&(CPNFKD[count]), 1, UNORM_NFKD, &error) !=  */
+    /*                                                          UNORM_YES) */
+    /* { */
+    /*   ERRMSG; */
+    /*   log_err("ERROR in NFKD quick check at U+%04x\n", CPNFKD[count]); */
+    /*   return; */
+    /* } */
+    /* if (unorm_quickCheck(&(CPNFKC[count]), 1, UNORM_NFKC, &error) !=  */
+    /*                                                          UNORM_YES) */
+    /* { */
+    /*   ERRMSG; */
+    /*   log_err("ERROR in NFKC quick check at U+%04x\n", CPNFKC[count]); */
+    /*   return; */
+    /* } */
+  }
+}
+
+static void TestQuickCheckResultMAYBE() 
+{
+  const UChar CPNFC[] = {0x0306, 0x0654, 0x0BBE, 0x102E, 0x1161, 
+                         0x116A, 0x1173, 0x1175, 0x3099, 0x309A};
+  const UChar CPNFKC[] = {0x0300, 0x0654, 0x0655, 0x09D7, 0x0B3E, 
+                          0x0DCF, 0xDDF, 0x102E, 0x11A8, 0x3099};
+
+
+  const int SIZE = 10;
+
+  int count = 0;
+  UErrorCode error = U_ZERO_ERROR;
+
+  /* NFD and NFKD does not have any MAYBE codepoints */
+  for (; count < SIZE; count ++)
+  {
+    UNormalizationCheckResult res;
+    if ((res=unorm_quickCheck(&(CPNFC[count]), 1, UNORM_NFC, &error)) != 
+                                                           UNORM_MAYBE)
+    {
+      ERRMSG;
+      log_data_err("ERROR in NFC quick check at U+%04x - %s wanted MAYBE\n", CPNFC[count], res2str(res));
+           /* return; */
+    }
+    /* if (unorm_quickCheck(&(CPNFKC[count]), 1, UNORM_NFKC, &error) !=  */
+    /*                                                        UNORM_MAYBE) */
+    /* { */
+    /*   ERRMSG; */
+    /*   log_err("ERROR in NFKC quick check at U+%04x\n", CPNFKC[count]); */
+    /*   return; */
+    /* } */
+  }
+}
+
+UChar* CharsToUChars(const char* str) {
+    /* Might be faster to just use uprv_strlen() as the preflight len - liu */
+    int32_t len = u_unescape(str, 0, 0); /* preflight */
+    /* Do NOT use malloc() - we are supposed to be acting like user code! */
+    UChar *buf = (UChar*) malloc(sizeof(UChar) * (len + 1));
+    u_unescape(str, buf, len + 1);
+    return buf;
+}
+
+const static char* canonTests[][3] = {
+    /* Input*/                    /*Decomposed*/                /*Composed*/
+    { "cat",                    "cat",                        "cat"                    },
+    { "\\u00e0ardvark",            "a\\u0300ardvark",            "\\u00e0ardvark",        },
+
+    { "\\u1e0a",                "D\\u0307",                    "\\u1e0a"                }, /* D-dot_above*/
+    { "D\\u0307",                "D\\u0307",                    "\\u1e0a"                }, /* D dot_above*/
+    
+    { "\\u1e0c\\u0307",            "D\\u0323\\u0307",            "\\u1e0c\\u0307"        }, /* D-dot_below dot_above*/
+    { "\\u1e0a\\u0323",            "D\\u0323\\u0307",            "\\u1e0c\\u0307"        }, /* D-dot_above dot_below */
+    { "D\\u0307\\u0323",        "D\\u0323\\u0307",            "\\u1e0c\\u0307"        }, /* D dot_below dot_above */
+    
+    { "\\u1e10\\u0307\\u0323",    "D\\u0327\\u0323\\u0307",    "\\u1e10\\u0323\\u0307"    }, /*D dot_below cedilla dot_above*/
+    { "D\\u0307\\u0328\\u0323",    "D\\u0328\\u0323\\u0307",    "\\u1e0c\\u0328\\u0307"    }, /* D dot_above ogonek dot_below*/
+
+    { "\\u1E14",                "E\\u0304\\u0300",            "\\u1E14"                }, /* E-macron-grave*/
+    { "\\u0112\\u0300",            "E\\u0304\\u0300",            "\\u1E14"                }, /* E-macron + grave*/
+    { "\\u00c8\\u0304",            "E\\u0300\\u0304",            "\\u00c8\\u0304"        }, /* E-grave + macron*/
+    
+    { "\\u212b",                "A\\u030a",                    "\\u00c5"                }, /* angstrom_sign*/
+    { "\\u00c5",                "A\\u030a",                    "\\u00c5"                }, /* A-ring*/
+    
+    { "\\u00C4ffin",            "A\\u0308ffin",                "\\u00C4ffin"                    },
+    { "\\u00C4\\uFB03n",        "A\\u0308\\uFB03n",            "\\u00C4\\uFB03n"                },
+
+    { "Henry IV",                "Henry IV",                    "Henry IV"                },
+    { "Henry \\u2163",            "Henry \\u2163",            "Henry \\u2163"            },
+
+    { "\\u30AC",                "\\u30AB\\u3099",            "\\u30AC"                }, /* ga (Katakana)*/
+    { "\\u30AB\\u3099",            "\\u30AB\\u3099",            "\\u30AC"                }, /*ka + ten*/
+    { "\\uFF76\\uFF9E",            "\\uFF76\\uFF9E",            "\\uFF76\\uFF9E"        }, /* hw_ka + hw_ten*/
+    { "\\u30AB\\uFF9E",            "\\u30AB\\uFF9E",            "\\u30AB\\uFF9E"        }, /* ka + hw_ten*/
+    { "\\uFF76\\u3099",            "\\uFF76\\u3099",            "\\uFF76\\u3099"        },  /* hw_ka + ten*/
+    { "A\\u0300\\u0316",           "A\\u0316\\u0300",           "\\u00C0\\u0316"        }  /* hw_ka + ten*/
+};
+
+const static char* compatTests[][3] = {
+    /* Input*/                        /*Decomposed    */                /*Composed*/
+    { "cat",                        "cat",                            "cat"                },
+
+    { "\\uFB4f",                    "\\u05D0\\u05DC",                "\\u05D0\\u05DC"    }, /* Alef-Lamed vs. Alef, Lamed*/
+
+    { "\\u00C4ffin",                "A\\u0308ffin",                    "\\u00C4ffin"             },
+    { "\\u00C4\\uFB03n",            "A\\u0308ffin",                    "\\u00C4ffin"                }, /* ffi ligature -> f + f + i*/
+
+    { "Henry IV",                    "Henry IV",                        "Henry IV"            },
+    { "Henry \\u2163",                "Henry IV",                        "Henry IV"            },
+
+    { "\\u30AC",                    "\\u30AB\\u3099",                "\\u30AC"            }, /* ga (Katakana)*/
+    { "\\u30AB\\u3099",                "\\u30AB\\u3099",                "\\u30AC"            }, /*ka + ten*/
+    
+    { "\\uFF76\\u3099",                "\\u30AB\\u3099",                "\\u30AC"            }, /* hw_ka + ten*/
+
+    /*These two are broken in Unicode 2.1.2 but fixed in 2.1.5 and later*/
+    { "\\uFF76\\uFF9E",                "\\u30AB\\u3099",                "\\u30AC"            }, /* hw_ka + hw_ten*/
+    { "\\u30AB\\uFF9E",                "\\u30AB\\u3099",                "\\u30AC"            } /* ka + hw_ten*/
+    
+};
+
+char *austrdup(const UChar* unichars)
+{
+    int   length;
+    char *newString;
+
+    length    = u_strlen ( unichars );
+    /*newString = (char*)malloc  ( sizeof( char ) * 4 * ( length + 1 ) );*/ /* this leaks for now */
+    newString = (char*)malloc  ( sizeof( char ) * 4 * ( length + 1 ) ); /* this shouldn't */
+
+    if ( newString == NULL )
+        return NULL;
+
+    u_austrcpy ( newString, unichars );
+
+    return newString;
+}
+
+char *aescstrdup(const UChar* unichars,int32_t length){
+    char *newString,*targetLimit,*target;
+    UConverterFromUCallback cb;
+    const void *p;
+    UErrorCode errorCode = U_ZERO_ERROR;
+#if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+#   ifdef OS390
+        static const char convName[] = "ibm-1047";
+#   else
+        static const char convName[] = "ibm-37";
+#   endif
+#else
+    static const char convName[] = "US-ASCII";
+#endif
+    UConverter* conv = ucnv_open(convName, &errorCode);
+    if(length==-1){
+        length = u_strlen( unichars);
+    }
+    newString = (char*)malloc ( sizeof(char) * 8 * (length +1));
+    target = newString;
+    targetLimit = newString+sizeof(char) * 8 * (length +1);
+    ucnv_setFromUCallBack(conv, UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_C, &cb, &p, &errorCode);
+    ucnv_fromUnicode(conv,&target,targetLimit, &unichars, (UChar*)(unichars+length),NULL,TRUE,&errorCode);
+    ucnv_close(conv);
+    *target = '\0';
+    return newString;
+}
+
+static void assertEqual(const UChar* result, const char* expected, int32_t index)
+{
+    UChar *expectedUni = CharsToUChars(expected);
+    if(u_strcmp(result, expectedUni)!=0){
+        log_err("ERROR in index = %d. EXPECTED: %s , GOT: %s\n", index, expected,
+            austrdup(result) );
+    }
+    free(expectedUni);
+}
+
+void TestCanonDecompCompose() 
+{
+    UErrorCode status = U_ZERO_ERROR;
+    int32_t x, neededLen, resLen;
+    UChar *source=NULL, *result=NULL; 
+    status = U_ZERO_ERROR;
+    resLen=0;
+    log_verbose("Testing unorm_normalize with Decomp can compose compat\n");
+    for(x=0; x < LENGTHOF(canonTests); x++)
+    {
+        source=CharsToUChars(canonTests[x][0]);
+        neededLen= unorm_normalize(source, u_strlen(source), UNORM_NFC, 0, NULL, 0, &status); 
+        if(status==U_BUFFER_OVERFLOW_ERROR)
+        {
+            status=U_ZERO_ERROR;
+            resLen=neededLen+1;
+            result=(UChar*)malloc(sizeof(UChar*) * resLen);
+            unorm_normalize(source, u_strlen(source), UNORM_NFC, 0, result, resLen, &status); 
+            if(U_FAILURE(status)){
+              log_data_err("ERROR in unorm_normalize at %s:  %s - (Are you missing data?)\n", austrdup(source),u_errorName(status) );
+            } else {
+              assertEqual(result, canonTests[x][2], x);
+            }
+            free(result);
+        } else {
+          log_data_err("ERROR in normalization of %s: status was %s should be U_BUFFER_OVERFLOW_ERROR, neededLen %d, len was %d\n", 
+                       austrdup(source), u_errorName(status), neededLen, u_strlen(source));
+        }
+        free(source);
+    }
+}
+
+
+static void TestQuickCheckStringResult() 
+{
+#if 1
+  int count;
+  UChar *d = NULL;
+  UChar *c = NULL;
+  UErrorCode error = U_ZERO_ERROR;
+
+  for (count = 0; count < LENGTHOF(canonTests); count ++)
+  {
+    UNormalizationCheckResult res;
+
+    d = CharsToUChars(canonTests[count][1]);
+    c = CharsToUChars(canonTests[count][2]);
+    /* if (unorm_quickCheck(d, u_strlen(d), UNORM_NFD, &error) !=  */
+    /*                                                         UNORM_YES) */
+    /* { */
+    /*   log_data_err("ERROR in NFD quick check for string at count %d - (Are you missing data?)\n", count); */
+    /*   return; */
+    /* } */
+
+    if ((res=unorm_quickCheck(c, u_strlen(c), UNORM_NFC, &error)) == 
+                                                            UNORM_NO)
+    {
+      log_err("ERROR in NFC quick check for string at count %d, got %s wanted %s\n", count, res2str(res), res2str(UNORM_NO));
+      return;
+    }
+
+    free(d);
+    free(c);
+    /* printf("OK: %s = NO \n", canonTests[count][2]); */
+  }
+
+  /* for (count = 0; count < LENGTHOF(compatTests); count ++) */
+  /* { */
+  /*   d = CharsToUChars(compatTests[count][1]); */
+  /*   c = CharsToUChars(compatTests[count][2]); */
+  /*   if (unorm_quickCheck(d, u_strlen(d), UNORM_NFKD, &error) !=  */
+  /*                                                           UNORM_YES) */
+  /*   { */
+  /*     log_err("ERROR in NFKD quick check for string at count %d\n", count); */
+  /*     return; */
+  /*   } */
+
+  /*   if (unorm_quickCheck(c, u_strlen(c), UNORM_NFKC, &error) !=  */
+  /*                                                           UNORM_YES) */
+  /*   { */
+  /*     log_err("ERROR in NFKC quick check for string at count %d\n", count); */
+  /*     return; */
+  /*   } */
+
+  /*   free(d); */
+  /*   free(c); */
+  /* }   */
+#endif
+}
+
+void TestQuickCheck() 
+{
+  TestQuickCheckResultNO();
+  TestQuickCheckResultYES();
+  TestQuickCheckResultMAYBE();
+  TestQuickCheckStringResult(); 
+}
+
 
 int main()
 {
+  char *dl = NULL;
   UErrorCode status = U_ZERO_ERROR;
 
+#if 0
+  dl = uloc_getDefault();
+
+  printf("Default Name: %s\n", dl!=NULL?dl:"<NULL>");
   printf("u_iscntrl(U+%04X)=%d\n", 0x0009, u_iscntrl(0x0009));
   printf("u_iscntrl(U+%04X)=%d\n", 0x0020, u_iscntrl(0x0020));
   printf("u_tolower(U+%04X)=U+%04X\n", 0x2C1F, u_tolower(0x2C1F));
   printf("u_tolower(U+%04X)=U+%04X\n", 0xA65C, u_tolower(0xA65C));
+
+  printf("Testing QuickCheck..");
+  fflush(stdout);
+  TestQuickCheck();
+
+  printf("Testing norm instance..");
+  fflush(stdout);
+  /* norm */
+  {
+    UErrorCode errorCode;
+    const UNormalizer2 *norm2;
+    int length;
+    UChar buffer16[300];
+    UChar source[50];
+    
+    /*
+     * Test for an example that unorm_getCanonStartSet() delivers
+     * all characters that compose from the input one,
+     * even in multiple steps.
+     * For example, the set for "I" (0049) should contain both
+     * I-diaeresis (00CF) and I-diaeresis-acute (1E2E).
+     * In general, the set for the middle such character should be a subset
+     * of the set for the first.
+     */
+    errorCode=U_ZERO_ERROR;
+    norm2=unorm2_getInstance(NULL, "nfc", UNORM2_COMPOSE, &errorCode);
+    if(U_FAILURE(errorCode)) {
+        log_data_err("unorm2_getInstance(NFC) failed - %s\n", u_errorName(errorCode));
+        return -1;
+    }
+
+    length=unorm2_normalize(norm2, source, 1, buffer16, LENGTHOF(buffer16), &errorCode);
+
+    unorm2_close(norm2);
+  }
+
+#endif
+
+  TestCanonDecompCompose();
+
+#if 0
+  {
+    UNormalizationCheckResult res;
+    UChar cpnfc = 0x0306;
+    UErrorCode error = U_ZERO_ERROR;
+    
+    res = unorm_quickCheck(&cpnfc, 1, UNORM_NFC, &error);
+    printf("CH: U+%04X, res=%s, err=%s\n", cpnfc, res2str(res), u_errorName(error));
+  }
+#endif
+
   printf("Pure C test OK: %s\n", u_errorName(status));
+  fflush(stdout);
   return status;
 }
