/*
*******************************************************************************
*
*   Copyright (C) 2001-2007, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*   file name:  ucol_bld.cpp
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created 02/22/2001
*   created by: Vladimir Weinstein
*
* This module builds a collator based on the rule set.
* 
*/

#include "unicode/utypes.h"

#if !UCONFIG_NO_COLLATION

#include "unicode/ucoleitr.h"
#include "unicode/uchar.h"
#include "ucol_bld.h" 
#include "ucln_in.h" 
#include "umutex.h"
#include "unicode/uniset.h"
#include "unormimp.h"

static const InverseUCATableHeader* _staticInvUCA = NULL;
static UDataMemory* invUCA_DATA_MEM = NULL;

U_CDECL_BEGIN
static UBool U_CALLCONV
isAcceptableInvUCA(void * /*context*/, 
                   const char * /*type*/, const char * /*name*/,
                   const UDataInfo *pInfo)
{
    /* context, type & name are intentionally not used */
    if( pInfo->size>=20 &&
        pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
        pInfo->charsetFamily==U_CHARSET_FAMILY &&
        pInfo->dataFormat[0]==INVUCA_DATA_FORMAT_0 &&   /* dataFormat="InvC" */
        pInfo->dataFormat[1]==INVUCA_DATA_FORMAT_1 &&
        pInfo->dataFormat[2]==INVUCA_DATA_FORMAT_2 &&
        pInfo->dataFormat[3]==INVUCA_DATA_FORMAT_3 &&
        pInfo->formatVersion[0]==INVUCA_FORMAT_VERSION_0 &&
        pInfo->formatVersion[1]>=INVUCA_FORMAT_VERSION_1 //&&
        //pInfo->formatVersion[1]==INVUCA_FORMAT_VERSION_1 &&
        //pInfo->formatVersion[2]==INVUCA_FORMAT_VERSION_2 &&
        //pInfo->formatVersion[3]==INVUCA_FORMAT_VERSION_3 &&
        ) {
            UVersionInfo UCDVersion;
            u_getUnicodeVersion(UCDVersion);
            if(pInfo->dataVersion[0]==UCDVersion[0] &&
                pInfo->dataVersion[1]==UCDVersion[1]) {
                    //pInfo->dataVersion[1]==invUcaDataInfo.dataVersion[1] &&
                    //pInfo->dataVersion[2]==invUcaDataInfo.dataVersion[2] &&
                    //pInfo->dataVersion[3]==invUcaDataInfo.dataVersion[3]) {
                    return TRUE;
                } else {
                    return FALSE;
                }
        } else {
            return FALSE;
        }
}
U_CDECL_END

/* 
* Takes two CEs (lead and continuation) and 
* compares them as CEs should be compared:
* primary vs. primary, secondary vs. secondary
* tertiary vs. tertiary
*/
static int32_t compareCEs(uint32_t source0, uint32_t source1, uint32_t target0, uint32_t target1) {
    uint32_t s1 = source0, s2, t1 = target0, t2;
    if(isContinuation(source1)) {
        s2 = source1;
    } else {
        s2 = 0;
    }
    if(isContinuation(target1)) {
        t2 = target1;
    } else {
        t2 = 0;
    }

    uint32_t s = 0, t = 0;
    if(s1 == t1 && s2 == t2) {
        return 0;
    }
    s = (s1 & 0xFFFF0000)|((s2 & 0xFFFF0000)>>16); 
    t = (t1 & 0xFFFF0000)|((t2 & 0xFFFF0000)>>16); 
    if(s < t) {
        return -1;
    } else if(s > t) {
        return 1;
    } else {
        s = (s1 & 0x0000FF00) | (s2 & 0x0000FF00)>>8;
        t = (t1 & 0x0000FF00) | (t2 & 0x0000FF00)>>8;
        if(s < t) {
            return -1;
        } else if(s > t) {
            return 1;
        } else {
            s = (s1 & 0x000000FF)<<8 | (s2 & 0x000000FF);
            t = (t1 & 0x000000FF)<<8 | (t2 & 0x000000FF);
            if(s < t) {
                return -1;
            } else {
                return 1;
            }
        }
    }
}

static
int32_t ucol_inv_findCE(const UColTokenParser *src, uint32_t CE, uint32_t SecondCE) {
    uint32_t bottom = 0, top = src->invUCA->tableSize;
    uint32_t i = 0;
    uint32_t first = 0, second = 0;
    uint32_t *CETable = (uint32_t *)((uint8_t *)src->invUCA+src->invUCA->table);
    int32_t res = 0;

    while(bottom < top-1) {
        i = (top+bottom)/2;
        first = *(CETable+3*i);
        second = *(CETable+3*i+1);
        res = compareCEs(first, second, CE, SecondCE);
        if(res > 0) {
            top = i;
        } else if(res < 0) {
            bottom = i;
        } else {
            break;
        }
    }

    /* weiv:                                                  */
    /* in searching for elements, I have removed the failure  */
    /* The reason for this is that the builder does not rely  */
    /* on search mechanism telling it that it didn't find an  */
    /* element. However, indirect positioning relies on being */
    /* able to find the elements around any CE, even if it is */
    /* not defined in the UCA. */
    return i;
    /*
    if((first == CE && second == SecondCE)) {
    return i;
    } else {
    return -1;
    }
    */
}

static const uint32_t strengthMask[UCOL_CE_STRENGTH_LIMIT] = {
    0xFFFF0000,
        0xFFFFFF00,
        0xFFFFFFFF
};

U_CAPI int32_t U_EXPORT2 ucol_inv_getNextCE(const UColTokenParser *src,
                                            uint32_t CE, uint32_t contCE, 
                                            uint32_t *nextCE, uint32_t *nextContCE, 
                                            uint32_t strength)
{
    uint32_t *CETable = (uint32_t *)((uint8_t *)src->invUCA+src->invUCA->table);
    int32_t iCE;

    iCE = ucol_inv_findCE(src, CE, contCE);

    if(iCE<0) {
        *nextCE = UCOL_NOT_FOUND;
        return -1;
    }

    CE &= strengthMask[strength];
    contCE &= strengthMask[strength];

    *nextCE = CE;
    *nextContCE = contCE;

    while((*nextCE  & strengthMask[strength]) == CE 
        && (*nextContCE  & strengthMask[strength]) == contCE) {
            *nextCE = (*(CETable+3*(++iCE)));
            *nextContCE = (*(CETable+3*(iCE)+1));
        }

        return iCE;
}

