/*
*******************************************************************************
*
*   Copyright (C) 2001-2010, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*   file name:  ucaelems.cpp
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created 02/22/2001
*   created by: Vladimir Weinstein
*
*   This program reads the Franctional UCA table and generates
*   internal format for UCA table as well as inverse UCA table.
*   It then writes binary files containing the data: ucadata.dat 
*   & invuca.dat
* 
*   date        name       comments
*   03/02/2001  synwee     added setMaxExpansion
*   03/07/2001  synwee     merged UCA's maxexpansion and tailoring's
*/

#include "unicode/utypes.h"

#if !UCONFIG_NO_COLLATION

#include "unicode/uchar.h"
#include "unicode/unistr.h"
#include "unicode/ucoleitr.h"
#include "unicode/normlzr.h"
#include "normalizer2impl.h"
#include "ucol_elm.h"
#include "ucol_tok.h"
#include "ucol_cnt.h"
#include "unicode/caniter.h"
#include "cmemory.h"

U_NAMESPACE_USE

static uint32_t uprv_uca_processContraction(CntTable *contractions, UCAElements *element, uint32_t existingCE, UErrorCode *status);

U_CDECL_BEGIN
static int32_t U_CALLCONV
prefixLookupHash(const UHashTok e) {
    UCAElements *element = (UCAElements *)e.pointer;
    UChar buf[256];
    UHashTok key;
    key.pointer = buf;
    uprv_memcpy(buf, element->cPoints, element->cSize*sizeof(UChar));
    buf[element->cSize] = 0;
    //key.pointer = element->cPoints;
    //element->cPoints[element->cSize] = 0;
    return uhash_hashUChars(key);
}

static int8_t U_CALLCONV
prefixLookupComp(const UHashTok e1, const UHashTok e2) {
    UCAElements *element1 = (UCAElements *)e1.pointer;
    UCAElements *element2 = (UCAElements *)e2.pointer;

    UChar buf1[256];
    UHashTok key1;
    key1.pointer = buf1;
    uprv_memcpy(buf1, element1->cPoints, element1->cSize*sizeof(UChar));
    buf1[element1->cSize] = 0;

    UChar buf2[256];
    UHashTok key2;
    key2.pointer = buf2;
    uprv_memcpy(buf2, element2->cPoints, element2->cSize*sizeof(UChar));
    buf2[element2->cSize] = 0;

    return uhash_compareUChars(key1, key2);
}
U_CDECL_END

static int32_t uprv_uca_addExpansion(ExpansionTable *expansions, uint32_t value, UErrorCode *status) {
    if(U_FAILURE(*status)) {
        return 0;
    }
    if(expansions->CEs == NULL) {
        expansions->CEs = (uint32_t *)uprv_malloc(INIT_EXP_TABLE_SIZE*sizeof(uint32_t));
        /* test for NULL */
        if (expansions->CEs == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }
        expansions->size = INIT_EXP_TABLE_SIZE;
        expansions->position = 0;
    }

    if(expansions->position == expansions->size) {
        uint32_t *newData = (uint32_t *)uprv_realloc(expansions->CEs, 2*expansions->size*sizeof(uint32_t));
        if(newData == NULL) {
#ifdef UCOL_DEBUG
            fprintf(stderr, "out of memory for expansions\n");
#endif
            *status = U_MEMORY_ALLOCATION_ERROR;
            return -1;
        }
        expansions->CEs = newData;
        expansions->size *= 2;
    }

    expansions->CEs[expansions->position] = value;
    return(expansions->position++);
}

U_CAPI tempUCATable*  U_EXPORT2
uprv_uca_initTempTable(UCATableHeader *image, UColOptionSet *opts, const UCollator *UCA, UColCETags initTag, UColCETags supplementaryInitTag, UErrorCode *status) {
    MaxJamoExpansionTable *maxjet;
    MaxExpansionTable *maxet;
    tempUCATable *t = (tempUCATable *)uprv_malloc(sizeof(tempUCATable));
    /* test for NULL */
    if (t == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    uprv_memset(t, 0, sizeof(tempUCATable));

    maxet  = (MaxExpansionTable *)uprv_malloc(sizeof(MaxExpansionTable));
    if (maxet == NULL) {
        goto allocation_failure;
    }
    uprv_memset(maxet, 0, sizeof(MaxExpansionTable));
    t->maxExpansions       = maxet;

    maxjet = (MaxJamoExpansionTable *)uprv_malloc(sizeof(MaxJamoExpansionTable));
    if (maxjet == NULL) {
        goto allocation_failure;
    }
    uprv_memset(maxjet, 0, sizeof(MaxJamoExpansionTable));
    t->maxJamoExpansions = maxjet;

    t->image = image;
    t->options = opts;

    t->UCA = UCA;
    t->expansions = (ExpansionTable *)uprv_malloc(sizeof(ExpansionTable));
    /* test for NULL */
    if (t->expansions == NULL) {
        goto allocation_failure;
    }
    uprv_memset(t->expansions, 0, sizeof(ExpansionTable));

    t->mapping = utrie_open(NULL, NULL, UCOL_ELM_TRIE_CAPACITY,
        UCOL_SPECIAL_FLAG | (initTag<<24),
        UCOL_SPECIAL_FLAG | (supplementaryInitTag << 24),
        TRUE); // Do your own mallocs for the structure, array and have linear Latin 1
    if (U_FAILURE(*status)) {
        goto allocation_failure;
    }
    t->prefixLookup = uhash_open(prefixLookupHash, prefixLookupComp, NULL, status);
    if (U_FAILURE(*status)) {
        goto allocation_failure;
    }
    uhash_setValueDeleter(t->prefixLookup, uhash_freeBlock);

    t->contractions = uprv_cnttab_open(t->mapping, status);
    if (U_FAILURE(*status)) {
        goto cleanup;
    }

    /* copy UCA's maxexpansion and merge as we go along */
    if (UCA != NULL) {
        /* adding an extra initial value for easier manipulation */
        maxet->size            = (int32_t)(UCA->lastEndExpansionCE - UCA->endExpansionCE) + 2;
        maxet->position        = maxet->size - 1;
        maxet->endExpansionCE  = 
            (uint32_t *)uprv_malloc(sizeof(uint32_t) * maxet->size);
        /* test for NULL */
        if (maxet->endExpansionCE == NULL) {
            goto allocation_failure;
        }
        maxet->expansionCESize =
            (uint8_t *)uprv_malloc(sizeof(uint8_t) * maxet->size);
        /* test for NULL */
        if (maxet->expansionCESize == NULL) {
            goto allocation_failure;
        }
        /* initialized value */
        *(maxet->endExpansionCE)  = 0;
        *(maxet->expansionCESize) = 0;
        uprv_memcpy(maxet->endExpansionCE + 1, UCA->endExpansionCE, 
            sizeof(uint32_t) * (maxet->size - 1));
        uprv_memcpy(maxet->expansionCESize + 1, UCA->expansionCESize, 
            sizeof(uint8_t) * (maxet->size - 1));
    }
    else {
        maxet->size     = 0;
    }
    maxjet->endExpansionCE = NULL;
    maxjet->isV = NULL;
    maxjet->size = 0;
    maxjet->position = 0;
    maxjet->maxLSize = 1;
    maxjet->maxVSize = 1;
    maxjet->maxTSize = 1;

    t->unsafeCP = (uint8_t *)uprv_malloc(UCOL_UNSAFECP_TABLE_SIZE);
    /* test for NULL */
    if (t->unsafeCP == NULL) {
        goto allocation_failure;
    }
    t->contrEndCP = (uint8_t *)uprv_malloc(UCOL_UNSAFECP_TABLE_SIZE);
    /* test for NULL */
    if (t->contrEndCP == NULL) {
        goto allocation_failure;
    }
    uprv_memset(t->unsafeCP, 0, UCOL_UNSAFECP_TABLE_SIZE);
    uprv_memset(t->contrEndCP, 0, UCOL_UNSAFECP_TABLE_SIZE);
    t->cmLookup = NULL;
    return t;

allocation_failure:
    *status = U_MEMORY_ALLOCATION_ERROR;
cleanup:
    uprv_uca_closeTempTable(t);
    return NULL;
}

static tempUCATable* U_EXPORT2
uprv_uca_cloneTempTable(tempUCATable *t, UErrorCode *status) {
    if(U_FAILURE(*status)) {
        return NULL;
    }

    tempUCATable *r = (tempUCATable *)uprv_malloc(sizeof(tempUCATable));
    /* test for NULL */
    if (r == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    uprv_memset(r, 0, sizeof(tempUCATable));

    /* mapping */
    if(t->mapping != NULL) {
        /*r->mapping = ucmpe32_clone(t->mapping, status);*/
        r->mapping = utrie_clone(NULL, t->mapping, NULL, 0);
    }

    // a hashing clone function would be very nice. We have none currently...
    // However, we should be good, as closing should not produce any prefixed elements.
    r->prefixLookup = NULL; // prefixes are not used in closing

    /* expansions */
    if(t->expansions != NULL) {
        r->expansions = (ExpansionTable *)uprv_malloc(sizeof(ExpansionTable));
        /* test for NULL */
        if (r->expansions == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            goto cleanup;
        }
        r->expansions->position = t->expansions->position;
        r->expansions->size = t->expansions->size;
        if(t->expansions->CEs != NULL) {
            r->expansions->CEs = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->expansions->size);
            /* test for NULL */
            if (r->expansions->CEs == NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
                goto cleanup;
            }
            uprv_memcpy(r->expansions->CEs, t->expansions->CEs, sizeof(uint32_t)*t->expansions->position);
        } else {
            r->expansions->CEs = NULL;
        }
    }

    if(t->contractions != NULL) {
        r->contractions = uprv_cnttab_clone(t->contractions, status);
        // Check for cloning failure.
        if (r->contractions == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            goto cleanup;
        }
        r->contractions->mapping = r->mapping;
    }

    if(t->maxExpansions != NULL) {
        r->maxExpansions = (MaxExpansionTable *)uprv_malloc(sizeof(MaxExpansionTable));
        /* test for NULL */
        if (r->maxExpansions == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            goto cleanup;
        }
        r->maxExpansions->size = t->maxExpansions->size;
        r->maxExpansions->position = t->maxExpansions->position;
        if(t->maxExpansions->endExpansionCE != NULL) {
            r->maxExpansions->endExpansionCE = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->maxExpansions->size);
            /* test for NULL */
            if (r->maxExpansions->endExpansionCE == NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
                goto cleanup;
            }
            uprv_memset(r->maxExpansions->endExpansionCE, 0xDB, sizeof(uint32_t)*t->maxExpansions->size);
            uprv_memcpy(r->maxExpansions->endExpansionCE, t->maxExpansions->endExpansionCE, t->maxExpansions->position*sizeof(uint32_t));
        } else {
            r->maxExpansions->endExpansionCE = NULL;
        }
        if(t->maxExpansions->expansionCESize != NULL) {
            r->maxExpansions->expansionCESize = (uint8_t *)uprv_malloc(sizeof(uint8_t)*t->maxExpansions->size);
            /* test for NULL */
            if (r->maxExpansions->expansionCESize == NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
                goto cleanup;
            }
            uprv_memset(r->maxExpansions->expansionCESize, 0xDB, sizeof(uint8_t)*t->maxExpansions->size);
            uprv_memcpy(r->maxExpansions->expansionCESize, t->maxExpansions->expansionCESize, t->maxExpansions->position*sizeof(uint8_t));
        } else {
            r->maxExpansions->expansionCESize = NULL;
        }
    }

    if(t->maxJamoExpansions != NULL) {
        r->maxJamoExpansions = (MaxJamoExpansionTable *)uprv_malloc(sizeof(MaxJamoExpansionTable));
        /* test for NULL */
        if (r->maxJamoExpansions == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            goto cleanup;
        }
        r->maxJamoExpansions->size = t->maxJamoExpansions->size;
        r->maxJamoExpansions->position = t->maxJamoExpansions->position;
        r->maxJamoExpansions->maxLSize = t->maxJamoExpansions->maxLSize;
        r->maxJamoExpansions->maxVSize = t->maxJamoExpansions->maxVSize;
        r->maxJamoExpansions->maxTSize = t->maxJamoExpansions->maxTSize;
        if(t->maxJamoExpansions->size != 0) {
            r->maxJamoExpansions->endExpansionCE = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->maxJamoExpansions->size);
            /* test for NULL */
            if (r->maxJamoExpansions->endExpansionCE == NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
                goto cleanup;
            }
            uprv_memcpy(r->maxJamoExpansions->endExpansionCE, t->maxJamoExpansions->endExpansionCE, t->maxJamoExpansions->position*sizeof(uint32_t));
            r->maxJamoExpansions->isV = (UBool *)uprv_malloc(sizeof(UBool)*t->maxJamoExpansions->size);
            /* test for NULL */
            if (r->maxJamoExpansions->isV == NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
                goto cleanup;
            }
            uprv_memcpy(r->maxJamoExpansions->isV, t->maxJamoExpansions->isV, t->maxJamoExpansions->position*sizeof(UBool));
        } else {
            r->maxJamoExpansions->endExpansionCE = NULL;
            r->maxJamoExpansions->isV = NULL;
        }
    }

    if(t->unsafeCP != NULL) {
        r->unsafeCP = (uint8_t *)uprv_malloc(UCOL_UNSAFECP_TABLE_SIZE);
        /* test for NULL */
        if (r->unsafeCP == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            goto cleanup;
        }
        uprv_memcpy(r->unsafeCP, t->unsafeCP, UCOL_UNSAFECP_TABLE_SIZE);
    }

    if(t->contrEndCP != NULL) {
        r->contrEndCP = (uint8_t *)uprv_malloc(UCOL_UNSAFECP_TABLE_SIZE);
        /* test for NULL */
        if (r->contrEndCP == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            goto cleanup;
        }
        uprv_memcpy(r->contrEndCP, t->contrEndCP, UCOL_UNSAFECP_TABLE_SIZE);
    }

    r->UCA = t->UCA;
    r->image = t->image;
    r->options = t->options;

    return r;
