/**
*******************************************************************************
* Copyright (C) 2006, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*
*******************************************************************************
*/ 
package com.ibm.icu.charset;

import java.io.IOException;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;

import com.ibm.icu.impl.ICUData;
import com.ibm.icu.impl.ICUResourceBundle;

final class UConverterAlias {
    static final int UNNORMALIZED = 0;

    static final int STD_NORMALIZED = 1;

    static final int AMBIGUOUS_ALIAS_MAP_BIT = 0x8000;
    
    static final int CONTAINS_OPTION_BIT = 0x4000;

    static final int CONVERTER_INDEX_MASK = 0xFFF;

    static final int NUM_RESERVED_TAGS = 2;

    static final int NUM_HIDDEN_TAGS = 1;

    static int[] gConverterList = null;

    static int[] gTagList = null;

    static int[] gAliasList = null;

    static int[] gUntaggedConvArray = null;

    static int[] gTaggedAliasArray = null;

    static int[] gTaggedAliasLists = null;

    static int[] gOptionTable = null;

    static byte[] gStringTable = null;

    static byte[] gNormalizedStringTable = null;

    static final String GET_STRING(int idx) {
        return new String(gStringTable, 2 * idx, (int) strlen(gStringTable, 2 * idx));
    }

    private static final String GET_NORMALIZED_STRING(int idx) {
        return new String(gNormalizedStringTable, 2 * idx, (int) strlen(gNormalizedStringTable, 2 * idx));
    }

    public static final int strlen(byte[] sArray, int sBegin)
    {
        int i = sBegin;
        while(i < sArray.length && sArray[i++] != 0) {}
        return i - sBegin - 1;
    }

    /*private*/ static final int tocLengthIndex = 0;

    private static final int converterListIndex = 1;

    private static final int tagListIndex = 2;

    private static final int aliasListIndex = 3;

    private static final int untaggedConvArrayIndex = 4;

    private static final int taggedAliasArrayIndex = 5;

    private static final int taggedAliasListsIndex = 6;

    private static final int optionTableIndex = 7;

    private static final int stringTableIndex = 8;

    private static final int normalizedStringTableIndex = 9;

    private static final int minTocLength = 9; /*
                                                 * min. tocLength in the file,
                                                 * does not count the
                                                 * tocLengthIndex!
                                                 */

    private static final int offsetsCount = minTocLength + 1; /*
                                                                 * length of the
                                                                 * swapper's
                                                                 * temporary
                                                                 * offsets[]
                                                                 */

    static ByteBuffer gAliasData = null;

    private static final boolean isAlias(String alias) {
        if (alias == null) {
            throw new IllegalArgumentException("Alias param is null!");
        }
        return (alias.length() != 0);
    }

    private static final String CNVALIAS_DATA_FILE_NAME = ICUResourceBundle.ICU_BUNDLE + "/cnvalias.icu";

    /**
     * Default buffer size of datafile
     */
    private static final int CNVALIAS_DATA_BUFFER_SIZE = 25000;

    private static final synchronized boolean haveAliasData() 
                                               throws IOException{
        boolean needInit;

        // agljport:todo umtx_lock(NULL);
        needInit = gAliasData == null;

        /* load converter alias data from file if necessary */
        if (needInit) {
            ByteBuffer data = null;
            int[] tableArray = null;
            int tableStart;
            //byte[] reservedBytes = null;

            InputStream i = ICUData.getRequiredStream(CNVALIAS_DATA_FILE_NAME);
            BufferedInputStream b = new BufferedInputStream(i, CNVALIAS_DATA_BUFFER_SIZE);
            UConverterAliasDataReader reader = new UConverterAliasDataReader(b);
            tableArray = reader.readToc(offsetsCount);

            tableStart = tableArray[0];
            if (tableStart < minTocLength) {
                throw new IOException("Invalid data format.");
            }
            gConverterList = new int[(int)tableArray[converterListIndex]];
            gTagList= new int[(int)tableArray[tagListIndex]];
            gAliasList = new int[(int)tableArray[aliasListIndex]];
            gUntaggedConvArray = new int[(int)tableArray[untaggedConvArrayIndex]];
            gTaggedAliasArray = new int[(int)tableArray[taggedAliasArrayIndex]];
            gTaggedAliasLists = new int[(int)tableArray[taggedAliasListsIndex]];
            gOptionTable = new int[(int)tableArray[optionTableIndex]];
            gStringTable = new byte[(int)tableArray[stringTableIndex]*2];
            gNormalizedStringTable = new byte[(int)tableArray[normalizedStringTableIndex]*2];

            reader.read(gConverterList, gTagList,
                    gAliasList, gUntaggedConvArray,
                    gTaggedAliasArray, gTaggedAliasLists,
                    gOptionTable, gStringTable, gNormalizedStringTable);
            data =  ByteBuffer.allocate(0); // dummy UDataMemory object in absence
                                        // of memory mapping

            if (gOptionTable[0] != STD_NORMALIZED) {
                throw new IOException("Unsupported alias normalization");
            }
            
            // agljport:todo umtx_lock(NULL);
            if (gAliasData == null) {
                gAliasData = data;
                data = null;

                // agljport:fix ucln_common_registerCleanup(UCLN_COMMON_IO,
                // io_cleanup);
            }
            // agljport:todo umtx_unlock(NULL);

            /* if a different thread set it first, then close the extra data */
            if (data != null) {
                // agljport:fix udata_close(data); /* NULL if it was set
                // correctly */
            }
        }

        return true;
    }