U_CFUNC int32_t U_EXPORT2 ucol_inv_getPrevCE(const UColTokenParser *src, 
                                            uint32_t CE, uint32_t contCE, 
                                            uint32_t *prevCE, uint32_t *prevContCE, 
                                            uint32_t strength)
{
    uint32_t *CETable = (uint32_t *)((uint8_t *)src->invUCA+src->invUCA->table);
    int32_t iCE;

    iCE = ucol_inv_findCE(src, CE, contCE);

    if(iCE<0) {
        *prevCE = UCOL_NOT_FOUND;
        return -1;
    }

    CE &= strengthMask[strength];
    contCE &= strengthMask[strength];

    *prevCE = CE;
    *prevContCE = contCE;

    while((*prevCE  & strengthMask[strength]) == CE 
        && (*prevContCE  & strengthMask[strength])== contCE
        && iCE > 0) { /* this condition should prevent falling off the edge of the world */
            /* here, we end up in a singularity - zero */
            *prevCE = (*(CETable+3*(--iCE)));
            *prevContCE = (*(CETable+3*(iCE)+1));
        }

        return iCE;
}

U_CFUNC uint32_t U_EXPORT2 ucol_getCEStrengthDifference(uint32_t CE, uint32_t contCE, 
                                                       uint32_t prevCE, uint32_t prevContCE) 
{
    if(prevCE == CE && prevContCE == contCE) {
        return UCOL_IDENTICAL;
    }
    if((prevCE & strengthMask[UCOL_PRIMARY]) != (CE & strengthMask[UCOL_PRIMARY])
        || (prevContCE & strengthMask[UCOL_PRIMARY]) != (contCE & strengthMask[UCOL_PRIMARY])) {
            return UCOL_PRIMARY;
        }
        if((prevCE & strengthMask[UCOL_SECONDARY]) != (CE & strengthMask[UCOL_SECONDARY])
            || (prevContCE & strengthMask[UCOL_SECONDARY]) != (contCE & strengthMask[UCOL_SECONDARY])) {
                return UCOL_SECONDARY;
            }
            return UCOL_TERTIARY;                                            
}


/*static
inline int32_t ucol_inv_getPrevious(UColTokenParser *src, UColTokListHeader *lh, uint32_t strength) {

    uint32_t CE = lh->baseCE;
    uint32_t SecondCE = lh->baseContCE; 

    uint32_t *CETable = (uint32_t *)((uint8_t *)src->invUCA+src->invUCA->table);
    uint32_t previousCE, previousContCE;
    int32_t iCE;

    iCE = ucol_inv_findCE(src, CE, SecondCE);

    if(iCE<0) {
        return -1;
    }

    CE &= strengthMask[strength];
    SecondCE &= strengthMask[strength];

    previousCE = CE;
    previousContCE = SecondCE;

    while((previousCE  & strengthMask[strength]) == CE && (previousContCE  & strengthMask[strength])== SecondCE) {
        previousCE = (*(CETable+3*(--iCE)));
        previousContCE = (*(CETable+3*(iCE)+1));
    }
    lh->previousCE = previousCE;
    lh->previousContCE = previousContCE;

    return iCE;
}*/

static
inline int32_t ucol_inv_getNext(UColTokenParser *src, UColTokListHeader *lh, uint32_t strength) {
    uint32_t CE = lh->baseCE;
    uint32_t SecondCE = lh->baseContCE; 

    uint32_t *CETable = (uint32_t *)((uint8_t *)src->invUCA+src->invUCA->table);
    uint32_t nextCE, nextContCE;
    int32_t iCE;

    iCE = ucol_inv_findCE(src, CE, SecondCE);

    if(iCE<0) {
        return -1;
    }

    CE &= strengthMask[strength];
    SecondCE &= strengthMask[strength];

    nextCE = CE;
    nextContCE = SecondCE;

    while((nextCE  & strengthMask[strength]) == CE 
        && (nextContCE  & strengthMask[strength]) == SecondCE) {
            nextCE = (*(CETable+3*(++iCE)));
            nextContCE = (*(CETable+3*(iCE)+1));
        }

        lh->nextCE = nextCE;
        lh->nextContCE = nextContCE;

        return iCE;
}