cleanup:
    uprv_uca_closeTempTable(t);
    return NULL;
}


U_CAPI void  U_EXPORT2
uprv_uca_closeTempTable(tempUCATable *t) {
    if(t != NULL) {
        if (t->expansions != NULL) {
            uprv_free(t->expansions->CEs);
            uprv_free(t->expansions);
        }
        if(t->contractions != NULL) {
            uprv_cnttab_close(t->contractions);
        }
        if (t->mapping != NULL) {
            utrie_close(t->mapping);
        }

        if(t->prefixLookup != NULL) {
            uhash_close(t->prefixLookup);
        }

        if (t->maxExpansions != NULL) {
            uprv_free(t->maxExpansions->endExpansionCE);
            uprv_free(t->maxExpansions->expansionCESize);
            uprv_free(t->maxExpansions);
        }

        if (t->maxJamoExpansions->size > 0) {
            uprv_free(t->maxJamoExpansions->endExpansionCE);
            uprv_free(t->maxJamoExpansions->isV);
        }
        uprv_free(t->maxJamoExpansions);

        uprv_free(t->unsafeCP);
        uprv_free(t->contrEndCP);
        
        if (t->cmLookup != NULL) {
            uprv_free(t->cmLookup->cPoints);
            uprv_free(t->cmLookup);
        }

        uprv_free(t);
    }
}

/**
* Looks for the maximum length of all expansion sequences ending with the same
* collation element. The size required for maxexpansion and maxsize is 
* returned if the arrays are too small.
* @param endexpansion the last expansion collation element to be added
* @param expansionsize size of the expansion
* @param maxexpansion data structure to store the maximum expansion data.
* @param status error status
* @returns size of the maxexpansion and maxsize used.
*/
static int uprv_uca_setMaxExpansion(uint32_t           endexpansion,
                                    uint8_t            expansionsize,
                                    MaxExpansionTable *maxexpansion,
                                    UErrorCode        *status)
{
    if (maxexpansion->size == 0) {
        /* we'll always make the first element 0, for easier manipulation */
        maxexpansion->endExpansionCE = 
            (uint32_t *)uprv_malloc(INIT_EXP_TABLE_SIZE * sizeof(int32_t));
        /* test for NULL */
        if (maxexpansion->endExpansionCE == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }
        *(maxexpansion->endExpansionCE) = 0;
        maxexpansion->expansionCESize =
            (uint8_t *)uprv_malloc(INIT_EXP_TABLE_SIZE * sizeof(uint8_t));
        /* test for NULL */;
        if (maxexpansion->expansionCESize == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }
        *(maxexpansion->expansionCESize) = 0;
        maxexpansion->size     = INIT_EXP_TABLE_SIZE;
        maxexpansion->position = 0;
    }

    if (maxexpansion->position + 1 == maxexpansion->size) {
        uint32_t *neweece = (uint32_t *)uprv_realloc(maxexpansion->endExpansionCE, 
            2 * maxexpansion->size * sizeof(uint32_t));
        if (neweece == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }
        maxexpansion->endExpansionCE  = neweece;

        uint8_t  *neweces = (uint8_t *)uprv_realloc(maxexpansion->expansionCESize, 
            2 * maxexpansion->size * sizeof(uint8_t));
        if (neweces == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }
        maxexpansion->expansionCESize = neweces;
        maxexpansion->size *= 2;
    }

    uint32_t *pendexpansionce = maxexpansion->endExpansionCE;
    uint8_t  *pexpansionsize  = maxexpansion->expansionCESize;
    int      pos              = maxexpansion->position;

    uint32_t *start = pendexpansionce;
    uint32_t *limit = pendexpansionce + pos;

    /* using binary search to determine if last expansion element is
    already in the array */
    uint32_t *mid;
    int       result = -1;
    while (start < limit - 1) {
        mid = start + ((limit - start) >> 1);
        if (endexpansion <= *mid) {
            limit = mid;
        }
        else {
            start = mid;
        }
    }

    if (*start == endexpansion) {
        result = (int)(start - pendexpansionce);
    }
    else if (*limit == endexpansion) {
        result = (int)(limit - pendexpansionce);
    }

    if (result > -1) {
        /* found the ce in expansion, we'll just modify the size if it is
        smaller */
        uint8_t *currentsize = pexpansionsize + result;
        if (*currentsize < expansionsize) {
            *currentsize = expansionsize;
        }
    }
    else {
        /* we'll need to squeeze the value into the array.
        initial implementation. */
        /* shifting the subarray down by 1 */
        int      shiftsize     = (int)((pendexpansionce + pos) - start);
        uint32_t *shiftpos     = start + 1;
        uint8_t  *sizeshiftpos = pexpansionsize + (shiftpos - pendexpansionce);

        /* okay need to rearrange the array into sorted order */
        if (shiftsize == 0 /*|| *(pendexpansionce + pos) < endexpansion*/) { /* the commented part is actually both redundant and dangerous */
            *(pendexpansionce + pos + 1) = endexpansion;
            *(pexpansionsize + pos + 1)  = expansionsize;
        }
        else {
            uprv_memmove(shiftpos + 1, shiftpos, shiftsize * sizeof(int32_t));
            uprv_memmove(sizeshiftpos + 1, sizeshiftpos, 
                shiftsize * sizeof(uint8_t));
            *shiftpos     = endexpansion;
            *sizeshiftpos = expansionsize;
        }
        maxexpansion->position ++;

#ifdef UCOL_DEBUG
        int   temp;
        UBool found = FALSE;
        for (temp = 0; temp < maxexpansion->position; temp ++) {
            if (pendexpansionce[temp] >= pendexpansionce[temp + 1]) {
                fprintf(stderr, "expansions %d\n", temp);
            }
            if (pendexpansionce[temp] == endexpansion) {
                found =TRUE;
                if (pexpansionsize[temp] < expansionsize) {
                    fprintf(stderr, "expansions size %d\n", temp);
                }
            }
        }
        if (pendexpansionce[temp] == endexpansion) {
            found =TRUE;
            if (pexpansionsize[temp] < expansionsize) {
                fprintf(stderr, "expansions size %d\n", temp);
            }
        }
        if (!found)
            fprintf(stderr, "expansion not found %d\n", temp);
#endif
    }

    return maxexpansion->position;
}