    // U_CFUNC const char * io_getConverterName(const char *alias, UErrorCode
    // *pErrorCode)
    public static final String io_getConverterName(String alias)
                                    throws IOException{
        if (haveAliasData() && isAlias(alias)) {
            boolean[] isAmbigous = new boolean[1];
            int convNum = findConverter(alias, isAmbigous);
            if (convNum < gConverterList.length) {
                return GET_STRING(gConverterList[(int) convNum]);
            }
            /* else converter not found */
        }
        return null;
    }

    /*
     * search for an alias return the converter number index for gConverterList
     */
    // static U_INLINE uint32_t findConverter(const char *alias, UErrorCode
    // *pErrorCode)
    private static final int findConverter(String alias, boolean[] isAmbigous) {
        int mid, start, limit;
        int lastMid;
        int result;
        StringBuffer strippedName = new StringBuffer();
        String aliasToCompare;

        stripForCompare(strippedName, alias);
        alias = strippedName.toString();

        /* do a binary search for the alias */
        start = 0;
        limit = gUntaggedConvArray.length;
        mid = limit;
        lastMid = Integer.MAX_VALUE;

        for (;;) {
            mid = (start + limit) / 2;
            if (lastMid == mid) { /* Have we moved? */
                break; /* We haven't moved, and it wasn't found. */
            }
            lastMid = mid;
            aliasToCompare = GET_NORMALIZED_STRING(gAliasList[(int) mid]);
            result = alias.compareTo(aliasToCompare);

            if (result < 0) {
                limit = mid;
            } else if (result > 0) {
                start = mid;
            } else {
                /*
                 * Since the gencnval tool folds duplicates into one entry, this
                 * alias in gAliasList is unique, but different standards may
                 * map an alias to different converters.
                 */
                if ((gUntaggedConvArray[(int) mid] & AMBIGUOUS_ALIAS_MAP_BIT) != 0) {
                    isAmbigous[0]=true;
                }
                /* State whether the canonical converter name contains an option.
                This information is contained in this list in order to maintain backward & forward compatibility. */
                /*if (containsOption) {
                    UBool containsCnvOptionInfo = (UBool)gMainTable.optionTable->containsCnvOptionInfo;
                    *containsOption = (UBool)((containsCnvOptionInfo
                        && ((gMainTable.untaggedConvArray[mid] & UCNV_CONTAINS_OPTION_BIT) != 0))
                        || !containsCnvOptionInfo);
                }*/
                return gUntaggedConvArray[(int) mid] & CONVERTER_INDEX_MASK;
            }
        }
        return Integer.MAX_VALUE;
    }

    /**
     * stripForCompare Remove the underscores, dashes and spaces from
     * the name, and convert the name to lower case.
     * 
     * @param dst The destination buffer, which is <= the buffer of name.
     * @param name The alias to strip
     * @return the destination buffer.
     */
    public static final StringBuffer stripForCompare(StringBuffer dst, String name) {
        return io_stripASCIIForCompare(dst, name);
    }

    // enum {
    private static final byte IGNORE = 0;
    private static final byte ZERO = 1;
    private static final byte NONZERO = 2;
    static final byte MINLETTER = 3; /* any values from here on are lowercase letter mappings */
    // }
    
    /* character types for ASCII 00..7F */
    static final byte asciiTypes[] = new byte[] {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        ZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, 0, 0, 0, 0, 0, 0,
        0, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
        0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0,
        0, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
        0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0
    };