U_CFUNC void ucol_inv_getGapPositions(UColTokenParser *src, UColTokListHeader *lh, UErrorCode *status) {
    /* reset all the gaps */
    int32_t i = 0;
    uint32_t *CETable = (uint32_t *)((uint8_t *)src->invUCA+src->invUCA->table);
    uint32_t st = 0;
    uint32_t t1, t2;
    int32_t pos;

    UColToken *tok = lh->first;
    uint32_t tokStrength = tok->strength;

    for(i = 0; i<3; i++) {
        lh->gapsHi[3*i] = 0;
        lh->gapsHi[3*i+1] = 0;
        lh->gapsHi[3*i+2] = 0;
        lh->gapsLo[3*i] = 0;
        lh->gapsLo[3*i+1] = 0;
        lh->gapsLo[3*i+2] = 0;
        lh->numStr[i] = 0;
        lh->fStrToken[i] = NULL;
        lh->lStrToken[i] = NULL;
        lh->pos[i] = -1;
    }

    UCAConstants *consts = (UCAConstants *)((uint8_t *)src->UCA->image + src->UCA->image->UCAConsts);

    if((lh->baseCE & 0xFF000000)>= (consts->UCA_PRIMARY_IMPLICIT_MIN<<24) && (lh->baseCE & 0xFF000000) <= (consts->UCA_PRIMARY_IMPLICIT_MAX<<24) ) { /* implicits - */ 
        //if(lh->baseCE >= PRIMARY_IMPLICIT_MIN && lh->baseCE < PRIMARY_IMPLICIT_MAX ) { /* implicits - */ 
        lh->pos[0] = 0;
        t1 = lh->baseCE;
        t2 = lh->baseContCE & UCOL_REMOVE_CONTINUATION;
        lh->gapsLo[0] = (t1 & UCOL_PRIMARYMASK) | (t2 & UCOL_PRIMARYMASK) >> 16;
        lh->gapsLo[1] = (t1 & UCOL_SECONDARYMASK) << 16 | (t2 & UCOL_SECONDARYMASK) << 8;
        lh->gapsLo[2] = (UCOL_TERTIARYORDER(t1)) << 24 | (UCOL_TERTIARYORDER(t2)) << 16;
        uint32_t primaryCE = t1 & UCOL_PRIMARYMASK | (t2 & UCOL_PRIMARYMASK) >> 16;
        primaryCE = uprv_uca_getImplicitFromRaw(uprv_uca_getRawFromImplicit(primaryCE)+1);

        t1 = primaryCE & UCOL_PRIMARYMASK | 0x0505;
        t2 = (primaryCE << 16) & UCOL_PRIMARYMASK; // | UCOL_CONTINUATION_MARKER;

        lh->gapsHi[0] = (t1 & UCOL_PRIMARYMASK) | (t2 & UCOL_PRIMARYMASK) >> 16;
        lh->gapsHi[1] = (t1 & UCOL_SECONDARYMASK) << 16 | (t2 & UCOL_SECONDARYMASK) << 8;
        lh->gapsHi[2] = (UCOL_TERTIARYORDER(t1)) << 24 | (UCOL_TERTIARYORDER(t2)) << 16;
    } else if(lh->indirect == TRUE && lh->nextCE != 0) {
        //} else if(lh->baseCE == UCOL_RESET_TOP_VALUE && lh->baseContCE == 0) {
        lh->pos[0] = 0;
        t1 = lh->baseCE;
        t2 = lh->baseContCE&UCOL_REMOVE_CONTINUATION;
        lh->gapsLo[0] = (t1 & UCOL_PRIMARYMASK) | (t2 & UCOL_PRIMARYMASK) >> 16;
        lh->gapsLo[1] = (t1 & UCOL_SECONDARYMASK) << 16 | (t2 & UCOL_SECONDARYMASK) << 8;
        lh->gapsLo[2] = (UCOL_TERTIARYORDER(t1)) << 24 | (UCOL_TERTIARYORDER(t2)) << 16;
        t1 = lh->nextCE;
        t2 = lh->nextContCE&UCOL_REMOVE_CONTINUATION;
        lh->gapsHi[0] = (t1 & UCOL_PRIMARYMASK) | (t2 & UCOL_PRIMARYMASK) >> 16;
        lh->gapsHi[1] = (t1 & UCOL_SECONDARYMASK) << 16 | (t2 & UCOL_SECONDARYMASK) << 8;
        lh->gapsHi[2] = (UCOL_TERTIARYORDER(t1)) << 24 | (UCOL_TERTIARYORDER(t2)) << 16;
    } else {
        for(;;) {
            if(tokStrength < UCOL_CE_STRENGTH_LIMIT) {
                if((lh->pos[tokStrength] = ucol_inv_getNext(src, lh, tokStrength)) >= 0) {
                    lh->fStrToken[tokStrength] = tok;
                } else { /* The CE must be implicit, since it's not in the table */
                    /* Error */
                    *status = U_INTERNAL_PROGRAM_ERROR;
                }
            }

            while(tok != NULL && tok->strength >= tokStrength) {
                if(tokStrength < UCOL_CE_STRENGTH_LIMIT) {
                    lh->lStrToken[tokStrength] = tok;
                }
                tok = tok->next;
            }
            if(tokStrength < UCOL_CE_STRENGTH_LIMIT-1) {
                /* check if previous interval is the same and merge the intervals if it is so */
                if(lh->pos[tokStrength] == lh->pos[tokStrength+1]) {
                    lh->fStrToken[tokStrength] = lh->fStrToken[tokStrength+1];
                    lh->fStrToken[tokStrength+1] = NULL;
                    lh->lStrToken[tokStrength+1] = NULL;
                    lh->pos[tokStrength+1] = -1;
                }
            }
            if(tok != NULL) {
                tokStrength = tok->strength;
            } else {
                break;
            }
        }
        for(st = 0; st < 3; st++) {
            if((pos = lh->pos[st]) >= 0) {
                t1 = *(CETable+3*(pos));
                t2 = *(CETable+3*(pos)+1);
                lh->gapsHi[3*st] = (t1 & UCOL_PRIMARYMASK) | (t2 & UCOL_PRIMARYMASK) >> 16;
                lh->gapsHi[3*st+1] = (t1 & UCOL_SECONDARYMASK) << 16 | (t2 & UCOL_SECONDARYMASK) << 8;
                //lh->gapsHi[3*st+2] = (UCOL_TERTIARYORDER(t1)) << 24 | (UCOL_TERTIARYORDER(t2)) << 16;
                lh->gapsHi[3*st+2] = (t1&0x3f) << 24 | (t2&0x3f) << 16;
                //pos--;
                //t1 = *(CETable+3*(pos));
                //t2 = *(CETable+3*(pos)+1);
                t1 = lh->baseCE;
                t2 = lh->baseContCE;
                lh->gapsLo[3*st] = (t1 & UCOL_PRIMARYMASK) | (t2 & UCOL_PRIMARYMASK) >> 16;
                lh->gapsLo[3*st+1] = (t1 & UCOL_SECONDARYMASK) << 16 | (t2 & UCOL_SECONDARYMASK) << 8;
                lh->gapsLo[3*st+2] = (t1&0x3f) << 24 | (t2&0x3f) << 16;
            }
        }
    }
}


#define ucol_countBytes(value, noOfBytes)   \
{                               \
    uint32_t mask = 0xFFFFFFFF;   \
    (noOfBytes) = 0;              \
    while(mask != 0) {            \
    if(((value) & mask) != 0) { \
    (noOfBytes)++;            \
    }                           \
    mask >>= 8;                 \
    }                             \
}

U_CFUNC uint32_t ucol_getNextGenerated(ucolCEGenerator *g, UErrorCode *status) {
    if(U_SUCCESS(*status)) {
        g->current = ucol_nextWeight(g->ranges, &g->noOfRanges);
    }
    return g->current;
}

U_CFUNC uint32_t ucol_getSimpleCEGenerator(ucolCEGenerator *g, UColToken *tok, uint32_t strength, UErrorCode *status) {
    /* TODO: rename to enum names */
    uint32_t high, low, count=1;
    uint32_t maxByte = (strength == UCOL_TERTIARY)?0x3F:0xFF;

    if(strength == UCOL_SECONDARY) {
        low = UCOL_COMMON_TOP2<<24;
        high = 0xFFFFFFFF;
        count = 0xFF - UCOL_COMMON_TOP2;
    } else {
        low = UCOL_BYTE_COMMON << 24; //0x05000000;
        high = 0x40000000;
        count = 0x40 - UCOL_BYTE_COMMON;
    }

    if(tok->next != NULL && tok->next->strength == strength) {
        count = tok->next->toInsert;
    } 

    g->noOfRanges = ucol_allocWeights(low, high, count, maxByte, g->ranges);
    g->current = UCOL_BYTE_COMMON<<24;

    if(g->noOfRanges == 0) {
        *status = U_INTERNAL_PROGRAM_ERROR;
    }
    return g->current;
}