/**
* Sets the maximum length of all jamo expansion sequences ending with the same
* collation element. The size required for maxexpansion and maxsize is 
* returned if the arrays are too small.
* @param ch the jamo codepoint
* @param endexpansion the last expansion collation element to be added
* @param expansionsize size of the expansion
* @param maxexpansion data structure to store the maximum expansion data.
* @param status error status
* @returns size of the maxexpansion and maxsize used.
*/
static int uprv_uca_setMaxJamoExpansion(UChar                  ch,
                                        uint32_t               endexpansion,
                                        uint8_t                expansionsize,
                                        MaxJamoExpansionTable *maxexpansion,
                                        UErrorCode            *status)
{
    UBool isV = TRUE;
    if (((uint32_t)ch - 0x1100) <= (0x1112 - 0x1100)) {
        /* determines L for Jamo, doesn't need to store this since it is never
        at the end of a expansion */
        if (maxexpansion->maxLSize < expansionsize) {
            maxexpansion->maxLSize = expansionsize;
        }
        return maxexpansion->position;
    }

    if (((uint32_t)ch - 0x1161) <= (0x1175 - 0x1161)) {
        /* determines V for Jamo */
        if (maxexpansion->maxVSize < expansionsize) {
            maxexpansion->maxVSize = expansionsize;
        }
    }

    if (((uint32_t)ch - 0x11A8) <= (0x11C2 - 0x11A8)) {
        isV = FALSE;
        /* determines T for Jamo */
        if (maxexpansion->maxTSize < expansionsize) {
            maxexpansion->maxTSize = expansionsize;
        }
    }

    if (maxexpansion->size == 0) {
        /* we'll always make the first element 0, for easier manipulation */
        maxexpansion->endExpansionCE = 
            (uint32_t *)uprv_malloc(INIT_EXP_TABLE_SIZE * sizeof(uint32_t));
        /* test for NULL */;
        if (maxexpansion->endExpansionCE == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }
        *(maxexpansion->endExpansionCE) = 0;
        maxexpansion->isV = 
            (UBool *)uprv_malloc(INIT_EXP_TABLE_SIZE * sizeof(UBool));
        /* test for NULL */;
        if (maxexpansion->isV == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            uprv_free(maxexpansion->endExpansionCE);
            maxexpansion->endExpansionCE = NULL;
            return 0;
        }
        *(maxexpansion->isV) = 0;
        maxexpansion->size     = INIT_EXP_TABLE_SIZE;
        maxexpansion->position = 0;
    }

    if (maxexpansion->position + 1 == maxexpansion->size) {
        maxexpansion->size *= 2;
        maxexpansion->endExpansionCE = (uint32_t *)uprv_realloc(maxexpansion->endExpansionCE, 
            maxexpansion->size * sizeof(uint32_t));
        if (maxexpansion->endExpansionCE == NULL) {
#ifdef UCOL_DEBUG
            fprintf(stderr, "out of memory for maxExpansions\n");
#endif
            *status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }
        maxexpansion->isV  = (UBool *)uprv_realloc(maxexpansion->isV, 
            maxexpansion->size * sizeof(UBool));
        if (maxexpansion->isV == NULL) {
#ifdef UCOL_DEBUG
            fprintf(stderr, "out of memory for maxExpansions\n");
#endif
            *status = U_MEMORY_ALLOCATION_ERROR;
            uprv_free(maxexpansion->endExpansionCE);
            maxexpansion->endExpansionCE = NULL;
            return 0;
        }
    }

    uint32_t *pendexpansionce = maxexpansion->endExpansionCE;
    int       pos             = maxexpansion->position;

    while (pos > 0) {
        pos --;
        if (*(pendexpansionce + pos) == endexpansion) {
            return maxexpansion->position;
        }
    }

    *(pendexpansionce + maxexpansion->position) = endexpansion;
    *(maxexpansion->isV + maxexpansion->position) = isV;
    maxexpansion->position ++;

    return maxexpansion->position;
}


static void ContrEndCPSet(uint8_t *table, UChar c) {
    uint32_t    hash;
    uint8_t     *htByte;

    hash = c;
    if (hash >= UCOL_UNSAFECP_TABLE_SIZE*8) {
        hash = (hash & UCOL_UNSAFECP_TABLE_MASK) + 256;
    }
    htByte = &table[hash>>3];
    *htByte |= (1 << (hash & 7));
}


static void unsafeCPSet(uint8_t *table, UChar c) {
    uint32_t    hash;
    uint8_t     *htByte;

    hash = c;
    if (hash >= UCOL_UNSAFECP_TABLE_SIZE*8) {
        if (hash >= 0xd800 && hash <= 0xf8ff) {
            /*  Part of a surrogate, or in private use area.            */
            /*   These don't go in the table                            */
            return;
        }
        hash = (hash & UCOL_UNSAFECP_TABLE_MASK) + 256;
    }
    htByte = &table[hash>>3];
    *htByte |= (1 << (hash & 7));
}