    private static final char GET_CHAR_TYPE(char c) {
        return (char)((c < asciiTypes.length) ? asciiTypes[c] : (char)IGNORE);
    }
    
    /** @see UConverterAlias#compareNames */
    private static final StringBuffer io_stripASCIIForCompare(StringBuffer dst, String name) {
        int nameIndex = 0;
        char type, nextType;
        char c1;
        boolean afterDigit = false;

        while (nameIndex < name.length()) {
            c1 = name.charAt(nameIndex++);
            type = GET_CHAR_TYPE(c1);
            switch (type) {
            case IGNORE:
                afterDigit = false;
                continue; /* ignore all but letters and digits */
            case ZERO:
                if (!afterDigit && nameIndex < name.length()) {
                    nextType = GET_CHAR_TYPE(name.charAt(nameIndex));
                    if (nextType == ZERO || nextType == NONZERO) {
                        continue; /* ignore leading zero before another digit */
                    }
                }
                break;
            case NONZERO:
                afterDigit = true;
                break;
            default:
                c1 = (char)type; /* lowercased letter */
                afterDigit = false;
                break;
            }
            dst.append(c1);
        }
        return dst;
    }

    /**
     * Do a fuzzy compare of a two converter/alias names. The comparison is
     * case-insensitive. It also ignores the characters '-', '_', and ' ' (dash,
     * underscore, and space). Thus the strings "UTF-8", "utf_8", and "Utf 8"
     * are exactly equivalent.
     * 
     * This is a symmetrical (commutative) operation; order of arguments is
     * insignificant. This is an important property for sorting the list (when
     * the list is preprocessed into binary form) and for performing binary
     * searches on it at run time.
     * 
     * @param name1
     *            a converter name or alias, zero-terminated
     * @param name2
     *            a converter name or alias, zero-terminated
     * @return 0 if the names match, or a negative value if the name1 lexically
     *         precedes name2, or a positive value if the name1 lexically
     *         follows name2.
     * 
     * @see UConverterAlias#stripForCompare
     */
    static int compareNames(String name1, String name2){
        int rc, name1Index = 0, name2Index = 0;
        char type, nextType;
        char c1 = 0, c2 = 0;
        boolean afterDigit1 = false, afterDigit2 = false;

        for (;;) {
            while (name1Index < name1.length()) {
                c1 = name1.charAt(name1Index++);
                type = GET_CHAR_TYPE(c1);
                switch (type) {
                case IGNORE:
                    afterDigit1 = false;
                    continue; /* ignore all but letters and digits */
                case ZERO:
                    if (!afterDigit1 && name1Index < name1.length()) {
                        nextType = GET_CHAR_TYPE(name1.charAt(name1Index));
                        if (nextType == ZERO || nextType == NONZERO) {
                            continue; /* ignore leading zero before another digit */
                        }
                    }
                    break;
                case NONZERO:
                    afterDigit1 = true;
                    break;
                default:
                    c1 = (char)type; /* lowercased letter */
                    afterDigit1 = false;
                    break;
                }
                break; /* deliver c1 */
            }
            while (name2Index < name2.length()) {
                c2 = name2.charAt(name2Index++);
                type = GET_CHAR_TYPE(c2);
                switch (type) {
                case IGNORE:
                    afterDigit2 = false;
                    continue; /* ignore all but letters and digits */
                case ZERO:
                    if (!afterDigit2 && name1Index < name1.length()) {
                        nextType = GET_CHAR_TYPE(name2.charAt(name2Index));
                        if (nextType == ZERO || nextType == NONZERO) {
                            continue; /* ignore leading zero before another digit */
                        }
                    }
                    break;
                case NONZERO:
                    afterDigit2 = true;
                    break;
                default:
                    c2 = (char)type; /* lowercased letter */
                    afterDigit2 = false;
                    break;
                }
                break; /* deliver c2 */
            }

            /* If we reach the ends of both strings then they match */
            if (name1Index >= name1.length() && name2Index >= name2.length()) {
                return 0;
            }

            /* Case-insensitive comparison */
            rc = (int)c1 - (int)c2;
            if (rc != 0) {
                return rc;
            }
        }
    }

    static int io_countAliases(String alias) 
                        throws IOException{
        if (haveAliasData() && isAlias(alias)) {
            boolean[] isAmbigous = new boolean[1];
            int convNum = findConverter(alias, isAmbigous);
            if (convNum < gConverterList.length) {
                /* tagListNum - 1 is the ALL tag */
                int listOffset = gTaggedAliasArray[(int) ((gTagList.length - 1)
                        * gConverterList.length + convNum)];

                if (listOffset != 0) {
                    return gTaggedAliasLists[listOffset];
                }
                /* else this shouldn't happen. internal program error */
            }
            /* else converter not found */
        }
        return 0;
    }