U_CFUNC uint32_t ucol_getCEGenerator(ucolCEGenerator *g, uint32_t* lows, uint32_t* highs, UColToken *tok, uint32_t fStrength, UErrorCode *status) {
    uint32_t strength = tok->strength;
    uint32_t low = lows[fStrength*3+strength];
    uint32_t high = highs[fStrength*3+strength];
    uint32_t maxByte = 0;
    if(strength == UCOL_TERTIARY) {
        maxByte = 0x3F;
    } else if(strength == UCOL_PRIMARY) {
        maxByte = 0xFE;
    } else {
        maxByte = 0xFF;
    }

    uint32_t count = tok->toInsert;

    if(low >= high && strength > UCOL_PRIMARY) {
        int32_t s = strength;
        for(;;) {
            s--;
            if(lows[fStrength*3+s] != highs[fStrength*3+s]) {
                if(strength == UCOL_SECONDARY) {
                    low = UCOL_COMMON_TOP2<<24;
                    high = 0xFFFFFFFF;
                } else {
                    //low = 0x02000000; // This needs to be checked - what if low is
                    // not good...
                    high = 0x40000000;
                }
                break;
            }
            if(s<0) {
                *status = U_INTERNAL_PROGRAM_ERROR;
                return 0;
            }
        }
    } 

    if(low == 0) {
        low = 0x01000000;
    }

    if(strength == UCOL_SECONDARY) { /* similar as simple */
        if(low >= (UCOL_COMMON_BOT2<<24) && low < (uint32_t)(UCOL_COMMON_TOP2<<24)) {
            low = UCOL_COMMON_TOP2<<24;
        }
        if(high > (UCOL_COMMON_BOT2<<24) && high < (uint32_t)(UCOL_COMMON_TOP2<<24)) {
            high = UCOL_COMMON_TOP2<<24;
        } 
        if(low < (UCOL_COMMON_BOT2<<24)) {
            g->noOfRanges = ucol_allocWeights(UCOL_BYTE_UNSHIFTED_MIN<<24, high, count, maxByte, g->ranges);
            g->current = ucol_nextWeight(g->ranges, &g->noOfRanges);
            //g->current = UCOL_COMMON_BOT2<<24;
            return g->current;
        }
    } 

    g->noOfRanges = ucol_allocWeights(low, high, count, maxByte, g->ranges);
    if(g->noOfRanges == 0) {
        *status = U_INTERNAL_PROGRAM_ERROR;
    }
    g->current = ucol_nextWeight(g->ranges, &g->noOfRanges);
    return g->current;
}

static
uint32_t u_toLargeKana(const UChar *source, const uint32_t sourceLen, UChar *resBuf, const uint32_t resLen, UErrorCode *status) {
    uint32_t i = 0; 
    UChar c;

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

    if(sourceLen > resLen) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return 0;
    }

    for(i = 0; i < sourceLen; i++) {
        c = source[i];
        if(0x3041 <= c && c <= 0x30FA) { /* Kana range */
            switch(c - 0x3000) {
            case 0x41: case 0x43: case 0x45: case 0x47: case 0x49: case 0x63: case 0x83: case 0x85: case 0x8E:
            case 0xA1: case 0xA3: case 0xA5: case 0xA7: case 0xA9: case 0xC3: case 0xE3: case 0xE5: case 0xEE:
                c++;
                break;
            case 0xF5:
                c = 0x30AB;
                break;
            case 0xF6:
                c = 0x30B1;
                break;
            }
        }
        resBuf[i] = c;
    }
    return sourceLen;
}

static
uint32_t u_toSmallKana(const UChar *source, const uint32_t sourceLen, UChar *resBuf, const uint32_t resLen, UErrorCode *status) {
    uint32_t i = 0; 
    UChar c;

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

    if(sourceLen > resLen) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return 0;
    }

    for(i = 0; i < sourceLen; i++) {
        c = source[i];
        if(0x3041 <= c && c <= 0x30FA) { /* Kana range */
            switch(c - 0x3000) {
            case 0x42: case 0x44: case 0x46: case 0x48: case 0x4A: case 0x64: case 0x84: case 0x86: case 0x8F:
            case 0xA2: case 0xA4: case 0xA6: case 0xA8: case 0xAA: case 0xC4: case 0xE4: case 0xE6: case 0xEF:
                c--;
                break;
            case 0xAB:
                c = 0x30F5;
                break;
            case 0xB1:
                c = 0x30F6;
                break;
            }
        }
        resBuf[i] = c;
    }
    return sourceLen;
}

static
uint8_t ucol_uprv_getCaseBits(const UCollator *UCA, const UChar *src, uint32_t len, UErrorCode *status) {
    uint32_t i = 0;
    UChar n[128];
    uint32_t nLen = 0;
    uint32_t uCount = 0, lCount = 0;

    collIterate s;
    uint32_t order = 0;

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

    nLen = unorm_normalize(src, len, UNORM_NFKD, 0, n, 128, status);
    if(U_SUCCESS(*status)) {
        for(i = 0; i < nLen; i++) {
            uprv_init_collIterate(UCA, &n[i], 1, &s);
            order = ucol_getNextCE(UCA, &s, status);
            if(isContinuation(order)) {
                *status = U_INTERNAL_PROGRAM_ERROR;
                return UCOL_LOWER_CASE;
            }
            if((order&UCOL_CASE_BIT_MASK)== UCOL_UPPER_CASE) {
                uCount++;
            } else {
                if(u_islower(n[i])) {
                    lCount++;
                } else {
                    UChar sk[1], lk[1];
                    u_toSmallKana(&n[i], 1, sk, 1, status);
                    u_toLargeKana(&n[i], 1, lk, 1, status);
                    if(sk[0] == n[i] && lk[0] != n[i]) {
                        lCount++;
                    }
                }
            }
        }
    }

    if(uCount != 0 && lCount != 0) {
        return UCOL_MIXED_CASE;
    } else if(uCount != 0) {
        return UCOL_UPPER_CASE;
    } else {
        return UCOL_LOWER_CASE;
    }
}