static void
uprv_uca_createCMTable(tempUCATable *t, int32_t noOfCM, UErrorCode *status) {
    t->cmLookup = (CombinClassTable *)uprv_malloc(sizeof(CombinClassTable));
    if (t->cmLookup==NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    t->cmLookup->cPoints=(UChar *)uprv_malloc(noOfCM*sizeof(UChar));
    if (t->cmLookup->cPoints ==NULL) {
        uprv_free(t->cmLookup);
        t->cmLookup = NULL;
        *status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }

    t->cmLookup->size=noOfCM;
    uprv_memset(t->cmLookup->index, 0, sizeof(t->cmLookup->index));

    return;
}

static void
uprv_uca_copyCMTable(tempUCATable *t, UChar *cm, uint16_t *index) {
    int32_t count=0;

    for (int32_t i=0; i<256; ++i) {
        if (index[i]>0) {
            // cPoints is ordered by combining class value.
            uprv_memcpy(t->cmLookup->cPoints+count, cm+(i<<8), index[i]*sizeof(UChar));
            count += index[i];
        }
        t->cmLookup->index[i]=count;
    }
    return;
}

/* 1. to the UnsafeCP hash table, add all chars with combining class != 0     */
/* 2. build combining marks table for all chars with combining class != 0     */
static void uprv_uca_unsafeCPAddCCNZ(tempUCATable *t, UErrorCode *status) {

    UChar              c;
    uint16_t           fcd;     // Hi byte is lead combining class.
    // lo byte is trailing combing class.
    const uint16_t    *fcdTrieIndex;
    UChar32            fcdHighStart;
    UBool buildCMTable = (t->cmLookup==NULL); // flag for building combining class table
    UChar *cm=NULL;
    uint16_t index[256];
    int32_t count=0;
    fcdTrieIndex = unorm_getFCDTrieIndex(fcdHighStart, status);
    if (U_FAILURE(*status)) {
        return;
    }

    if (buildCMTable) {
        if (cm==NULL) {
            cm = (UChar *)uprv_malloc(sizeof(UChar)*UCOL_MAX_CM_TAB);
            if (cm==NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
                return;
            }
        }
        uprv_memset(index, 0, sizeof(index));
    }
    for (c=0; c<0xffff; c++) {
        fcd = unorm_getFCD16(fcdTrieIndex, c);
        if (fcd >= 0x100 ||               // if the leading combining class(c) > 0 ||
            (UTF_IS_LEAD(c) && fcd != 0)) {//    c is a leading surrogate with some FCD data
            if (buildCMTable) {
                uint32_t cClass = fcd & 0xff;
                //uint32_t temp=(cClass<<8)+index[cClass];
                cm[(cClass<<8)+index[cClass]] = c; //
                index[cClass]++;
                count++;
            }
            unsafeCPSet(t->unsafeCP, c);
        }
    }

    // copy to cm table
    if (buildCMTable) {
        uprv_uca_createCMTable(t, count, status);
        if(U_FAILURE(*status)) {
            if (cm!=NULL) {
                uprv_free(cm);
            }
            return;
        }
        uprv_uca_copyCMTable(t, cm, index);
    }

    if(t->prefixLookup != NULL) {
        int32_t i = -1;
        const UHashElement *e = NULL;
        UCAElements *element = NULL;
        UChar NFCbuf[256];
        uint32_t NFCbufLen = 0;
        while((e = uhash_nextElement(t->prefixLookup, &i)) != NULL) {
            element = (UCAElements *)e->value.pointer;
            // codepoints here are in the NFD form. We need to add the
            // first code point of the NFC form to unsafe, because
            // strcoll needs to backup over them.
            NFCbufLen = unorm_normalize(element->cPoints, element->cSize, UNORM_NFC, 0,
                NFCbuf, 256, status);
            unsafeCPSet(t->unsafeCP, NFCbuf[0]);
        }
    }

    if (cm!=NULL) {
        uprv_free(cm);
    }
}

static uint32_t uprv_uca_addPrefix(tempUCATable *t, uint32_t CE,
                                   UCAElements *element, UErrorCode *status)
{
    // currently the longest prefix we're supporting in Japanese is two characters
    // long. Although this table could quite easily mimic complete contraction stuff
    // there is no good reason to make a general solution, as it would require some
    // error prone messing.
    CntTable *contractions = t->contractions;
    UChar32 cp;
    uint32_t cpsize = 0;
    UChar *oldCP = element->cPoints;
    uint32_t oldCPSize = element->cSize;


    contractions->currentTag = SPEC_PROC_TAG;

    // here, we will normalize & add prefix to the table.
    uint32_t j = 0;
#ifdef UCOL_DEBUG
    for(j=0; j<element->cSize; j++) {
        fprintf(stdout, "CP: %04X ", element->cPoints[j]);
    }
    fprintf(stdout, "El: %08X Pref: ", CE);
    for(j=0; j<element->prefixSize; j++) {
        fprintf(stdout, "%04X ", element->prefix[j]);
    }
    fprintf(stdout, "%08X ", element->mapCE);
#endif

    for (j = 1; j<element->prefixSize; j++) {   /* First add NFD prefix chars to unsafe CP hash table */
        // Unless it is a trail surrogate, which is handled algoritmically and
        // shouldn't take up space in the table.
        if(!(UTF_IS_TRAIL(element->prefix[j]))) {
            unsafeCPSet(t->unsafeCP, element->prefix[j]);
        }
    }

    UChar tempPrefix = 0;

    for(j = 0; j < /*nfcSize*/element->prefixSize/2; j++) { // prefixes are going to be looked up backwards
        // therefore, we will promptly reverse the prefix buffer...
        tempPrefix = *(/*nfcBuffer*/element->prefix+element->prefixSize-j-1);
        *(/*nfcBuffer*/element->prefix+element->prefixSize-j-1) = element->prefix[j];
        element->prefix[j] = tempPrefix;
    }

#ifdef UCOL_DEBUG
    fprintf(stdout, "Reversed: ");
    for(j=0; j<element->prefixSize; j++) {
        fprintf(stdout, "%04X ", element->prefix[j]);
    }
    fprintf(stdout, "%08X\n", element->mapCE);
#endif

    // the first codepoint is also unsafe, as it forms a 'contraction' with the prefix
    if(!(UTF_IS_TRAIL(element->cPoints[0]))) {
        unsafeCPSet(t->unsafeCP, element->cPoints[0]);
    }

    // Maybe we need this... To handle prefixes completely in the forward direction...
    //if(element->cSize == 1) {
    //  if(!(UTF_IS_TRAIL(element->cPoints[0]))) {
    //    ContrEndCPSet(t->contrEndCP, element->cPoints[0]);
    //  }
    //}

    element->cPoints = element->prefix;
    element->cSize = element->prefixSize;

    // Add the last char of the contraction to the contraction-end hash table.
    // unless it is a trail surrogate, which is handled algorithmically and
    // shouldn't be in the table
    if(!(UTF_IS_TRAIL(element->cPoints[element->cSize -1]))) {
        ContrEndCPSet(t->contrEndCP, element->cPoints[element->cSize -1]);
    }

    // First we need to check if contractions starts with a surrogate
    UTF_NEXT_CHAR(element->cPoints, cpsize, element->cSize, cp);

    // If there are any Jamos in the contraction, we should turn on special
    // processing for Jamos
    if(UCOL_ISJAMO(element->prefix[0])) {
        t->image->jamoSpecial = TRUE;
    }
    /* then we need to deal with it */
    /* we could aready have something in table - or we might not */

    if(!isPrefix(CE)) {
        /* if it wasn't contraction, we wouldn't end up here*/
        int32_t firstContractionOffset = 0;
        firstContractionOffset = uprv_cnttab_addContraction(contractions, UPRV_CNTTAB_NEWELEMENT, 0, CE, status);
        uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
        uprv_cnttab_addContraction(contractions, firstContractionOffset, *element->prefix, newCE, status);
        uprv_cnttab_addContraction(contractions, firstContractionOffset, 0xFFFF, CE, status);
        CE =  constructContractCE(SPEC_PROC_TAG, firstContractionOffset);
    } else { /* we are adding to existing contraction */
        /* there were already some elements in the table, so we need to add a new contraction */
        /* Two things can happen here: either the codepoint is already in the table, or it is not */
        int32_t position = uprv_cnttab_findCP(contractions, CE, *element->prefix, status);
        if(position > 0) {       /* if it is we just continue down the chain */
            uint32_t eCE = uprv_cnttab_getCE(contractions, CE, position, status);
            uint32_t newCE = uprv_uca_processContraction(contractions, element, eCE, status);
            uprv_cnttab_setContraction(contractions, CE, position, *(element->prefix), newCE, status);
        } else {                  /* if it isn't, we will have to create a new sequence */
            uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
            uprv_cnttab_insertContraction(contractions, CE, *(element->prefix), element->mapCE, status);
        }
    }

    element->cPoints = oldCP;
    element->cSize = oldCPSize;

    return CE;
}

// Note regarding surrogate handling: We are interested only in the single
// or leading surrogates in a contraction. If a surrogate is somewhere else
// in the contraction, it is going to be handled as a pair of code units,
// as it doesn't affect the performance AND handling surrogates specially
// would complicate code way too much.
static uint32_t uprv_uca_addContraction(tempUCATable *t, uint32_t CE, 
                                        UCAElements *element, UErrorCode *status)
{
    CntTable *contractions = t->contractions;
    UChar32 cp;
    uint32_t cpsize = 0;

    contractions->currentTag = CONTRACTION_TAG;

    // First we need to check if contractions starts with a surrogate
    UTF_NEXT_CHAR(element->cPoints, cpsize, element->cSize, cp);

    if(cpsize<element->cSize) { // This is a real contraction, if there are other characters after the first
        uint32_t j = 0;
        for (j=1; j<element->cSize; j++) {   /* First add contraction chars to unsafe CP hash table */
            // Unless it is a trail surrogate, which is handled algoritmically and 
            // shouldn't take up space in the table.
            if(!(UTF_IS_TRAIL(element->cPoints[j]))) {
                unsafeCPSet(t->unsafeCP, element->cPoints[j]);
            }
        }
        // Add the last char of the contraction to the contraction-end hash table.
        // unless it is a trail surrogate, which is handled algorithmically and 
        // shouldn't be in the table
        if(!(UTF_IS_TRAIL(element->cPoints[element->cSize -1]))) {
            ContrEndCPSet(t->contrEndCP, element->cPoints[element->cSize -1]);
        }

        // If there are any Jamos in the contraction, we should turn on special 
        // processing for Jamos
        if(UCOL_ISJAMO(element->cPoints[0])) {
            t->image->jamoSpecial = TRUE;
        }
        /* then we need to deal with it */
        /* we could aready have something in table - or we might not */
        element->cPoints+=cpsize;
        element->cSize-=cpsize;
        if(!isContraction(CE)) { 
            /* if it wasn't contraction, we wouldn't end up here*/
            int32_t firstContractionOffset = 0;
            firstContractionOffset = uprv_cnttab_addContraction(contractions, UPRV_CNTTAB_NEWELEMENT, 0, CE, status);
            uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
            uprv_cnttab_addContraction(contractions, firstContractionOffset, *element->cPoints, newCE, status);
            uprv_cnttab_addContraction(contractions, firstContractionOffset, 0xFFFF, CE, status);
            CE =  constructContractCE(CONTRACTION_TAG, firstContractionOffset);
        } else { /* we are adding to existing contraction */
            /* there were already some elements in the table, so we need to add a new contraction */
            /* Two things can happen here: either the codepoint is already in the table, or it is not */
            int32_t position = uprv_cnttab_findCP(contractions, CE, *element->cPoints, status);
            if(position > 0) {       /* if it is we just continue down the chain */
                uint32_t eCE = uprv_cnttab_getCE(contractions, CE, position, status);
                uint32_t newCE = uprv_uca_processContraction(contractions, element, eCE, status);
                uprv_cnttab_setContraction(contractions, CE, position, *(element->cPoints), newCE, status);
            } else {                  /* if it isn't, we will have to create a new sequence */
                uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
                uprv_cnttab_insertContraction(contractions, CE, *(element->cPoints), newCE, status);
            }
        }
        element->cPoints-=cpsize;
        element->cSize+=cpsize;
        /*ucmpe32_set(t->mapping, cp, CE);*/
        utrie_set32(t->mapping, cp, CE);
    } else if(!isContraction(CE)) { /* this is just a surrogate, and there is no contraction */
        /*ucmpe32_set(t->mapping, cp, element->mapCE);*/
        utrie_set32(t->mapping, cp, element->mapCE);
    } else { /* fill out the first stage of the contraction with the surrogate CE */
        uprv_cnttab_changeContraction(contractions, CE, 0, element->mapCE, status);
        uprv_cnttab_changeContraction(contractions, CE, 0xFFFF, element->mapCE, status);
    }
    return CE;
}


static uint32_t uprv_uca_processContraction(CntTable *contractions, UCAElements *element, uint32_t existingCE, UErrorCode *status) {
    int32_t firstContractionOffset = 0;
    //    uint32_t contractionElement = UCOL_NOT_FOUND;

    if(U_FAILURE(*status)) {
        return UCOL_NOT_FOUND;
    }

    /* end of recursion */
    if(element->cSize == 1) {
        if(isCntTableElement(existingCE) && ((UColCETags)getCETag(existingCE) == contractions->currentTag)) {
            uprv_cnttab_changeContraction(contractions, existingCE, 0, element->mapCE, status);
            uprv_cnttab_changeContraction(contractions, existingCE, 0xFFFF, element->mapCE, status);
            return existingCE;
        } else {
            return element->mapCE; /*can't do just that. existingCe might be a contraction, meaning that we need to do another step */
        }
    }

    /* this recursion currently feeds on the only element we have... We will have to copy it in order to accomodate */
    /* for both backward and forward cycles */

    /* we encountered either an empty space or a non-contraction element */
    /* this means we are constructing a new contraction sequence */
    element->cPoints++;
    element->cSize--;
    if(!isCntTableElement(existingCE)) { 
        /* if it wasn't contraction, we wouldn't end up here*/
        firstContractionOffset = uprv_cnttab_addContraction(contractions, UPRV_CNTTAB_NEWELEMENT, 0, existingCE, status);
        uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
        uprv_cnttab_addContraction(contractions, firstContractionOffset, *element->cPoints, newCE, status);
        uprv_cnttab_addContraction(contractions, firstContractionOffset, 0xFFFF, existingCE, status);
        existingCE =  constructContractCE(contractions->currentTag, firstContractionOffset);
    } else { /* we are adding to existing contraction */
        /* there were already some elements in the table, so we need to add a new contraction */
        /* Two things can happen here: either the codepoint is already in the table, or it is not */
        int32_t position = uprv_cnttab_findCP(contractions, existingCE, *element->cPoints, status);
        if(position > 0) {       /* if it is we just continue down the chain */
            uint32_t eCE = uprv_cnttab_getCE(contractions, existingCE, position, status);
            uint32_t newCE = uprv_uca_processContraction(contractions, element, eCE, status);
            uprv_cnttab_setContraction(contractions, existingCE, position, *(element->cPoints), newCE, status);
        } else {                  /* if it isn't, we will have to create a new sequence */
            uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
            uprv_cnttab_insertContraction(contractions, existingCE, *(element->cPoints), newCE, status);
        }
    }
    element->cPoints--;
    element->cSize++;
    return existingCE;
}

static uint32_t uprv_uca_finalizeAddition(tempUCATable *t, UCAElements *element, UErrorCode *status) {
    uint32_t CE = UCOL_NOT_FOUND;
    // This should add a completely ignorable element to the 
    // unsafe table, so that backward iteration will skip
    // over it when treating contractions.
    uint32_t i = 0;
    if(element->mapCE == 0) {
        for(i = 0; i < element->cSize; i++) {
            if(!UTF_IS_TRAIL(element->cPoints[i])) {
                unsafeCPSet(t->unsafeCP, element->cPoints[i]);
            }
        }
    }
    if(element->cSize > 1) { /* we're adding a contraction */
        uint32_t i = 0;
        UChar32 cp;

        UTF_NEXT_CHAR(element->cPoints, i, element->cSize, cp);
        /*CE = ucmpe32_get(t->mapping, cp);*/
        CE = utrie_get32(t->mapping, cp, NULL);

        CE = uprv_uca_addContraction(t, CE, element, status);
    } else { /* easy case, */
        /*CE = ucmpe32_get(t->mapping, element->cPoints[0]);*/
        CE = utrie_get32(t->mapping, element->cPoints[0], NULL);

        if( CE != UCOL_NOT_FOUND) {
            if(isCntTableElement(CE) /*isContraction(CE)*/) { /* adding a non contraction element (thai, expansion, single) to already existing contraction */
                if(!isPrefix(element->mapCE)) { // we cannot reenter prefix elements - as we are going to create a dead loop
                    // Only expansions and regular CEs can go here... Contractions will never happen in this place
                    uprv_cnttab_setContraction(t->contractions, CE, 0, 0, element->mapCE, status);
                    /* This loop has to change the CE at the end of contraction REDO!*/
                    uprv_cnttab_changeLastCE(t->contractions, CE, element->mapCE, status);
                }
            } else {
                /*ucmpe32_set(t->mapping, element->cPoints[0], element->mapCE);*/
                utrie_set32(t->mapping, element->cPoints[0], element->mapCE);
                if ((element->prefixSize!=0) && (getCETag(CE)!=IMPLICIT_TAG)) {
                    UCAElements *origElem = (UCAElements *)uprv_malloc(sizeof(UCAElements));
                    /* test for NULL */
                    if (origElem== NULL) {
                        *status = U_MEMORY_ALLOCATION_ERROR;
                        return 0;
                    }
                    /* copy the original UCA value */
                    origElem->prefixSize = 0;
                    origElem->prefix = NULL;
                    origElem->cPoints = origElem->uchars;
                    origElem->cPoints[0] = element->cPoints[0];
                    origElem->cSize = 1;
                    origElem->CEs[0]=CE;
                    origElem->mapCE=CE;
                    origElem->noOfCEs=1;
                    uprv_uca_finalizeAddition(t, origElem, status);
                    uprv_free(origElem);
                }
#ifdef UCOL_DEBUG
                fprintf(stderr, "Warning - trying to overwrite existing data %08X for cp %04X with %08X\n", CE, element->cPoints[0], element->CEs[0]);
                //*status = U_ILLEGAL_ARGUMENT_ERROR;
#endif
            }
        } else {
            /*ucmpe32_set(t->mapping, element->cPoints[0], element->mapCE);*/
            utrie_set32(t->mapping, element->cPoints[0], element->mapCE);
        }
    }
    return CE;
}

/* This adds a read element, while testing for existence */
U_CAPI uint32_t  U_EXPORT2
uprv_uca_addAnElement(tempUCATable *t, UCAElements *element, UErrorCode *status) {
    U_NAMESPACE_USE

    ExpansionTable *expansions = t->expansions;

    uint32_t i = 1;
    uint32_t expansion = 0;
    uint32_t CE;

    if(U_FAILURE(*status)) {
        return 0xFFFF;
    }

    element->mapCE = 0; // clear mapCE so that we can catch expansions

    if(element->noOfCEs == 1) {
        element->mapCE = element->CEs[0];      
    } else {     
        /* ICU 2.1 long primaries */
        /* unfortunately, it looks like we have to look for a long primary here */
        /* since in canonical closure we are going to hit some long primaries from */
        /* the first phase, and they will come back as continuations/expansions */
        /* destroying the effect of the previous opitimization */
        /* A long primary is a three byte primary with starting secondaries and tertiaries */
        /* It can appear in long runs of only primary differences (like east Asian tailorings) */
        /* also, it should not be an expansion, as expansions would break with this */
        // This part came in from ucol_bld.cpp
        //if(tok->expansion == 0
        //&& noOfBytes[0] == 3 && noOfBytes[1] == 1 && noOfBytes[2] == 1
        //&& CEparts[1] == (UCOL_BYTE_COMMON << 24) && CEparts[2] == (UCOL_BYTE_COMMON << 24)) {
        /* we will construct a special CE that will go unchanged to the table */
        if(element->noOfCEs == 2 // a two CE expansion 
            && isContinuation(element->CEs[1]) // which  is a continuation
            && (element->CEs[1] & (~(0xFF << 24 | UCOL_CONTINUATION_MARKER))) == 0 // that has only primaries in continuation,
            && (((element->CEs[0]>>8) & 0xFF) == UCOL_BYTE_COMMON) // a common secondary
            && ((element->CEs[0] & 0xFF) == UCOL_BYTE_COMMON) // and a common tertiary
            )
        {
#ifdef UCOL_DEBUG
            fprintf(stdout, "Long primary %04X\n", element->cPoints[0]);
#endif
            element->mapCE = UCOL_SPECIAL_FLAG | (LONG_PRIMARY_TAG<<24) // a long primary special
                | ((element->CEs[0]>>8) & 0xFFFF00) // first and second byte of primary
                | ((element->CEs[1]>>24) & 0xFF);   // third byte of primary
        }
        else {
            expansion = (uint32_t)(UCOL_SPECIAL_FLAG | (EXPANSION_TAG<<UCOL_TAG_SHIFT) 
                | ((uprv_uca_addExpansion(expansions, element->CEs[0], status)+(headersize>>2))<<4)
                & 0xFFFFF0);

            for(i = 1; i<element->noOfCEs; i++) {
                uprv_uca_addExpansion(expansions, element->CEs[i], status);
            }
            if(element->noOfCEs <= 0xF) {
                expansion |= element->noOfCEs;
            } else {
                uprv_uca_addExpansion(expansions, 0, status);
            }
            element->mapCE = expansion;
            uprv_uca_setMaxExpansion(element->CEs[element->noOfCEs - 1],
                (uint8_t)element->noOfCEs,
                t->maxExpansions,
                status);
            if(UCOL_ISJAMO(element->cPoints[0])) {
                t->image->jamoSpecial = TRUE;
                uprv_uca_setMaxJamoExpansion(element->cPoints[0],
                    element->CEs[element->noOfCEs - 1],
                    (uint8_t)element->noOfCEs,
                    t->maxJamoExpansions,
                    status);
            }
            if (U_FAILURE(*status)) {
                return 0;
            }
        }
    }

    // We treat digits differently - they are "uber special" and should be
    // processed differently if numeric collation is on. 
    UChar32 uniChar = 0;
    //printElement(element);
    if ((element->cSize == 2) && U16_IS_LEAD(element->cPoints[0])){
        uniChar = U16_GET_SUPPLEMENTARY(element->cPoints[0], element->cPoints[1]);
    } else if (element->cSize == 1){
        uniChar = element->cPoints[0];
    }

    // Here, we either have one normal CE OR mapCE is set. Therefore, we stuff only
    // one element to the expansion buffer. When we encounter a digit and we don't 
    // do numeric collation, we will just pick the CE we have and break out of case
    // (see ucol.cpp ucol_prv_getSpecialCE && ucol_prv_getSpecialPrevCE). If we picked
    // a special, further processing will occur. If it's a simple CE, we'll return due
    // to how the loop is constructed.
    if (uniChar != 0 && u_isdigit(uniChar)){
        expansion = (uint32_t)(UCOL_SPECIAL_FLAG | (DIGIT_TAG<<UCOL_TAG_SHIFT) | 1); // prepare the element
        if(element->mapCE) { // if there is an expansion, we'll pick it here
            expansion |= ((uprv_uca_addExpansion(expansions, element->mapCE, status)+(headersize>>2))<<4);
        } else {
            expansion |= ((uprv_uca_addExpansion(expansions, element->CEs[0], status)+(headersize>>2))<<4);
        }
        element->mapCE = expansion;

        // Need to go back to the beginning of the digit string if in the middle!
        if(uniChar <= 0xFFFF) { // supplementaries are always unsafe. API takes UChars
            unsafeCPSet(t->unsafeCP, (UChar)uniChar);
        }
    }

    // here we want to add the prefix structure.
    // I will try to process it as a reverse contraction, if possible.
    // prefix buffer is already reversed.

    if(element->prefixSize!=0) {
        // We keep the seen prefix starter elements in a hashtable
        // we need it to be able to distinguish between the simple
        // codepoints and prefix starters. Also, we need to use it
        // for canonical closure.

        UCAElements *composed = (UCAElements *)uprv_malloc(sizeof(UCAElements));
        /* test for NULL */
        if (composed == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return 0;
        }
        uprv_memcpy(composed, element, sizeof(UCAElements));
        composed->cPoints = composed->uchars;
        composed->prefix = composed->prefixChars;

        composed->prefixSize = unorm_normalize(element->prefix, element->prefixSize, UNORM_NFC, 0, composed->prefix, 128, status);


        if(t->prefixLookup != NULL) {
            UCAElements *uCE = (UCAElements *)uhash_get(t->prefixLookup, element);
            if(uCE != NULL) { // there is already a set of code points here
                element->mapCE = uprv_uca_addPrefix(t, uCE->mapCE, element, status);
            } else { // no code points, so this spot is clean
                element->mapCE = uprv_uca_addPrefix(t, UCOL_NOT_FOUND, element, status);
                uCE = (UCAElements *)uprv_malloc(sizeof(UCAElements));
                /* test for NULL */
                if (uCE == NULL) {
                    *status = U_MEMORY_ALLOCATION_ERROR;
                    return 0;
                }
                uprv_memcpy(uCE, element, sizeof(UCAElements));
                uCE->cPoints = uCE->uchars;
                uhash_put(t->prefixLookup, uCE, uCE, status);
            }
            if(composed->prefixSize != element->prefixSize || uprv_memcmp(composed->prefix, element->prefix, element->prefixSize)) {
                // do it!
                composed->mapCE = uprv_uca_addPrefix(t, element->mapCE, composed, status);
            }
        }
        uprv_free(composed);
    }

    // We need to use the canonical iterator here
    // the way we do it is to generate the canonically equivalent strings 
    // for the contraction and then add the sequences that pass FCD check
    if(element->cSize > 1 && !(element->cSize==2 && UTF16_IS_LEAD(element->cPoints[0]) && UTF16_IS_TRAIL(element->cPoints[1]))) { // this is a contraction, we should check whether a composed form should also be included
        UnicodeString source(element->cPoints, element->cSize);
        CanonicalIterator it(source, *status);
        source = it.next();
        while(!source.isBogus()) {
            if(Normalizer::quickCheck(source, UNORM_FCD, *status) != UNORM_NO) {
                element->cSize = source.extract(element->cPoints, 128, *status);
                uprv_uca_finalizeAddition(t, element, status);
            }
            source = it.next();
        }
        CE = element->mapCE;
    } else {
        CE = uprv_uca_finalizeAddition(t, element, status);  
    }

    return CE;
}


/*void uprv_uca_getMaxExpansionJamo(CompactEIntArray       *mapping, */
static void uprv_uca_getMaxExpansionJamo(UNewTrie       *mapping, 
                                         MaxExpansionTable     *maxexpansion,
                                         MaxJamoExpansionTable *maxjamoexpansion,
                                         UBool                  jamospecial,
                                         UErrorCode            *status)
{
    const uint32_t VBASE  = 0x1161;
    const uint32_t TBASE  = 0x11A8;
    const uint32_t VCOUNT = 21;
    const uint32_t TCOUNT = 28;

    uint32_t v = VBASE + VCOUNT - 1;
    uint32_t t = TBASE + TCOUNT - 1;
    uint32_t ce;

    while (v >= VBASE) {
        /*ce = ucmpe32_get(mapping, v);*/
        ce = utrie_get32(mapping, v, NULL);
        if (ce < UCOL_SPECIAL_FLAG) {
            uprv_uca_setMaxExpansion(ce, 2, maxexpansion, status);
        }
        v --;
    }

    while (t >= TBASE)
    {
        /*ce = ucmpe32_get(mapping, t);*/
        ce = utrie_get32(mapping, t, NULL);
        if (ce < UCOL_SPECIAL_FLAG) {
            uprv_uca_setMaxExpansion(ce, 3, maxexpansion, status);
        }
        t --;
    }
    /*  According to the docs, 99% of the time, the Jamo will not be special */
    if (jamospecial) {
        /* gets the max expansion in all unicode characters */
        int     count    = maxjamoexpansion->position;
        uint8_t maxTSize = (uint8_t)(maxjamoexpansion->maxLSize + 
            maxjamoexpansion->maxVSize +
            maxjamoexpansion->maxTSize);
        uint8_t maxVSize = (uint8_t)(maxjamoexpansion->maxLSize + 
            maxjamoexpansion->maxVSize);

        while (count > 0) {
            count --;
            if (*(maxjamoexpansion->isV + count) == TRUE) {
                uprv_uca_setMaxExpansion(
                    *(maxjamoexpansion->endExpansionCE + count), 
                    maxVSize, maxexpansion, status);
            }
            else {
                uprv_uca_setMaxExpansion(
                    *(maxjamoexpansion->endExpansionCE + count), 
                    maxTSize, maxexpansion, status);
            }
        }
    }
}

U_CDECL_BEGIN
static inline uint32_t U_CALLCONV
getFoldedValue(UNewTrie *trie, UChar32 start, int32_t offset)
{
    uint32_t value;
    uint32_t tag;
    UChar32 limit;
    UBool inBlockZero;

    limit=start+0x400;
    while(start<limit) {
        value=utrie_get32(trie, start, &inBlockZero);
        tag = getCETag(value);
        if(inBlockZero == TRUE) {
            start+=UTRIE_DATA_BLOCK_LENGTH;
        } else if(!(isSpecial(value) && (tag == IMPLICIT_TAG || tag == NOT_FOUND_TAG))) {
            /* These are values that are starting in either UCA (IMPLICIT_TAG) or in the 
            * tailorings (NOT_FOUND_TAG). Presence of these tags means that there is 
            * nothing in this position and that it should be skipped.
            */
#ifdef UCOL_DEBUG
            static int32_t count = 1;
            fprintf(stdout, "%i, Folded %08X, value %08X\n", count++, start, value);
#endif
            return (uint32_t)(UCOL_SPECIAL_FLAG | (SURROGATE_TAG<<24) | offset);
        } else {
            ++start;
        }
    }
    return 0;
}
U_CDECL_END

#ifdef UCOL_DEBUG
// This is a debug function to print the contents of a trie.
// It is used in conjuction with the code around utrie_unserialize call
void enumRange(const void *context, UChar32 start, UChar32 limit, uint32_t value) {
    if(start<0x10000) {
        fprintf(stdout, "%08X, %08X, %08X\n", start, limit, value);
    } else {
        fprintf(stdout, "%08X=%04X %04X, %08X=%04X %04X, %08X\n", start, UTF16_LEAD(start), UTF16_TRAIL(start), limit, UTF16_LEAD(limit), UTF16_TRAIL(limit), value);
    }
}

int32_t 
myGetFoldingOffset(uint32_t data) {
    if(data > UCOL_NOT_FOUND && getCETag(data) == SURROGATE_TAG) {
        return (data&0xFFFFFF);
    } else {
        return 0;
    }
}
#endif

U_CAPI UCATableHeader* U_EXPORT2
uprv_uca_assembleTable(tempUCATable *t, UErrorCode *status) {
    /*CompactEIntArray *mapping = t->mapping;*/
    UNewTrie *mapping = t->mapping;
    ExpansionTable *expansions = t->expansions;
    CntTable *contractions = t->contractions;
    MaxExpansionTable *maxexpansion = t->maxExpansions;

    if(U_FAILURE(*status)) {
        return NULL;
    }

    uint32_t beforeContractions = (uint32_t)((headersize+paddedsize(expansions->position*sizeof(uint32_t)))/sizeof(UChar));

    int32_t contractionsSize = 0;
    contractionsSize = uprv_cnttab_constructTable(contractions, beforeContractions, status);

    /* the following operation depends on the trie data. Therefore, we have to do it before */
    /* the trie is compacted */
    /* sets jamo expansions */
    uprv_uca_getMaxExpansionJamo(mapping, maxexpansion, t->maxJamoExpansions,
        t->image->jamoSpecial, status);

    /*ucmpe32_compact(mapping);*/
    /*UMemoryStream *ms = uprv_mstrm_openNew(8192);*/
    /*int32_t mappingSize = ucmpe32_flattenMem(mapping, ms);*/
    /*const uint8_t *flattened = uprv_mstrm_getBuffer(ms, &mappingSize);*/

    // After setting the jamo expansions, compact the trie and get the needed size
    int32_t mappingSize = utrie_serialize(mapping, NULL, 0, getFoldedValue /*getFoldedValue*/, FALSE, status);

    uint32_t tableOffset = 0;
    uint8_t *dataStart;

    /* TODO: LATIN1 array is now in the utrie - it should be removed from the calculation */

    uint32_t toAllocate =(uint32_t)(headersize+                                    
        paddedsize(expansions->position*sizeof(uint32_t))+
        paddedsize(mappingSize)+
        paddedsize(contractionsSize*(sizeof(UChar)+sizeof(uint32_t)))+
        //paddedsize(0x100*sizeof(uint32_t))  /* Latin1 is now included in the trie */
        /* maxexpansion array */
        + paddedsize(maxexpansion->position * sizeof(uint32_t)) +
        /* maxexpansion size array */
        paddedsize(maxexpansion->position * sizeof(uint8_t)) +
        paddedsize(UCOL_UNSAFECP_TABLE_SIZE) +   /*  Unsafe chars             */
        paddedsize(UCOL_UNSAFECP_TABLE_SIZE));    /*  Contraction Ending chars */


    dataStart = (uint8_t *)uprv_malloc(toAllocate);
    /* test for NULL */
    if (dataStart == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    UCATableHeader *myData = (UCATableHeader *)dataStart;
    // Please, do reset all the fields!
    uprv_memset(dataStart, 0, toAllocate);
    // Make sure we know this is reset
    myData->magic = UCOL_HEADER_MAGIC;
    myData->isBigEndian = U_IS_BIG_ENDIAN;
    myData->charSetFamily = U_CHARSET_FAMILY;
    myData->formatVersion[0] = UCA_FORMAT_VERSION_0;
    myData->formatVersion[1] = UCA_FORMAT_VERSION_1;
    myData->formatVersion[2] = UCA_FORMAT_VERSION_2;
    myData->formatVersion[3] = UCA_FORMAT_VERSION_3;
    myData->jamoSpecial = t->image->jamoSpecial;

    // Don't copy stuff from UCA header!
    //uprv_memcpy(myData, t->image, sizeof(UCATableHeader));

    myData->contractionSize = contractionsSize;

    tableOffset += (uint32_t)(paddedsize(sizeof(UCATableHeader)));

    myData->options = tableOffset;
    uprv_memcpy(dataStart+tableOffset, t->options, sizeof(UColOptionSet));
    tableOffset += (uint32_t)(paddedsize(sizeof(UColOptionSet)));

    /* copy expansions */
    /*myData->expansion = (uint32_t *)dataStart+tableOffset;*/
    myData->expansion = tableOffset;
    uprv_memcpy(dataStart+tableOffset, expansions->CEs, expansions->position*sizeof(uint32_t));
    tableOffset += (uint32_t)(paddedsize(expansions->position*sizeof(uint32_t)));

    /* contractions block */
    if(contractionsSize != 0) {
        /* copy contraction index */
        /*myData->contractionIndex = (UChar *)(dataStart+tableOffset);*/
        myData->contractionIndex = tableOffset;
        uprv_memcpy(dataStart+tableOffset, contractions->codePoints, contractionsSize*sizeof(UChar));
        tableOffset += (uint32_t)(paddedsize(contractionsSize*sizeof(UChar)));

        /* copy contraction collation elements */
        /*myData->contractionCEs = (uint32_t *)(dataStart+tableOffset);*/
        myData->contractionCEs = tableOffset;
        uprv_memcpy(dataStart+tableOffset, contractions->CEs, contractionsSize*sizeof(uint32_t));
        tableOffset += (uint32_t)(paddedsize(contractionsSize*sizeof(uint32_t)));
    } else {
        myData->contractionIndex = 0;
        myData->contractionCEs = 0;
    }

    /* copy mapping table */
    /*myData->mappingPosition = dataStart+tableOffset;*/
    /*myData->mappingPosition = tableOffset;*/
    /*uprv_memcpy(dataStart+tableOffset, flattened, mappingSize);*/

    myData->mappingPosition = tableOffset;
    utrie_serialize(mapping, dataStart+tableOffset, toAllocate-tableOffset, getFoldedValue, FALSE, status);
#ifdef UCOL_DEBUG
    // This is debug code to dump the contents of the trie. It needs two functions defined above
    {
        UTrie UCAt = { 0 };
        uint32_t trieWord;
        utrie_unserialize(&UCAt, dataStart+tableOffset, 9999999, status);
        UCAt.getFoldingOffset = myGetFoldingOffset;
        if(U_SUCCESS(*status)) {
            utrie_enum(&UCAt, NULL, enumRange, NULL);
        }
        trieWord = UTRIE_GET32_FROM_LEAD(UCAt, 0xDC01) 
    }
#endif
    tableOffset += paddedsize(mappingSize);


    int32_t i = 0;

    /* copy max expansion table */
    myData->endExpansionCE      = tableOffset;
    myData->endExpansionCECount = maxexpansion->position - 1;
    /* not copying the first element which is a dummy */
    uprv_memcpy(dataStart + tableOffset, maxexpansion->endExpansionCE + 1, 
        (maxexpansion->position - 1) * sizeof(uint32_t));
    tableOffset += (uint32_t)(paddedsize((maxexpansion->position)* sizeof(uint32_t)));
    myData->expansionCESize = tableOffset;
    uprv_memcpy(dataStart + tableOffset, maxexpansion->expansionCESize + 1, 
        (maxexpansion->position - 1) * sizeof(uint8_t));
    tableOffset += (uint32_t)(paddedsize((maxexpansion->position)* sizeof(uint8_t)));

    /* Unsafe chars table.  Finish it off, then copy it. */
    uprv_uca_unsafeCPAddCCNZ(t, status);
    if (t->UCA != 0) {              /* Or in unsafebits from UCA, making a combined table.    */
        for (i=0; i<UCOL_UNSAFECP_TABLE_SIZE; i++) {    
            t->unsafeCP[i] |= t->UCA->unsafeCP[i];
        }
    }
    myData->unsafeCP = tableOffset;
    uprv_memcpy(dataStart + tableOffset, t->unsafeCP, UCOL_UNSAFECP_TABLE_SIZE);
    tableOffset += paddedsize(UCOL_UNSAFECP_TABLE_SIZE);


    /* Finish building Contraction Ending chars hash table and then copy it out.  */
    if (t->UCA != 0) {              /* Or in unsafebits from UCA, making a combined table.    */
        for (i=0; i<UCOL_UNSAFECP_TABLE_SIZE; i++) {    
            t->contrEndCP[i] |= t->UCA->contrEndCP[i];
        }
    }
    myData->contrEndCP = tableOffset;
    uprv_memcpy(dataStart + tableOffset, t->contrEndCP, UCOL_UNSAFECP_TABLE_SIZE);
    tableOffset += paddedsize(UCOL_UNSAFECP_TABLE_SIZE);

    if(tableOffset != toAllocate) {
#ifdef UCOL_DEBUG
        fprintf(stderr, "calculation screwup!!! Expected to write %i but wrote %i instead!!!\n", toAllocate, tableOffset);
#endif
        *status = U_INTERNAL_PROGRAM_ERROR;
        uprv_free(dataStart);
        return 0;
    }

    myData->size = tableOffset;
    /* This should happen upon ressurection */
    /*const uint8_t *mapPosition = (uint8_t*)myData+myData->mappingPosition;*/
    /*uprv_mstrm_close(ms);*/
    return myData;
}


struct enumStruct {
    tempUCATable *t;
    UCollator *tempColl;
    UCollationElements* colEl;
    const Normalizer2Impl *nfcImpl;
    int32_t noOfClosures;
    UErrorCode *status;
};
U_CDECL_BEGIN
static UBool U_CALLCONV
_enumCategoryRangeClosureCategory(const void *context, UChar32 start, UChar32 limit, UCharCategory type) {

    if (type != U_UNASSIGNED && type != U_PRIVATE_USE_CHAR) { // if the range is assigned - we might ommit more categories later
        UErrorCode *status = ((enumStruct *)context)->status;
        tempUCATable *t = ((enumStruct *)context)->t;
        UCollator *tempColl = ((enumStruct *)context)->tempColl;
        UCollationElements* colEl = ((enumStruct *)context)->colEl;
        UCAElements el;
        UChar decompBuffer[4];
        const UChar *decomp;
        int32_t noOfDec = 0;

        UChar32 u32 = 0;
        UChar comp[2];
        uint32_t len = 0;

        for(u32 = start; u32 < limit; u32++) {
            decomp = ((enumStruct *)context)->nfcImpl->
                getDecomposition(u32, decompBuffer, noOfDec);
            //if((noOfDec = unorm_normalize(comp, len, UNORM_NFD, 0, decomp, 256, status)) > 1
            //|| (noOfDec == 1 && *decomp != (UChar)u32))
            if(decomp != NULL)
            {
                len = 0;
                U16_APPEND_UNSAFE(comp, len, u32);
                if(ucol_strcoll(tempColl, comp, len, decomp, noOfDec) != UCOL_EQUAL) {
#ifdef UCOL_DEBUG
                    fprintf(stderr, "Closure: %08X -> ", u32);
                    uint32_t i = 0;
                    for(i = 0; i<noOfDec; i++) {
                        fprintf(stderr, "%04X ", decomp[i]);
                    }
                    fprintf(stderr, "\n");
#endif
                    ((enumStruct *)context)->noOfClosures++;
                    el.cPoints = (UChar *)decomp;
                    el.cSize = noOfDec;
                    el.noOfCEs = 0;
                    el.prefix = el.prefixChars;
                    el.prefixSize = 0;

                    UCAElements *prefix=(UCAElements *)uhash_get(t->prefixLookup, &el);
                    el.cPoints = comp;
                    el.cSize = len;
                    el.prefix = el.prefixChars;
                    el.prefixSize = 0;
                    if(prefix == NULL) {
                        el.noOfCEs = 0;
                        ucol_setText(colEl, decomp, noOfDec, status);
                        while((el.CEs[el.noOfCEs] = ucol_next(colEl, status)) != (uint32_t)UCOL_NULLORDER) {
                            el.noOfCEs++;
                        }
                    } else {
                        el.noOfCEs = 1;
                        el.CEs[0] = prefix->mapCE;
                        // This character uses a prefix. We have to add it 
                        // to the unsafe table, as it decomposed form is already
                        // in. In Japanese, this happens for \u309e & \u30fe
                        // Since unsafeCPSet is static in ucol_elm, we are going
                        // to wrap it up in the uprv_uca_unsafeCPAddCCNZ function
                    }
                    uprv_uca_addAnElement(t, &el, status);
                }
            }
        }
    }
    return TRUE;
}
U_CDECL_END

static void
uprv_uca_setMapCE(tempUCATable *t, UCAElements *element, UErrorCode *status) {
    uint32_t expansion = 0;
    int32_t j;

    ExpansionTable *expansions = t->expansions;
    if(element->noOfCEs == 2 // a two CE expansion
        && isContinuation(element->CEs[1]) // which  is a continuation
        && (element->CEs[1] & (~(0xFF << 24 | UCOL_CONTINUATION_MARKER))) == 0 // that has only primaries in continuation,
        && (((element->CEs[0]>>8) & 0xFF) == UCOL_BYTE_COMMON) // a common secondary
        && ((element->CEs[0] & 0xFF) == UCOL_BYTE_COMMON) // and a common tertiary
        ) {
            element->mapCE = UCOL_SPECIAL_FLAG | (LONG_PRIMARY_TAG<<24) // a long primary special
                | ((element->CEs[0]>>8) & 0xFFFF00) // first and second byte of primary
                | ((element->CEs[1]>>24) & 0xFF);   // third byte of primary
        } else {
            expansion = (uint32_t)(UCOL_SPECIAL_FLAG | (EXPANSION_TAG<<UCOL_TAG_SHIFT)
                | ((uprv_uca_addExpansion(expansions, element->CEs[0], status)+(headersize>>2))<<4)
                & 0xFFFFF0);

            for(j = 1; j<(int32_t)element->noOfCEs; j++) {
                uprv_uca_addExpansion(expansions, element->CEs[j], status);
            }
            if(element->noOfCEs <= 0xF) {
                expansion |= element->noOfCEs;
            } else {
                uprv_uca_addExpansion(expansions, 0, status);
            }
            element->mapCE = expansion;
            uprv_uca_setMaxExpansion(element->CEs[element->noOfCEs - 1],
                (uint8_t)element->noOfCEs,
                t->maxExpansions,
                status);
        }
}

static void
uprv_uca_addFCD4AccentedContractions(tempUCATable *t,
                                      UCollationElements* colEl,
                                      UChar *data,
                                      int32_t len,
                                      UCAElements *el,
                                      UErrorCode *status) {
    UChar decomp[256], comp[256];
    int32_t decLen, compLen;

    decLen = unorm_normalize(data, len, UNORM_NFD, 0, decomp, 256, status);
    compLen = unorm_normalize(data, len, UNORM_NFC, 0, comp, 256, status);
    decomp[decLen] = comp[compLen] = 0;

    el->cPoints = decomp;
    el->cSize = decLen;
    el->noOfCEs = 0;
    el->prefixSize = 0;
    el->prefix = el->prefixChars;

    UCAElements *prefix=(UCAElements *)uhash_get(t->prefixLookup, el);
    el->cPoints = comp;
    el->cSize = compLen;
    el->prefix = el->prefixChars;
    el->prefixSize = 0;
    if(prefix == NULL) {
        el->noOfCEs = 0;
        ucol_setText(colEl, decomp, decLen, status);
        while((el->CEs[el->noOfCEs] = ucol_next(colEl, status)) != (uint32_t)UCOL_NULLORDER) {
            el->noOfCEs++;
        }
        uprv_uca_setMapCE(t, el, status);
        uprv_uca_addAnElement(t, el, status);
    }
}

static void
uprv_uca_addMultiCMContractions(tempUCATable *t,
                                UCollationElements* colEl,
                                tempTailorContext *c,
                                UCAElements *el,
                                UErrorCode *status) {
    CombinClassTable *cmLookup = t->cmLookup;
    UChar  newDecomp[256];
    int32_t maxComp, newDecLen;
    UChar32 fcdHighStart;
    const uint16_t *fcdTrieIndex = unorm_getFCDTrieIndex(fcdHighStart, status);
    if (U_FAILURE(*status)) {
        return;
    }
    int16_t curClass = (unorm_getFCD16(fcdTrieIndex, c->tailoringCM) & 0xff);
    CompData *precomp = c->precomp;
    int32_t  compLen = c->compLen;
    UChar *comp = c->comp;
    maxComp = c->precompLen;

    for (int32_t j=0; j < maxComp; j++) {
        int32_t count=0;
        do {
            if ( count == 0 ) {  // Decompose the saved precomposed char.
                UChar temp[2];
                temp[0]=precomp[j].cp;
                temp[1]=0;
                newDecLen = unorm_normalize(temp, 1, UNORM_NFD, 0,
                            newDecomp, sizeof(newDecomp)/sizeof(UChar), status);
                newDecomp[newDecLen++] = cmLookup->cPoints[c->cmPos];
            }
            else {  // swap 2 combining marks when they are equal.
                uprv_memcpy(newDecomp, c->decomp, sizeof(UChar)*(c->decompLen));
                newDecLen = c->decompLen;
                newDecomp[newDecLen++] = precomp[j].cClass;
            }
            newDecomp[newDecLen] = 0;
            compLen = unorm_normalize(newDecomp, newDecLen, UNORM_NFC, 0,
                              comp, 256, status);
            if (compLen==1) {
                comp[compLen++] = newDecomp[newDecLen++] = c->tailoringCM;
                comp[compLen] = newDecomp[newDecLen] = 0;
                el->cPoints = newDecomp;
                el->cSize = newDecLen;

                UCAElements *prefix=(UCAElements *)uhash_get(t->prefixLookup, el);
                el->cPoints = c->comp;
                el->cSize = compLen;
                el->prefix = el->prefixChars;
                el->prefixSize = 0;
                if(prefix == NULL) {
                    el->noOfCEs = 0;
                    ucol_setText(colEl, newDecomp, newDecLen, status);
                    while((el->CEs[el->noOfCEs] = ucol_next(colEl, status)) != (uint32_t)UCOL_NULLORDER) {
                        el->noOfCEs++;
                    }
                    uprv_uca_setMapCE(t, el, status);
                    uprv_uca_finalizeAddition(t, el, status);

                    // Save the current precomposed char and its class to find any
                    // other combining mark combinations.
                    precomp[c->precompLen].cp=comp[0];
                    precomp[c->precompLen].cClass = curClass;
                    c->precompLen++;
                }
            }
        } while (++count<2 && (precomp[j].cClass == curClass));
    }

}

static void
uprv_uca_addTailCanonicalClosures(tempUCATable *t,
                                  UCollationElements* colEl,
                                  UChar baseCh,
                                  UChar cMark,
                                  UCAElements *el,
                                  UErrorCode *status) {
    CombinClassTable *cmLookup = t->cmLookup;
    UChar32 fcdHighStart;
    const uint16_t *fcdTrieIndex = unorm_getFCDTrieIndex(fcdHighStart, status);
    if (U_FAILURE(*status)) {
        return;
    }
    int16_t maxIndex = (unorm_getFCD16(fcdTrieIndex, cMark) & 0xff );
    UCAElements element;
    uint16_t *index;
    UChar  decomp[256];
    UChar  comp[256];
    CompData precomp[256];   // precomposed array
    int32_t  precompLen = 0; // count for precomp
    int32_t i, len, decompLen, curClass, replacedPos;
    tempTailorContext c;

    if ( cmLookup == NULL ) {
        return;
    }
    index = cmLookup->index;
    int32_t cClass=(unorm_getFCD16(fcdTrieIndex, cMark) & 0xff);
    maxIndex = (int32_t)index[(unorm_getFCD16(fcdTrieIndex, cMark) & 0xff)-1];
    c.comp = comp;
    c.decomp = decomp;
    c.precomp = precomp;
    c.tailoringCM =  cMark;

    if (cClass>0) {
        maxIndex = (int32_t)index[cClass-1];
    }
    else {
        maxIndex=0;
    }
    decomp[0]=baseCh;
    for ( i=0; i<maxIndex ; i++ ) {
        decomp[1] = cmLookup->cPoints[i];
        decomp[2]=0;
        decompLen=2;
        len = unorm_normalize(decomp, decompLen, UNORM_NFC, 0, comp, 256, status);
        if (len==1) {
            // Save the current precomposed char and its class to find any
            // other combining mark combinations.
            precomp[precompLen].cp=comp[0];
            curClass = precomp[precompLen].cClass =
                       index[unorm_getFCD16(fcdTrieIndex, decomp[1]) & 0xff];
            precompLen++;
            replacedPos=0;
            for (decompLen=0; decompLen< (int32_t)el->cSize; decompLen++) {
                decomp[decompLen] = el->cPoints[decompLen];
                if (decomp[decompLen]==cMark) {
                    replacedPos = decompLen;  // record the position for later use
                }
            }
            if ( replacedPos != 0 ) {
                decomp[replacedPos]=cmLookup->cPoints[i];
            }
            decomp[decompLen] = 0;
            len = unorm_normalize(decomp, decompLen, UNORM_NFC, 0, comp, 256, status);
            comp[len++] = decomp[decompLen++] = cMark;
            comp[len] = decomp[decompLen] = 0;
            element.cPoints = decomp;
            element.cSize = decompLen;
            element.noOfCEs = 0;
            element.prefix = el->prefixChars;
            element.prefixSize = 0;

            UCAElements *prefix=(UCAElements *)uhash_get(t->prefixLookup, &element);
            element.cPoints = comp;
            element.cSize = len;
            element.prefix = el->prefixChars;
            element.prefixSize = 0;
            if(prefix == NULL) {
                element.noOfCEs = 0;
                ucol_setText(colEl, decomp, decompLen, status);
                while((element.CEs[element.noOfCEs] = ucol_next(colEl, status)) != (uint32_t)UCOL_NULLORDER) {
                    element.noOfCEs++;
                }
                uprv_uca_setMapCE(t, &element, status);
                uprv_uca_finalizeAddition(t, &element, status);
            }

            // This is a fix for tailoring contractions with accented
            // character at the end of contraction string.
            if ((len>2) && 
                (unorm_getFCD16(fcdTrieIndex, comp[len-2]) & 0xff00)==0) {
                uprv_uca_addFCD4AccentedContractions(t, colEl, comp, len, &element, status);
            }

            if (precompLen >1) {
                c.compLen = len;
                c.decompLen = decompLen;
                c.precompLen = precompLen;
                c.cmPos = i;
                uprv_uca_addMultiCMContractions(t, colEl, &c, &element, status);
                precompLen = c.precompLen;
            }
        }
    }
}

U_CFUNC int32_t U_EXPORT2
uprv_uca_canonicalClosure(tempUCATable *t,
                          UColTokenParser *src,
                          UErrorCode *status)
{
    enumStruct context;
    context.noOfClosures = 0;
    UCAElements el;
    UColToken *tok;
    uint32_t i = 0, j = 0;
    UChar  baseChar, firstCM;
    UChar32 fcdHighStart;
    const uint16_t *fcdTrieIndex = unorm_getFCDTrieIndex(fcdHighStart, status);
    context.nfcImpl=Normalizer2Factory::getNFCImpl(*status);
    if(U_FAILURE(*status)) {
        return 0;
    }

    UCollator *tempColl = NULL;
    tempUCATable *tempTable = uprv_uca_cloneTempTable(t, status);
    // Check for null pointer
    if (U_FAILURE(*status)) {
        return 0;
    }

    UCATableHeader *tempData = uprv_uca_assembleTable(tempTable, status);
    tempColl = ucol_initCollator(tempData, 0, t->UCA, status);
    if ( tempTable->cmLookup != NULL ) {
        t->cmLookup = tempTable->cmLookup;  // copy over to t
        tempTable->cmLookup = NULL;
    }
    uprv_uca_closeTempTable(tempTable);

    if(U_SUCCESS(*status)) {
        tempColl->ucaRules = NULL;
        tempColl->actualLocale = NULL;
        tempColl->validLocale = NULL;
        tempColl->requestedLocale = NULL;
        tempColl->hasRealData = TRUE;
        tempColl->freeImageOnClose = TRUE;
    } else if(tempData != 0) {
        uprv_free(tempData);
    }

    /* produce canonical closure */
    UCollationElements* colEl = ucol_openElements(tempColl, NULL, 0, status);
    // Check for null pointer
    if (U_FAILURE(*status)) {
        return 0;
    }
    context.t = t;
    context.tempColl = tempColl;
    context.colEl = colEl;
    context.status = status;
    u_enumCharTypes(_enumCategoryRangeClosureCategory, &context);

    if ( (src==NULL) || !src->buildCCTabFlag ) {
        ucol_closeElements(colEl);
        ucol_close(tempColl);
        return context.noOfClosures;  // no extra contraction needed to add
    }

    for (i=0; i < src->resultLen; i++) {
        baseChar = firstCM= (UChar)0;
        tok = src->lh[i].first;
        while (tok != NULL && U_SUCCESS(*status)) {
            el.prefix = el.prefixChars;
            el.cPoints = el.uchars;
            if(tok->prefix != 0) {
                el.prefixSize = tok->prefix>>24;
                uprv_memcpy(el.prefix, src->source + (tok->prefix & 0x00FFFFFF), el.prefixSize*sizeof(UChar));

                el.cSize = (tok->source >> 24)-(tok->prefix>>24);
                uprv_memcpy(el.uchars, (tok->source & 0x00FFFFFF)+(tok->prefix>>24) + src->source, el.cSize*sizeof(UChar));
            } else {
                el.prefixSize = 0;
                *el.prefix = 0;

                el.cSize = (tok->source >> 24);
                uprv_memcpy(el.uchars, (tok->source & 0x00FFFFFF) + src->source, el.cSize*sizeof(UChar));
            }
            if(src->UCA != NULL) {
                for(j = 0; j<el.cSize; j++) {
                    int16_t fcd = unorm_getFCD16(fcdTrieIndex, el.cPoints[j]);
                    if ( (fcd & 0xff) == 0 ) {
                        baseChar = el.cPoints[j];  // last base character
                        firstCM=0;  // reset combining mark value
                    }
                    else {
                        if ( (baseChar!=0) && (firstCM==0) ) {
                            firstCM = el.cPoints[j];  // first combining mark
                        }
                    }
                }
            }
            if ( (baseChar!= (UChar)0) && (firstCM != (UChar)0) ) {
                // find all the canonical rules
                uprv_uca_addTailCanonicalClosures(t, colEl, baseChar, firstCM, &el, status);
            }
            tok = tok->next;
        }
    }
    ucol_closeElements(colEl);
    ucol_close(tempColl);
    
    return context.noOfClosures;
}

#endif /* #if !UCONFIG_NO_COLLATION */