    /**
     * Return the number of all aliases (and converter names).
     * 
     * @return the number of all aliases
     */
    // U_CFUNC uint16_t io_countTotalAliases(UErrorCode *pErrorCode);
    static int io_countTotalAliases() throws IOException{
        if (haveAliasData()) {
            return (int) gAliasList.length;
        }
        return 0;
    }

    // U_CFUNC const char * io_getAlias(const char *alias, uint16_t n,
    // UErrorCode *pErrorCode)
    static String io_getAlias(String alias, int n) throws IOException{
        if (haveAliasData() && isAlias(alias)) {
            boolean[] isAmbigous = new boolean[1];
            int convNum = findConverter(alias,isAmbigous);
            if (convNum < gConverterList.length) {
                /* tagListNum - 1 is the ALL tag */
                int listOffset = gTaggedAliasArray[(int) ((gTagList.length - 1)
                        * gConverterList.length + convNum)];

                if (listOffset != 0) {
                    //int listCount = gTaggedAliasListsArray[listOffset];
                    /* +1 to skip listCount */
                    int[] currListArray = gTaggedAliasLists;
                    int currListArrayIndex = listOffset + 1;

                    return GET_STRING(currListArray[currListArrayIndex + n]);
                    
                }
                /* else this shouldn't happen. internal program error */
            }
            /* else converter not found */
        }
        return null;
    }

    // U_CFUNC uint16_t io_countStandards(UErrorCode *pErrorCode) {
    static int io_countStandards() throws IOException{
        if (haveAliasData()) {
            return (int) (gTagList.length - NUM_HIDDEN_TAGS);
        }
        return 0;
    }

    // U_CAPI const char * U_EXPORT2getStandard(uint16_t n, UErrorCode
    // *pErrorCode)
    static String getStandard(int n) throws IOException{
        if (haveAliasData()) {
            return GET_STRING(gTagList[n]);
        }
        return null;
    }

    // U_CAPI const char * U_EXPORT2 getStandardName(const char *alias, const
    // char *standard, UErrorCode *pErrorCode)
    static final String getStandardName(String alias, String standard)throws IOException {
        if (haveAliasData() && isAlias(alias)) {
            int listOffset = findTaggedAliasListsOffset(alias, standard);

            if (0 < listOffset && listOffset < gTaggedAliasLists.length) {
                int[] currListArray = gTaggedAliasLists;
                int currListArrayIndex = listOffset + 1;
                if (currListArray[0] != 0) {
                    return GET_STRING(currListArray[(int) currListArrayIndex]);
                }
            }
        }
        return null;
    }

    // U_CAPI uint16_t U_EXPORT2 countAliases(const char *alias, UErrorCode
    // *pErrorCode)
    static int countAliases(String alias) throws IOException{
        return io_countAliases(alias);
    }

    // U_CAPI const char* U_EXPORT2 getAlias(const char *alias, uint16_t n,
    // UErrorCode *pErrorCode)
    static String getAlias(String alias, int n) throws IOException{
        return io_getAlias(alias, n);
    }

    // U_CFUNC uint16_t countStandards(void)
    static int countStandards()throws IOException{
        return io_countStandards();
    }
    
    /*returns a single Name from the list, will return NULL if out of bounds
     */
    static String getAvailableName (int n){
        try{
          if (0 <= n && n <= 0xffff) {
            String name = bld_getAvailableConverter(n);
            return name;
          }
        }catch(IOException ex){
            //throw away exception
        }
        return null;
    }
    // U_CAPI const char * U_EXPORT2 getCanonicalName(const char *alias, const
    // char *standard, UErrorCode *pErrorCode) {
    static String getCanonicalName(String alias, String standard) throws IOException{
        if (haveAliasData() && isAlias(alias)) {
            int convNum = findTaggedConverterNum(alias, standard);

            if (convNum < gConverterList.length) {
                return GET_STRING(gConverterList[(int) convNum]);
            }
        }

        return null;
    }
    static int countAvailable (){
        try{
            return bld_countAvailableConverters();
        }catch(IOException ex){
            //throw away exception
        }
        return -1;
    }
        