U_CFUNC void ucol_doCE(UColTokenParser *src, uint32_t *CEparts, UColToken *tok, UErrorCode *status) {
    /* this one makes the table and stuff */
    uint32_t noOfBytes[3];
    uint32_t i;

    for(i = 0; i<3; i++) {
        ucol_countBytes(CEparts[i], noOfBytes[i]);
    }

    /* Here we have to pack CEs from parts */

    uint32_t CEi = 0;
    uint32_t value = 0;

    while(2*CEi<noOfBytes[0] || CEi<noOfBytes[1] || CEi<noOfBytes[2]) {
        if(CEi > 0) {
            value = UCOL_CONTINUATION_MARKER; /* Continuation marker */
        } else {
            value = 0;
        }

        if(2*CEi<noOfBytes[0]) {
            value |= ((CEparts[0]>>(32-16*(CEi+1))) & 0xFFFF) << 16;
        }
        if(CEi<noOfBytes[1]) {
            value |= ((CEparts[1]>>(32-8*(CEi+1))) & 0xFF) << 8;
        }
        if(CEi<noOfBytes[2]) {
            value |= ((CEparts[2]>>(32-8*(CEi+1))) & 0x3F);
        }
        tok->CEs[CEi] = value;
        CEi++;
    }
    if(CEi == 0) { /* totally ignorable */
        tok->noOfCEs = 1;
        tok->CEs[0] = 0;
    } else { /* there is at least something */
        tok->noOfCEs = CEi;
    }


    // we want to set case bits here and now, not later.
    // Case bits handling 
    if(tok->CEs[0] != 0) { // case bits should be set only for non-ignorables
        tok->CEs[0] &= 0xFFFFFF3F; // Clean the case bits field
        int32_t cSize = (tok->source & 0xFF000000) >> 24;
        UChar *cPoints = (tok->source & 0x00FFFFFF) + src->source;

        if(cSize > 1) {
            // Do it manually
            tok->CEs[0] |= ucol_uprv_getCaseBits(src->UCA, cPoints, cSize, status);
        } else {
            // Copy it from the UCA
            uint32_t caseCE = ucol_getFirstCE(src->UCA, cPoints[0], status);
            tok->CEs[0] |= (caseCE & 0xC0);
        }
    }

#if UCOL_DEBUG==2
    fprintf(stderr, "%04X str: %i, [%08X, %08X, %08X]: tok: ", tok->debugSource, tok->strength, CEparts[0] >> (32-8*noOfBytes[0]), CEparts[1] >> (32-8*noOfBytes[1]), CEparts[2]>> (32-8*noOfBytes[2]));
    for(i = 0; i<tok->noOfCEs; i++) {
        fprintf(stderr, "%08X ", tok->CEs[i]);
    }
    fprintf(stderr, "\n");
#endif
}

U_CFUNC void ucol_initBuffers(UColTokenParser *src, UColTokListHeader *lh, UErrorCode *status) {
    ucolCEGenerator Gens[UCOL_CE_STRENGTH_LIMIT];
    uint32_t CEparts[UCOL_CE_STRENGTH_LIMIT];

    UColToken *tok = lh->last;
    uint32_t t[UCOL_STRENGTH_LIMIT];

    uprv_memset(t, 0, UCOL_STRENGTH_LIMIT*sizeof(uint32_t));

    tok->toInsert = 1;
    t[tok->strength] = 1;

    while(tok->previous != NULL) {
        if(tok->previous->strength < tok->strength) { /* going up */
            t[tok->strength] = 0;
            t[tok->previous->strength]++;
        } else if(tok->previous->strength > tok->strength) { /* going down */
            t[tok->previous->strength] = 1;
        } else {
            t[tok->strength]++;
        }
        tok=tok->previous;
        tok->toInsert = t[tok->strength];
    } 

    tok->toInsert = t[tok->strength];
    ucol_inv_getGapPositions(src, lh, status);

#if UCOL_DEBUG
    fprintf(stderr, "BaseCE: %08X %08X\n", lh->baseCE, lh->baseContCE);
    int32_t j = 2;
    for(j = 2; j >= 0; j--) {
        fprintf(stderr, "gapsLo[%i] [%08X %08X %08X]\n", j, lh->gapsLo[j*3], lh->gapsLo[j*3+1], lh->gapsLo[j*3+2]);
        fprintf(stderr, "gapsHi[%i] [%08X %08X %08X]\n", j, lh->gapsHi[j*3], lh->gapsHi[j*3+1], lh->gapsHi[j*3+2]);
    }
    tok=lh->first[UCOL_TOK_POLARITY_POSITIVE];

    do {
        fprintf(stderr,"%i", tok->strength);
        tok = tok->next;
    } while(tok != NULL);
    fprintf(stderr, "\n");

    tok=lh->first[UCOL_TOK_POLARITY_POSITIVE];

    do {  
        fprintf(stderr,"%i", tok->toInsert);
        tok = tok->next;
    } while(tok != NULL);
#endif

    tok = lh->first;
    uint32_t fStrength = UCOL_IDENTICAL;
    uint32_t initStrength = UCOL_IDENTICAL;


    CEparts[UCOL_PRIMARY] = (lh->baseCE & UCOL_PRIMARYMASK) | (lh->baseContCE & UCOL_PRIMARYMASK) >> 16;
    CEparts[UCOL_SECONDARY] = (lh->baseCE & UCOL_SECONDARYMASK) << 16 | (lh->baseContCE & UCOL_SECONDARYMASK) << 8;
    CEparts[UCOL_TERTIARY] = (UCOL_TERTIARYORDER(lh->baseCE)) << 24 | (UCOL_TERTIARYORDER(lh->baseContCE)) << 16;

    while (tok != NULL && U_SUCCESS(*status)) {
        fStrength = tok->strength;
        if(fStrength < initStrength) {
            initStrength = fStrength;
            if(lh->pos[fStrength] == -1) {
                while(lh->pos[fStrength] == -1 && fStrength > 0) {
                    fStrength--;
                }
                if(lh->pos[fStrength] == -1) {
                    *status = U_INTERNAL_PROGRAM_ERROR;
                    return;
                }
            }
            if(initStrength == UCOL_TERTIARY) { /* starting with tertiary */
                CEparts[UCOL_PRIMARY] = lh->gapsLo[fStrength*3];
                CEparts[UCOL_SECONDARY] = lh->gapsLo[fStrength*3+1];
                /*CEparts[UCOL_TERTIARY] = ucol_getCEGenerator(&Gens[2], lh->gapsLo[fStrength*3+2], lh->gapsHi[fStrength*3+2], tok, UCOL_TERTIARY); */
                CEparts[UCOL_TERTIARY] = ucol_getCEGenerator(&Gens[UCOL_TERTIARY], lh->gapsLo, lh->gapsHi, tok, fStrength, status); 
            } else if(initStrength == UCOL_SECONDARY) { /* secondaries */
                CEparts[UCOL_PRIMARY] = lh->gapsLo[fStrength*3];
                /*CEparts[1] = ucol_getCEGenerator(&Gens[1], lh->gapsLo[fStrength*3+1], lh->gapsHi[fStrength*3+1], tok, 1);*/
                CEparts[UCOL_SECONDARY] = ucol_getCEGenerator(&Gens[UCOL_SECONDARY], lh->gapsLo, lh->gapsHi, tok, fStrength,  status);
                CEparts[UCOL_TERTIARY] = ucol_getSimpleCEGenerator(&Gens[UCOL_TERTIARY], tok, UCOL_TERTIARY, status);
            } else { /* primaries */
                /*CEparts[UCOL_PRIMARY] = ucol_getCEGenerator(&Gens[0], lh->gapsLo[0], lh->gapsHi[0], tok, UCOL_PRIMARY);*/
                CEparts[UCOL_PRIMARY] = ucol_getCEGenerator(&Gens[UCOL_PRIMARY], lh->gapsLo, lh->gapsHi, tok, fStrength,  status);
                CEparts[UCOL_SECONDARY] = ucol_getSimpleCEGenerator(&Gens[UCOL_SECONDARY], tok, UCOL_SECONDARY, status);
                CEparts[UCOL_TERTIARY] = ucol_getSimpleCEGenerator(&Gens[UCOL_TERTIARY], tok, UCOL_TERTIARY, status);
            }
        } else {
            if(tok->strength == UCOL_TERTIARY) {
                CEparts[UCOL_TERTIARY] = ucol_getNextGenerated(&Gens[UCOL_TERTIARY], status);
            } else if(tok->strength == UCOL_SECONDARY) {
                CEparts[UCOL_SECONDARY] = ucol_getNextGenerated(&Gens[UCOL_SECONDARY], status);
                CEparts[UCOL_TERTIARY] = ucol_getSimpleCEGenerator(&Gens[UCOL_TERTIARY], tok, UCOL_TERTIARY, status);
            } else if(tok->strength == UCOL_PRIMARY) {
                CEparts[UCOL_PRIMARY] = ucol_getNextGenerated(&Gens[UCOL_PRIMARY], status);
                CEparts[UCOL_SECONDARY] = ucol_getSimpleCEGenerator(&Gens[UCOL_SECONDARY], tok, UCOL_SECONDARY, status);
                CEparts[UCOL_TERTIARY] = ucol_getSimpleCEGenerator(&Gens[UCOL_TERTIARY], tok, UCOL_TERTIARY, status);
            }
        }
        ucol_doCE(src, CEparts, tok, status);
        tok = tok->next;
    }
}

U_CFUNC void ucol_createElements(UColTokenParser *src, tempUCATable *t, UColTokListHeader *lh, UErrorCode *status) {
    UCAElements el;
    UColToken *tok = lh->first;
    UColToken *expt = NULL;
    uint32_t i = 0, j = 0;
    const uint16_t  *fcdTrieData = unorm_getFCDTrie(status);

    while(tok != NULL && U_SUCCESS(*status)) {
        /* first, check if there are any expansions */
        /* if there are expansions, we need to do a little bit more processing */
        /* since parts of expansion can be tailored, while others are not */
        if(tok->expansion != 0) {
            uint32_t len = tok->expansion >> 24;
            uint32_t currentSequenceLen = len;
            uint32_t expOffset = tok->expansion & 0x00FFFFFF;
            //uint32_t exp = currentSequenceLen | expOffset;
            UColToken exp;
            exp.source = currentSequenceLen | expOffset;
            exp.rulesToParse = src->source;

            while(len > 0) {
                currentSequenceLen = len;
                while(currentSequenceLen > 0) {
                    exp.source = (currentSequenceLen << 24) | expOffset;
                    if((expt = (UColToken *)uhash_get(src->tailored, &exp)) != NULL && expt->strength != UCOL_TOK_RESET) { /* expansion is tailored */
                        uint32_t noOfCEsToCopy = expt->noOfCEs;
                        for(j = 0; j<noOfCEsToCopy; j++) {
                            tok->expCEs[tok->noOfExpCEs + j] = expt->CEs[j];
                        }
                        tok->noOfExpCEs += noOfCEsToCopy;
                        // Smart people never try to add codepoints and CEs.
                        // For some odd reason, it won't work.
                        expOffset += currentSequenceLen; //noOfCEsToCopy;
                        len -= currentSequenceLen; //noOfCEsToCopy;
                        break;
                    } else {
                        currentSequenceLen--;
                    }
                }
                if(currentSequenceLen == 0) { /* couldn't find any tailored subsequence */
                    /* will have to get one from UCA */
                    /* first, get the UChars from the rules */
                    /* then pick CEs out until there is no more and stuff them into expansion */
                    collIterate s;
                    uint32_t order = 0;
                    uprv_init_collIterate(src->UCA, expOffset + src->source, 1, &s);

                    for(;;) {
                        order = ucol_getNextCE(src->UCA, &s, status);
                        if(order == UCOL_NO_MORE_CES) {
                            break;
                        }
                        tok->expCEs[tok->noOfExpCEs++] = order;
                    }
                    expOffset++;
                    len--;
                }
            }
        } else {
            tok->noOfExpCEs = 0;
        }

        /* set the ucaelement with obtained values */
        el.noOfCEs = tok->noOfCEs + tok->noOfExpCEs;
        /* copy CEs */
        for(i = 0; i<tok->noOfCEs; i++) {
            el.CEs[i] = tok->CEs[i];
        }
        for(i = 0; i<tok->noOfExpCEs; i++) {
            el.CEs[i+tok->noOfCEs] = tok->expCEs[i];
        }

        /* copy UChars */
        // We kept prefix and source kind of together, as it is a kind of a contraction. 
        // However, now we have to slice the prefix off the main thing - 
        el.prefix = el.prefixChars;
        el.cPoints = el.uchars;
        if(tok->prefix != 0) { // we will just copy the prefix here, and adjust accordingly in the
            // addPrefix function in ucol_elm. The reason is that we need to add both composed AND
            // decomposed elements to the unsaf table.
            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) {
            UBool containCombinMarks = FALSE;
            for(i = 0; i<el.cSize; i++) {
                if(UCOL_ISJAMO(el.cPoints[i])) {
                    t->image->jamoSpecial = TRUE;
                }
                if ( !src->buildCCTabFlag ) {
                    // check combining class
                    int16_t fcd = unorm_getFCD16(fcdTrieData, el.cPoints[i]);
                    if ( (fcd && 0xff) == 0 ) {
                        // reset flag when current char is not combining mark.
                        containCombinMarks = FALSE;  
                    }
                    else {
                        containCombinMarks = TRUE;
                    }
                }
            }
            if ( !src->buildCCTabFlag && containCombinMarks ) {
                src->buildCCTabFlag = TRUE;
            }
        }

        /* and then, add it */
#if UCOL_DEBUG==2
        fprintf(stderr, "Adding: %04X with %08X\n", el.cPoints[0], el.CEs[0]);
#endif
        uprv_uca_addAnElement(t, &el, status);

#if UCOL_DEBUG_DUPLICATES
        if(*status != U_ZERO_ERROR) {
            fprintf(stderr, "replaced CE for %04X with CE for %04X\n", el.cPoints[0], tok->debugSource);
            *status = U_ZERO_ERROR;
        }
#endif

        tok = tok->next;
    }
}