    // U_CAPI UEnumeration * U_EXPORT2 openStandardNames(const char *convName,
    // const char *standard, UErrorCode *pErrorCode)
/*    static final UConverterAliasesEnumeration openStandardNames(String convName, String standard)throws IOException {
        UConverterAliasesEnumeration aliasEnum = null;
        if (haveAliasData() && isAlias(convName)) {
            int listOffset = findTaggedAliasListsOffset(convName, standard);

            
             * When listOffset == 0, we want to acknowledge that the converter
             * name and standard are okay, but there is nothing to enumerate.
             
            if (listOffset < gTaggedAliasLists.length) {

                UConverterAliasesEnumeration.UAliasContext context = new UConverterAliasesEnumeration.UAliasContext(listOffset, 0);
                aliasEnum = new UConverterAliasesEnumeration();
                aliasEnum.setContext(context);
            }
             else converter or tag not found 
        }
        return aliasEnum;
    }*/

    // static uint32_t getTagNumber(const char *tagname)
    private static int getTagNumber(String tagName) {
        if (gTagList != null) {
            int tagNum;
            for (tagNum = 0; tagNum < gTagList.length; tagNum++) {
                if (tagName.equals(GET_STRING(gTagList[(int) tagNum]))) {
                    return tagNum;
                }
            }
        }

        return Integer.MAX_VALUE;
    }

    // static uint32_t findTaggedAliasListsOffset(const char *alias, const char
    // *standard, UErrorCode *pErrorCode)
    private static int findTaggedAliasListsOffset(String alias, String standard) {
        int idx;
        int listOffset;
        int convNum;
        int tagNum = getTagNumber(standard);
        boolean[] isAmbigous = new boolean[1];
        /* Make a quick guess. Hopefully they used a TR22 canonical alias. */
        convNum = findConverter(alias, isAmbigous);

        if (tagNum < (gTagList.length - NUM_HIDDEN_TAGS)
                && convNum < gConverterList.length) {
            listOffset = gTaggedAliasArray[(int) (tagNum
                    * gConverterList.length + convNum)];
            if (listOffset != 0
                    && gTaggedAliasLists[(int) listOffset + 1] != 0) {
                return listOffset;
            }
            if (isAmbigous[0]==true) {
                /*
                 * Uh Oh! They used an ambiguous alias. We have to search the
                 * whole swiss cheese starting at the highest standard affinity.
                 * This may take a while.
                 */

                for (idx = 0; idx < gTaggedAliasArray.length; idx++) {
                    listOffset = gTaggedAliasArray[(int) idx];
                    if (listOffset != 0 && isAliasInList(alias, listOffset)) {
                        int currTagNum = idx / gConverterList.length;
                        int currConvNum = (idx - currTagNum
                                * gConverterList.length);
                        int tempListOffset = gTaggedAliasArray[(int) (tagNum
                                * gConverterList.length + currConvNum)];
                        if (tempListOffset != 0
                                && gTaggedAliasLists[(int) tempListOffset + 1] != 0) {
                            return tempListOffset;
                        }
                        /*
                         * else keep on looking We could speed this up by
                         * starting on the next row because an alias is unique
                         * per row, right now. This would change if alias
                         * versioning appears.
                         */
                    }
                }
                /* The standard doesn't know about the alias */
            }
            /* else no default name */
            return 0;
        }
        /* else converter or tag not found */

        return Integer.MAX_VALUE;
    }

    /* Return the canonical name */
    // static uint32_t findTaggedConverterNum(const char *alias, const char
    // *standard, UErrorCode *pErrorCode)
    private static int findTaggedConverterNum(String alias, String standard) {
        int idx;
        int listOffset;
        int convNum;
        int tagNum = getTagNumber(standard);
        boolean[] isAmbigous = new boolean[1];
        
        /* Make a quick guess. Hopefully they used a TR22 canonical alias. */
        convNum = findConverter(alias, isAmbigous);        

        if (tagNum < (gTagList.length - NUM_HIDDEN_TAGS)
                && convNum < gConverterList.length) {
            listOffset = gTaggedAliasArray[(int) (tagNum
                    * gConverterList.length + convNum)];
            if (listOffset != 0 && isAliasInList(alias, listOffset)) {
                return convNum;
            }
            if (isAmbigous[0] == true) {
                /*
                 * Uh Oh! They used an ambiguous alias. We have to search one
                 * slice of the swiss cheese. We search only in the requested
                 * tag, not the whole thing. This may take a while.
                 */
                int convStart = (tagNum) * gConverterList.length;
                int convLimit = (tagNum + 1) * gConverterList.length;
                for (idx = convStart; idx < convLimit; idx++) {
                    listOffset = gTaggedAliasArray[(int) idx];
                    if (listOffset != 0 && isAliasInList(alias, listOffset)) {
                        return idx - convStart;
                    }
                }
                /* The standard doesn't know about the alias */
            }
            /* else no canonical name */
        }
        /* else converter or tag not found */

        return Integer.MAX_VALUE;
    }