U_CDECL_BEGIN
static UBool U_CALLCONV
_processUCACompleteIgnorables(const void *context, UChar32 start, UChar32 limit, uint32_t value) {
    UErrorCode status = U_ZERO_ERROR;
    tempUCATable *t = (tempUCATable *)context;
    if(value == 0) {
        while(start < limit) {
            uint32_t CE = utrie_get32(t->mapping, start, NULL);
            if(CE == UCOL_NOT_FOUND) {
                UCAElements el;
                el.isThai = FALSE;
                el.prefixSize = 0;
                el.prefixChars[0] = 0;
                el.prefix = el.prefixChars;
                el.cPoints = el.uchars;

                el.cSize = 0;
                UTF_APPEND_CHAR(el.uchars, el.cSize, 1024, start);

                el.noOfCEs = 1;
                el.CEs[0] = 0;
                uprv_uca_addAnElement(t, &el, &status);

            }
            start++;
        }
    }
    if(U_FAILURE(status)) {
        return FALSE;
    } else {
        return TRUE;
    }
}
U_CDECL_END

static void 
ucol_uprv_bld_copyRangeFromUCA(UColTokenParser *src, tempUCATable *t,
                               UChar32 start, UChar32 end, 
                               UErrorCode *status)
{
    //UChar decomp[256];
    uint32_t CE = UCOL_NOT_FOUND;
    UChar32 u = 0;
    UCAElements el;
    el.isThai = FALSE;
    el.prefixSize = 0;
    el.prefixChars[0] = 0;
    collIterate colIt;

    if(U_SUCCESS(*status)) {
        for(u = start; u<=end; u++) {
            if((CE = utrie_get32(t->mapping, u, NULL)) == UCOL_NOT_FOUND 
                /* this test is for contractions that are missing the starting element. */
                || ((isCntTableElement(CE)) &&
                (uprv_cnttab_getCE(t->contractions, CE, 0, status) == UCOL_NOT_FOUND))
                ) {
                    el.cSize = 0;
                    U16_APPEND_UNSAFE(el.uchars, el.cSize, u); 
                    //decomp[0] = (UChar)u;
                    //el.uchars[0] = (UChar)u;
                    el.cPoints = el.uchars;
                    //el.cSize = 1;
                    el.noOfCEs = 0;
                    el.prefix = el.prefixChars;
                    el.prefixSize = 0;
                    //uprv_init_collIterate(src->UCA, decomp, 1, &colIt);
                    // We actually want to check whether this element is a special
                    // If it is an implicit element (hangul, CJK - we want to copy the
                    // special, not the resolved CEs) - for hangul, copying resolved
                    // would just make things the same (there is an expansion and it
                    // takes approximately the same amount of time to resolve as 
                    // falling back to the UCA).
                    /*
                    UTRIE_GET32(src->UCA->mapping, u, CE);
                    tag = getCETag(CE);
                    if(tag == HANGUL_SYLLABLE_TAG || tag == CJK_IMPLICIT_TAG 
                    || tag == IMPLICIT_TAG || tag == TRAIL_SURROGATE_TAG
                    || tag == LEAD_SURROGATE_TAG) {
                    el.CEs[el.noOfCEs++] = CE;
                    } else {
                    */
                    // It turns out that it does not make sense to keep implicits
                    // unresolved. The cost of resolving them is big enough so that
                    // it doesn't make any difference whether we have to go to the UCA
                    // or not.
                    {
                        uprv_init_collIterate(src->UCA, el.uchars, el.cSize, &colIt);
                        while(CE != UCOL_NO_MORE_CES) {
                            CE = ucol_getNextCE(src->UCA, &colIt, status);
                            if(CE != UCOL_NO_MORE_CES) {
                                el.CEs[el.noOfCEs++] = CE;
                            }
                        }
                    }
                    uprv_uca_addAnElement(t, &el, status);
                }
        }
    }
}

UCATableHeader *ucol_assembleTailoringTable(UColTokenParser *src, UErrorCode *status) {
    U_NAMESPACE_USE

    uint32_t i = 0;
    if(U_FAILURE(*status)) {
        return NULL;
    }
    /*
    2.  Eliminate the negative lists by doing the following for each non-null negative list: 
    o   if previousCE(baseCE, strongestN) != some ListHeader X's baseCE, 
    create new ListHeader X 
    o   reverse the list, add to the end of X's positive list. Reset the strength of the 
    first item you add, based on the stronger strength levels of the two lists. 
    */
    /*
    3.  For each ListHeader with a non-null positive list: 
    */
    /*
    o   Find all character strings with CEs between the baseCE and the 
    next/previous CE, at the strength of the first token. Add these to the 
    tailoring. 
    ? That is, if UCA has ...  x <<< X << x' <<< X' < y ..., and the 
    tailoring has & x < z... 
    ? Then we change the tailoring to & x  <<< X << x' <<< X' < z ... 
    */
    /* It is possible that this part should be done even while constructing list */
    /* The problem is that it is unknown what is going to be the strongest weight */
    /* So we might as well do it here */

    /*
    o   Allocate CEs for each token in the list, based on the total number N of the 
    largest level difference, and the gap G between baseCE and nextCE at that 
    level. The relation * between the last item and nextCE is the same as the 
    strongest strength. 
    o   Example: baseCE < a << b <<< q << c < d < e * nextCE(X,1) 
    ? There are 3 primary items: a, d, e. Fit them into the primary gap. 
    Then fit b and c into the secondary gap between a and d, then fit q 
    into the tertiary gap between b and c. 

    o   Example: baseCE << b <<< q << c * nextCE(X,2) 
    ? There are 2 secondary items: b, c. Fit them into the secondary gap. 
    Then fit q into the tertiary gap between b and c. 
    o   When incrementing primary values, we will not cross high byte 
    boundaries except where there is only a single-byte primary. That is to 
    ensure that the script reordering will continue to work. 
    */
    UCATableHeader *image = (UCATableHeader *)uprv_malloc(sizeof(UCATableHeader));
    /* test for NULL */
    if (image == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    uprv_memcpy(image, src->UCA->image, sizeof(UCATableHeader));

    for(i = 0; i<src->resultLen; i++) {
        /* now we need to generate the CEs */ 
        /* We stuff the initial value in the buffers, and increase the appropriate buffer */
        /* According to strength                                                          */
        if(U_SUCCESS(*status)) {
            if(src->lh[i].first) { // if there are any elements
                // due to the way parser works, subsequent tailorings
                // may remove all the elements from a sequence, therefore
                // leaving an empty tailoring sequence.
                ucol_initBuffers(src, &src->lh[i], status);
            }
        }
        if(U_FAILURE(*status)) {
            uprv_free(image);
            return NULL;
        }
    }

    if(src->varTop != NULL) { /* stuff the variable top value */
        src->opts->variableTopValue = (*(src->varTop->CEs))>>16;
        /* remove it from the list */
        if(src->varTop->listHeader->first == src->varTop) { /* first in list */
            src->varTop->listHeader->first = src->varTop->next;
        }
        if(src->varTop->listHeader->last == src->varTop) { /* first in list */
            src->varTop->listHeader->last = src->varTop->previous;    
        }
        if(src->varTop->next != NULL) {
            src->varTop->next->previous = src->varTop->previous;
        }
        if(src->varTop->previous != NULL) {
            src->varTop->previous->next = src->varTop->next;
        }
    }


    tempUCATable *t = uprv_uca_initTempTable(image, src->opts, src->UCA, NOT_FOUND_TAG, NOT_FOUND_TAG, status);
    if(U_FAILURE(*status)) {
        uprv_free(image);
        return NULL;
    }


    /* After this, we have assigned CE values to all regular CEs      */
    /* now we will go through list once more and resolve expansions,  */
    /* make UCAElements structs and add them to table                 */
    for(i = 0; i<src->resultLen; i++) {
        /* now we need to generate the CEs */ 
        /* We stuff the initial value in the buffers, and increase the appropriate buffer */
        /* According to strength                                                          */
        if(U_SUCCESS(*status)) {
            ucol_createElements(src, t, &src->lh[i], status);
        }
    }

    UCAElements el;
    el.isThai = FALSE;
    el.prefixSize = 0;
    el.prefixChars[0] = 0;

    /* add latin-1 stuff */
    ucol_uprv_bld_copyRangeFromUCA(src, t, 0, 0xFF, status);

    /* add stuff for copying */
    if(src->copySet != NULL) {
        int32_t i = 0;
        UnicodeSet *set = (UnicodeSet *)src->copySet;
        for(i = 0; i < set->getRangeCount(); i++) {
            ucol_uprv_bld_copyRangeFromUCA(src, t, set->getRangeStart(i), set->getRangeEnd(i), status);
        }
    }

    if(U_SUCCESS(*status)) {
        /* copy contractions from the UCA - this is felt mostly for cyrillic*/

        uint32_t tailoredCE = UCOL_NOT_FOUND;
        //UChar *conts = (UChar *)((uint8_t *)src->UCA->image + src->UCA->image->UCAConsts+sizeof(UCAConstants));
        UChar *conts = (UChar *)((uint8_t *)src->UCA->image + src->UCA->image->contractionUCACombos);
        UCollationElements *ucaEl = ucol_openElements(src->UCA, NULL, 0, status);
        while(*conts != 0) {
            /*tailoredCE = ucmpe32_get(t->mapping, *conts);*/
            tailoredCE = utrie_get32(t->mapping, *conts, NULL);
            if(tailoredCE != UCOL_NOT_FOUND) {         
                UBool needToAdd = TRUE;
                if(isCntTableElement(tailoredCE)) {
                    if(uprv_cnttab_isTailored(t->contractions, tailoredCE, conts+1, status) == TRUE) {
                        needToAdd = FALSE;
                    }
                }
                if(src->removeSet != NULL && uset_contains(src->removeSet, *conts)) {
                    needToAdd = FALSE;
                }

                if(needToAdd == TRUE) { // we need to add if this contraction is not tailored.
                    el.prefix = el.prefixChars;
                    el.prefixSize = 0;
                    el.cPoints = el.uchars;
                    el.noOfCEs = 0;
                    el.uchars[0] = *conts;
                    el.uchars[1] = *(conts+1);
                    if(*(conts+2)!=0) {
                        el.uchars[2] = *(conts+2);
                        el.cSize = 3;
                    } else {
                        el.cSize = 2;
                    }
                    ucol_setText(ucaEl, el.uchars, el.cSize, status);
                    while ((int32_t)(el.CEs[el.noOfCEs] = ucol_next(ucaEl, status)) != UCOL_NULLORDER) {
                        el.noOfCEs++;
                    }
                    uprv_uca_addAnElement(t, &el, status);
                }

            } else if(src->removeSet != NULL && uset_contains(src->removeSet, *conts)) {
                ucol_uprv_bld_copyRangeFromUCA(src, t, *conts, *conts, status);
            }
            conts+=3;
        }
        ucol_closeElements(ucaEl);
    }

    // Add completely ignorable elements
    utrie_enum(&t->UCA->mapping, NULL, _processUCACompleteIgnorables, t);

    // add tailoring characters related canonical closures
    uprv_uca_canonicalClosure(t, src, status);

    /* still need to produce compatibility closure */

    UCATableHeader *myData = uprv_uca_assembleTable(t, status);  

    uprv_uca_closeTempTable(t);    
    uprv_free(image);

    return myData;
}

U_CDECL_BEGIN
static UBool U_CALLCONV
ucol_bld_cleanup(void)
{
    udata_close(invUCA_DATA_MEM);
    invUCA_DATA_MEM = NULL;
    _staticInvUCA = NULL;
    return TRUE;
}
U_CDECL_END

U_CAPI const InverseUCATableHeader * U_EXPORT2
ucol_initInverseUCA(UErrorCode *status)
{
    if(U_FAILURE(*status)) return NULL;

    UBool needsInit;
    UMTX_CHECK(NULL, (_staticInvUCA == NULL), needsInit);

    if(needsInit) {
        InverseUCATableHeader *newInvUCA = NULL;
        UDataMemory *result = udata_openChoice(NULL, INVC_DATA_TYPE, INVC_DATA_NAME, isAcceptableInvUCA, NULL, status);

        if(U_FAILURE(*status)) {
            if (result) {
                udata_close(result);
            }
            // This is not needed, as we are talking about
            // memory we got from UData
            //uprv_free(newInvUCA);
        }

        if(result != NULL) { /* It looks like sometimes we can fail to find the data file */
            newInvUCA = (InverseUCATableHeader *)udata_getMemory(result);
            UCollator *UCA = ucol_initUCA(status);
            // UCA versions of UCA and inverse UCA should match
            if(uprv_memcmp(newInvUCA->UCAVersion, UCA->image->UCAVersion, sizeof(UVersionInfo)) != 0) {
                *status = U_INVALID_FORMAT_ERROR;
                udata_close(result);
                return NULL;
            }

            umtx_lock(NULL);
            if(_staticInvUCA == NULL) {
                _staticInvUCA = newInvUCA;
                invUCA_DATA_MEM = result;
                result = NULL;
                newInvUCA = NULL;
            }
            umtx_unlock(NULL);

            if(newInvUCA != NULL) {
                udata_close(result);
                // This is not needed, as we are talking about
                // memory we got from UData
                //uprv_free(newInvUCA);
            }
            else {
                ucln_i18n_registerCleanup(UCLN_I18N_UCOL_BLD, ucol_bld_cleanup);
            }
        }
    }
    return _staticInvUCA;
}

#endif /* #if !UCONFIG_NO_COLLATION */