    // static U_INLINE UBool isAliasInList(const char *alias, uint32_t
    // listOffset)
    private static boolean isAliasInList(String alias, int listOffset) {
        if (listOffset != 0) {
            int currAlias;
            int listCount = gTaggedAliasLists[(int) listOffset];
            /* +1 to skip listCount */
            int[] currList = gTaggedAliasLists;
            int currListArrayIndex = listOffset + 1;
            for (currAlias = 0; currAlias < listCount; currAlias++) {
                if (currList[(int) (currAlias + currListArrayIndex)] != 0
                        && compareNames(
                                alias,
                                GET_STRING(currList[(int) (currAlias + currListArrayIndex)])) == 0) {
                    return true;
                }
            }
        }
        return false;
    }

    // begin bld.c
    static String[] gAvailableConverters = null;

    static int gAvailableConverterCount = 0;

    static byte[] gDefaultConverterNameBuffer; // [MAX_CONVERTER_NAME_LENGTH +
                                                // 1]; /* +1 for NULL */

    static String gDefaultConverterName = null;

    // static UBool haveAvailableConverterList(UErrorCode *pErrorCode)
    static boolean haveAvailableConverterList() throws IOException{
        if (gAvailableConverters == null) {
            int idx;
            int localConverterCount;
            String converterName;
            String[] localConverterList;

            if (!haveAliasData()) {
                return false;
            }

            /* We can't have more than "*converterTable" converters to open */
            localConverterList = new String[(int) gConverterList.length];

            localConverterCount = 0;

            for (idx = 0; idx < gConverterList.length; idx++) {
                converterName = GET_STRING(gConverterList[idx]);
                //UConverter cnv = UConverter.open(converterName);
                //TODO: Fix me
                localConverterList[localConverterCount++] = converterName;
                
            }

            // agljport:todo umtx_lock(NULL);
            if (gAvailableConverters == null) {
                gAvailableConverters = localConverterList;
                gAvailableConverterCount = localConverterCount;
                /* haveData should have already registered the cleanup function */
            } else {
                // agljport:todo free((char **)localConverterList);
            }
            // agljport:todo umtx_unlock(NULL);
        }
        return true;
    }

    // U_CFUNC uint16_t bld_countAvailableConverters(UErrorCode *pErrorCode)
    static int bld_countAvailableConverters() throws IOException{
        if (haveAvailableConverterList()) {
            return gAvailableConverterCount;
        }
        return 0;
    }

    // U_CFUNC const char * bld_getAvailableConverter(uint16_t n, UErrorCode
    // *pErrorCode)
    static String bld_getAvailableConverter(int n) throws IOException{
        if (haveAvailableConverterList()) {
            if (n < gAvailableConverterCount) {
                return gAvailableConverters[n];
            }
        }
        return null;
    }

    /* default converter name --------------------------------------------------- */

    /*
     * In order to be really thread-safe, the get function would have to take
     * a buffer parameter and copy the current string inside a mutex block.
     * This implementation only tries to be really thread-safe while
     * setting the name.
     * It assumes that setting a pointer is atomic.
     */

    // U_CFUNC const char * getDefaultName()
    static final synchronized String getDefaultName() {
        /* local variable to be thread-safe */
        String name;

        //agljport:todo umtx_lock(null);
        name = gDefaultConverterName;
        //agljport:todo umtx_unlock(null);

        if (name == null) {
            //UConverter cnv = null;
            int length = 0;

            name = CharsetICU.getDefaultCharsetName();

            /* if the name is there, test it out and get the canonical name with options */
            if (name != null) {
               // cnv = UConverter.open(name); 
               // name = cnv.getName(cnv);
                // TODO: fix me
            }

            if (name == null || name.length() == 0 ||/* cnv == null ||*/
                     length >= gDefaultConverterNameBuffer.length) {
                /* Panic time, let's use a fallback. */
                name = new String("US-ASCII");
            }

            //length=(int32_t)(strlen(name));

            /* Copy the name before we close the converter. */
            name = gDefaultConverterName;
        }

        return name;
    }

    //end bld.c
}