// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
* Copyright (C) 2011-2016, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*
* File TZNAMES_IMPL.CPP
*
*******************************************************************************
*/

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/strenum.h"
#include "unicode/ustring.h"
#include "unicode/timezone.h"
#include "unicode/utf16.h"

#include "tznames_impl.h"
#include "bytesinkutil.h"
#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "uassert.h"
#include "mutex.h"
#include "resource.h"
#include "ulocimp.h"
#include "uresimp.h"
#include "ureslocs.h"
#include "zonemeta.h"
#include "ucln_in.h"
#include "uvector.h"
#include "olsontz.h"

U_NAMESPACE_BEGIN

#define ZID_KEY_MAX  128
#define MZ_PREFIX_LEN 5

static const char gZoneStrings[]        = "zoneStrings";
static const char gMZPrefix[]           = "meta:";

static const char EMPTY[]               = "<empty>";   // place holder for empty ZNames
static const char DUMMY_LOADER[]        = "<dummy>";   // place holder for dummy ZNamesLoader
static const UChar NO_NAME[]            = { 0 };   // for empty no-fallback time zone names

// stuff for TZDBTimeZoneNames
static const char* TZDBNAMES_KEYS[]               = {"ss", "sd"};
static const int32_t TZDBNAMES_KEYS_SIZE = UPRV_LENGTHOF(TZDBNAMES_KEYS);

static UMutex gDataMutex;

static UHashtable* gTZDBNamesMap = NULL;
static icu::UInitOnce gTZDBNamesMapInitOnce {};

static TextTrieMap* gTZDBNamesTrie = NULL;
static icu::UInitOnce gTZDBNamesTrieInitOnce {};

// The order in which strings are stored may be different than the order in the public enum.
enum UTimeZoneNameTypeIndex {
    UTZNM_INDEX_UNKNOWN = -1,
    UTZNM_INDEX_EXEMPLAR_LOCATION,
    UTZNM_INDEX_LONG_GENERIC,
    UTZNM_INDEX_LONG_STANDARD,
    UTZNM_INDEX_LONG_DAYLIGHT,
    UTZNM_INDEX_SHORT_GENERIC,
    UTZNM_INDEX_SHORT_STANDARD,
    UTZNM_INDEX_SHORT_DAYLIGHT,
    UTZNM_INDEX_COUNT
};
static const UChar* const EMPTY_NAMES[UTZNM_INDEX_COUNT] = {0,0,0,0,0,0,0};

U_CDECL_BEGIN
static UBool U_CALLCONV tzdbTimeZoneNames_cleanup(void) {
    if (gTZDBNamesMap != NULL) {
        uhash_close(gTZDBNamesMap);
        gTZDBNamesMap = NULL;
    }
    gTZDBNamesMapInitOnce.reset();

    if (gTZDBNamesTrie != NULL) {
        delete gTZDBNamesTrie;
        gTZDBNamesTrie = NULL;
    }
    gTZDBNamesTrieInitOnce.reset();

    return TRUE;
}
U_CDECL_END

/**
 * ZNameInfo stores zone name information in the trie
 */
struct ZNameInfo {
    UTimeZoneNameType   type;
    const UChar*        tzID;
    const UChar*        mzID;
};

/**
 * ZMatchInfo stores zone name match information used by find method
 */
struct ZMatchInfo {
    const ZNameInfo*    znameInfo;
    int32_t             matchLength;
};

// Helper functions
static void mergeTimeZoneKey(const UnicodeString& mzID, char* result);

#define DEFAULT_CHARACTERNODE_CAPACITY 1

// ---------------------------------------------------
// CharacterNode class implementation
// ---------------------------------------------------
void CharacterNode::clear() {
    uprv_memset(this, 0, sizeof(*this));
}

void CharacterNode::deleteValues(UObjectDeleter *valueDeleter) {
    if (fValues == NULL) {
        // Do nothing.
    } else if (!fHasValuesVector) {
        if (valueDeleter) {
            valueDeleter(fValues);
        }
    } else {
        delete (UVector *)fValues;
    }
}

void
CharacterNode::addValue(void *value, UObjectDeleter *valueDeleter, UErrorCode &status) {
    if (U_FAILURE(status)) {
        if (valueDeleter) {
            valueDeleter(value);
        }
        return;
    }
    if (fValues == NULL) {
        fValues = value;
    } else {
        // At least one value already.
        if (!fHasValuesVector) {
            // There is only one value so far, and not in a vector yet.
            // Create a vector and add the old value.
            LocalPointer<UVector> values(
                new UVector(valueDeleter, NULL, DEFAULT_CHARACTERNODE_CAPACITY, status), status);
            if (U_FAILURE(status)) {
                if (valueDeleter) {
                    valueDeleter(value);
                }
                return;
            }
            if (values->hasDeleter()) {
                values->adoptElement(fValues, status);
            } else {
                values->addElement(fValues, status);
            }
            fValues = values.orphan();
            fHasValuesVector = TRUE;
        }
        // Add the new value.
        UVector *values = (UVector *)fValues;
        if (values->hasDeleter()) {
            values->adoptElement(value, status);
        } else {
            values->addElement(value, status);
        }
    }
}

// ---------------------------------------------------
// TextTrieMapSearchResultHandler class implementation
// ---------------------------------------------------
TextTrieMapSearchResultHandler::~TextTrieMapSearchResultHandler(){
}

// ---------------------------------------------------
// TextTrieMap class implementation
// ---------------------------------------------------
TextTrieMap::TextTrieMap(UBool ignoreCase, UObjectDeleter *valueDeleter)
: fIgnoreCase(ignoreCase), fNodes(NULL), fNodesCapacity(0), fNodesCount(0), 
  fLazyContents(NULL), fIsEmpty(TRUE), fValueDeleter(valueDeleter) {
}

TextTrieMap::~TextTrieMap() {
    int32_t index;
    for (index = 0; index < fNodesCount; ++index) {
        fNodes[index].deleteValues(fValueDeleter);
    }
    uprv_free(fNodes);
    if (fLazyContents != NULL) {
        for (int32_t i=0; i<fLazyContents->size(); i+=2) {
            if (fValueDeleter) {
                fValueDeleter(fLazyContents->elementAt(i+1));
            }
        } 
        delete fLazyContents;
    }
}

int32_t TextTrieMap::isEmpty() const {
    // Use a separate field for fIsEmpty because it will remain unchanged once the
    //   Trie is built, while fNodes and fLazyContents change with the lazy init
    //   of the nodes structure.  Trying to test the changing fields has
    //   thread safety complications.
    return fIsEmpty;
}


//  We defer actually building the TextTrieMap node structure until the first time a
//     search is performed.  put() simply saves the parameters in case we do
//     eventually need to build it.
//     
void
TextTrieMap::put(const UnicodeString &key, void *value, ZNStringPool &sp, UErrorCode &status) {
    const UChar *s = sp.get(key, status);
    put(s, value, status);
}

// This method is designed for a persistent key, such as string key stored in
// resource bundle.
void
TextTrieMap::put(const UChar *key, void *value, UErrorCode &status) {
    fIsEmpty = FALSE;
    if (fLazyContents == NULL) {
        LocalPointer<UVector> lpLazyContents(new UVector(status), status);
        fLazyContents = lpLazyContents.orphan();
    }
    if (U_FAILURE(status)) {
        if (fValueDeleter) {
            fValueDeleter((void*) key);
        }
        return;
    }
    U_ASSERT(fLazyContents != NULL);

    UChar *s = const_cast<UChar *>(key);
    fLazyContents->addElement(s, status);
    if (U_FAILURE(status)) {
        if (fValueDeleter) {
            fValueDeleter((void*) key);
        }
        return;
    }

    fLazyContents->addElement(value, status);
}

void
TextTrieMap::putImpl(const UnicodeString &key, void *value, UErrorCode &status) {
    if (fNodes == NULL) {
        fNodesCapacity = 512;
        fNodes = (CharacterNode *)uprv_malloc(fNodesCapacity * sizeof(CharacterNode));
        if (fNodes == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        fNodes[0].clear();  // Init root node.
        fNodesCount = 1;
    }

    UnicodeString foldedKey;
    const UChar *keyBuffer;
    int32_t keyLength;
    if (fIgnoreCase) {
        // Ok to use fastCopyFrom() because we discard the copy when we return.
        foldedKey.fastCopyFrom(key).foldCase();
        keyBuffer = foldedKey.getBuffer();
        keyLength = foldedKey.length();
    } else {
        keyBuffer = key.getBuffer();
        keyLength = key.length();
    }

    CharacterNode *node = fNodes;
    int32_t index;
    for (index = 0; index < keyLength; ++index) {
        node = addChildNode(node, keyBuffer[index], status);
    }
    node->addValue(value, fValueDeleter, status);
}

UBool
TextTrieMap::growNodes() {
    if (fNodesCapacity == 0xffff) {
        return FALSE;  // We use 16-bit node indexes.
    }
    int32_t newCapacity = fNodesCapacity + 1000;
    if (newCapacity > 0xffff) {
        newCapacity = 0xffff;
    }
    CharacterNode *newNodes = (CharacterNode *)uprv_malloc(newCapacity * sizeof(CharacterNode));
    if (newNodes == NULL) {
        return FALSE;
    }
    uprv_memcpy(newNodes, fNodes, fNodesCount * sizeof(CharacterNode));
    uprv_free(fNodes);
    fNodes = newNodes;
    fNodesCapacity = newCapacity;
    return TRUE;
}

CharacterNode*
TextTrieMap::addChildNode(CharacterNode *parent, UChar c, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    // Linear search of the sorted list of children.
    uint16_t prevIndex = 0;
    uint16_t nodeIndex = parent->fFirstChild;
    while (nodeIndex > 0) {
        CharacterNode *current = fNodes + nodeIndex;
        UChar childCharacter = current->fCharacter;
        if (childCharacter == c) {
            return current;
        } else if (childCharacter > c) {
            break;
        }
        prevIndex = nodeIndex;
        nodeIndex = current->fNextSibling;
    }

    // Ensure capacity. Grow fNodes[] if needed.
    if (fNodesCount == fNodesCapacity) {
        int32_t parentIndex = (int32_t)(parent - fNodes);
        if (!growNodes()) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return NULL;
        }
        parent = fNodes + parentIndex;
    }

    // Insert a new child node with c in sorted order.
    CharacterNode *node = fNodes + fNodesCount;
    node->clear();
    node->fCharacter = c;
    node->fNextSibling = nodeIndex;
    if (prevIndex == 0) {
        parent->fFirstChild = (uint16_t)fNodesCount;
    } else {
        fNodes[prevIndex].fNextSibling = (uint16_t)fNodesCount;
    }
    ++fNodesCount;
    return node;
}

CharacterNode*
TextTrieMap::getChildNode(CharacterNode *parent, UChar c) const {
    // Linear search of the sorted list of children.
    uint16_t nodeIndex = parent->fFirstChild;
    while (nodeIndex > 0) {
        CharacterNode *current = fNodes + nodeIndex;
        UChar childCharacter = current->fCharacter;
        if (childCharacter == c) {
            return current;
        } else if (childCharacter > c) {
            break;
        }
        nodeIndex = current->fNextSibling;
    }
    return NULL;
}


// buildTrie() - The Trie node structure is needed.  Create it from the data that was
//               saved at the time the ZoneStringFormatter was created.  The Trie is only
//               needed for parsing operations, which are less common than formatting,
//               and the Trie is big, which is why its creation is deferred until first use.
void TextTrieMap::buildTrie(UErrorCode &status) {
    if (fLazyContents != NULL) {
        for (int32_t i=0; i<fLazyContents->size(); i+=2) {
            const UChar *key = (UChar *)fLazyContents->elementAt(i);
            void  *val = fLazyContents->elementAt(i+1);
            UnicodeString keyString(TRUE, key, -1);  // Aliasing UnicodeString constructor.
            putImpl(keyString, val, status);
        }
        delete fLazyContents;
        fLazyContents = NULL; 
    }
}

void
TextTrieMap::search(const UnicodeString &text, int32_t start,
                  TextTrieMapSearchResultHandler *handler, UErrorCode &status) const {
    {
        // TODO: if locking the mutex for each check proves to be a performance problem,
        //       add a flag of type atomic_int32_t to class TextTrieMap, and use only
        //       the ICU atomic safe functions for assigning and testing.
        //       Don't test the pointer fLazyContents.
        //       Don't do unless it's really required.

        // Mutex for protecting the lazy creation of the Trie node structure on the first call to search().
        static UMutex TextTrieMutex;

        Mutex lock(&TextTrieMutex);
        if (fLazyContents != NULL) {
            TextTrieMap *nonConstThis = const_cast<TextTrieMap *>(this);
            nonConstThis->buildTrie(status);
        }
    }
    if (fNodes == NULL) {
        return;
    }
    search(fNodes, text, start, start, handler, status);
}

void
TextTrieMap::search(CharacterNode *node, const UnicodeString &text, int32_t start,
                  int32_t index, TextTrieMapSearchResultHandler *handler, UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return;
    }
    if (node->hasValues()) {
        if (!handler->handleMatch(index - start, node, status)) {
            return;
        }
        if (U_FAILURE(status)) {
            return;
        }
    }
    if (fIgnoreCase) {
        // for folding we need to get a complete code point.
        // size of character may grow after fold operation;
        // then we need to get result as UTF16 code units.
        UChar32 c32 = text.char32At(index);
        index += U16_LENGTH(c32);
        UnicodeString tmp(c32);
        tmp.foldCase();
        int32_t tmpidx = 0;
        while (tmpidx < tmp.length()) {
            UChar c = tmp.charAt(tmpidx++);
            node = getChildNode(node, c);
            if (node == NULL) {
                break;
            }
        }
    } else {
        // here we just get the next UTF16 code unit
        UChar c = text.charAt(index++);
        node = getChildNode(node, c);
    }
    if (node != NULL) {
        search(node, text, start, index, handler, status);
    }
}

// ---------------------------------------------------
// ZNStringPool class implementation
// ---------------------------------------------------
static const int32_t POOL_CHUNK_SIZE = 2000;
struct ZNStringPoolChunk: public UMemory {
    ZNStringPoolChunk    *fNext;                       // Ptr to next pool chunk
    int32_t               fLimit;                       // Index to start of unused area at end of fStrings
    UChar                 fStrings[POOL_CHUNK_SIZE];    //  Strings array
    ZNStringPoolChunk();
};

ZNStringPoolChunk::ZNStringPoolChunk() {
    fNext = NULL;
    fLimit = 0;
}

ZNStringPool::ZNStringPool(UErrorCode &status) {
    fChunks = NULL;
    fHash   = NULL;
    if (U_FAILURE(status)) {
        return;
    }
    fChunks = new ZNStringPoolChunk;
    if (fChunks == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }

    fHash   = uhash_open(uhash_hashUChars      /* keyHash */, 
                         uhash_compareUChars   /* keyComp */, 
                         uhash_compareUChars   /* valueComp */, 
                         &status);
    if (U_FAILURE(status)) {
        return;
    }
}

ZNStringPool::~ZNStringPool() {
    if (fHash != NULL) {
        uhash_close(fHash);
        fHash = NULL;
    }

    while (fChunks != NULL) {
        ZNStringPoolChunk *nextChunk = fChunks->fNext;
        delete fChunks;
        fChunks = nextChunk;
    }
}

static const UChar EmptyString = 0;

const UChar *ZNStringPool::get(const UChar *s, UErrorCode &status) {
    const UChar *pooledString;
    if (U_FAILURE(status)) {
        return &EmptyString;
    }

    pooledString = static_cast<UChar *>(uhash_get(fHash, s));
    if (pooledString != NULL) {
        return pooledString;
    }

    int32_t length = u_strlen(s);
    int32_t remainingLength = POOL_CHUNK_SIZE - fChunks->fLimit;
    if (remainingLength <= length) {
        U_ASSERT(length < POOL_CHUNK_SIZE);
        if (length >= POOL_CHUNK_SIZE) {
            status = U_INTERNAL_PROGRAM_ERROR;
            return &EmptyString;
        }
        ZNStringPoolChunk *oldChunk = fChunks;
        fChunks = new ZNStringPoolChunk;
        if (fChunks == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return &EmptyString;
        }
        fChunks->fNext = oldChunk;
    }
    
    UChar *destString = &fChunks->fStrings[fChunks->fLimit];
    u_strcpy(destString, s);
    fChunks->fLimit += (length + 1);
    uhash_put(fHash, destString, destString, &status);
    return destString;
}        


//
//  ZNStringPool::adopt()    Put a string into the hash, but do not copy the string data
//                           into the pool's storage.  Used for strings from resource bundles,
//                           which will persist for the life of the zone string formatter, and
//                           therefore can be used directly without copying.
const UChar *ZNStringPool::adopt(const UChar * s, UErrorCode &status) {
    const UChar *pooledString;
    if (U_FAILURE(status)) {
        return &EmptyString;
    }
    if (s != NULL) {
        pooledString = static_cast<UChar *>(uhash_get(fHash, s));
        if (pooledString == NULL) {
            UChar *ncs = const_cast<UChar *>(s);
            uhash_put(fHash, ncs, ncs, &status);
        }
    }
    return s;
}

    
const UChar *ZNStringPool::get(const UnicodeString &s, UErrorCode &status) {
    UnicodeString &nonConstStr = const_cast<UnicodeString &>(s);
    return this->get(nonConstStr.getTerminatedBuffer(), status);
}

/*
 * freeze().   Close the hash table that maps to the pooled strings.
 *             After freezing, the pool can not be searched or added to,
 *             but all existing references to pooled strings remain valid.
 *
 *             The main purpose is to recover the storage used for the hash.
 */
void ZNStringPool::freeze() {
    uhash_close(fHash);
    fHash = NULL;
}


/**
 * This class stores name data for a meta zone or time zone.
 */
class ZNames : public UMemory {
private:
    friend class TimeZoneNamesImpl;

    static UTimeZoneNameTypeIndex getTZNameTypeIndex(UTimeZoneNameType type) {
        switch(type) {
        case UTZNM_EXEMPLAR_LOCATION: return UTZNM_INDEX_EXEMPLAR_LOCATION;
        case UTZNM_LONG_GENERIC: return UTZNM_INDEX_LONG_GENERIC;
        case UTZNM_LONG_STANDARD: return UTZNM_INDEX_LONG_STANDARD;
        case UTZNM_LONG_DAYLIGHT: return UTZNM_INDEX_LONG_DAYLIGHT;
        case UTZNM_SHORT_GENERIC: return UTZNM_INDEX_SHORT_GENERIC;
        case UTZNM_SHORT_STANDARD: return UTZNM_INDEX_SHORT_STANDARD;
        case UTZNM_SHORT_DAYLIGHT: return UTZNM_INDEX_SHORT_DAYLIGHT;
        default: return UTZNM_INDEX_UNKNOWN;
        }
    }
    static UTimeZoneNameType getTZNameType(UTimeZoneNameTypeIndex index) {
        switch(index) {
        case UTZNM_INDEX_EXEMPLAR_LOCATION: return UTZNM_EXEMPLAR_LOCATION;
        case UTZNM_INDEX_LONG_GENERIC: return UTZNM_LONG_GENERIC;
        case UTZNM_INDEX_LONG_STANDARD: return UTZNM_LONG_STANDARD;
        case UTZNM_INDEX_LONG_DAYLIGHT: return UTZNM_LONG_DAYLIGHT;
        case UTZNM_INDEX_SHORT_GENERIC: return UTZNM_SHORT_GENERIC;
        case UTZNM_INDEX_SHORT_STANDARD: return UTZNM_SHORT_STANDARD;
        case UTZNM_INDEX_SHORT_DAYLIGHT: return UTZNM_SHORT_DAYLIGHT;
        default: return UTZNM_UNKNOWN;
        }
    }

    const UChar* fNames[UTZNM_INDEX_COUNT];
    UBool fDidAddIntoTrie;

    // Whether we own the location string, if computed rather than loaded from a bundle.
    // A meta zone names instance never has an exemplar location string.
    UBool fOwnsLocationName;

    ZNames(const UChar* names[], const UChar* locationName)
            : fDidAddIntoTrie(FALSE) {
        uprv_memcpy(fNames, names, sizeof(fNames));
        if (locationName != NULL) {
            fOwnsLocationName = TRUE;
            fNames[UTZNM_INDEX_EXEMPLAR_LOCATION] = locationName;
        } else {
            fOwnsLocationName = FALSE;
        }
    }

public:
    ~ZNames() {
        if (fOwnsLocationName) {
            const UChar* locationName = fNames[UTZNM_INDEX_EXEMPLAR_LOCATION];
            U_ASSERT(locationName != NULL);
            uprv_free((void*) locationName);
        }
    }

private:
    static void* createMetaZoneAndPutInCache(UHashtable* cache, const UChar* names[],
            const UnicodeString& mzID, UErrorCode& status) {
        if (U_FAILURE(status)) { return NULL; }
        U_ASSERT(names != NULL);

        // Use the persistent ID as the resource key, so we can
        // avoid duplications.
        // TODO: Is there a more efficient way, like intern() in Java?
        void* key = (void*) ZoneMeta::findMetaZoneID(mzID);
        void* value;
        if (uprv_memcmp(names, EMPTY_NAMES, sizeof(EMPTY_NAMES)) == 0) {
            value = (void*) EMPTY;
        } else {
            value = (void*) (new ZNames(names, NULL));
            if (value == NULL) {
                status = U_MEMORY_ALLOCATION_ERROR;
                return NULL;
            }
        }
        uhash_put(cache, key, value, &status);
        return value;
    }

    static void* createTimeZoneAndPutInCache(UHashtable* cache, const UChar* names[],
            const UnicodeString& tzID, UErrorCode& status) {
        if (U_FAILURE(status)) { return NULL; }
        U_ASSERT(names != NULL);

        // If necessary, compute the location name from the time zone name.
        UChar* locationName = NULL;
        if (names[UTZNM_INDEX_EXEMPLAR_LOCATION] == NULL) {
            UnicodeString locationNameUniStr;
            TimeZoneNamesImpl::getDefaultExemplarLocationName(tzID, locationNameUniStr);

            // Copy the computed location name to the heap
            if (locationNameUniStr.length() > 0) {
                const UChar* buff = locationNameUniStr.getTerminatedBuffer();
                int32_t len = sizeof(UChar) * (locationNameUniStr.length() + 1);
                locationName = (UChar*) uprv_malloc(len);
                if (locationName == NULL) {
                    status = U_MEMORY_ALLOCATION_ERROR;
                    return NULL;
                }
                uprv_memcpy(locationName, buff, len);
            }
        }

        // Use the persistent ID as the resource key, so we can
        // avoid duplications.
        // TODO: Is there a more efficient way, like intern() in Java?
        void* key = (void*) ZoneMeta::findTimeZoneID(tzID);
        void* value = (void*) (new ZNames(names, locationName));
        if (value == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return NULL;
        }
        uhash_put(cache, key, value, &status);
        return value;
    }

    const UChar* getName(UTimeZoneNameType type) const {
        UTimeZoneNameTypeIndex index = getTZNameTypeIndex(type);
        return index >= 0 ? fNames[index] : NULL;
    }

    void addAsMetaZoneIntoTrie(const UChar* mzID, TextTrieMap& trie, UErrorCode& status) {
        addNamesIntoTrie(mzID, NULL, trie, status);
    }
    void addAsTimeZoneIntoTrie(const UChar* tzID, TextTrieMap& trie, UErrorCode& status) {
        addNamesIntoTrie(NULL, tzID, trie, status);
    }

    void addNamesIntoTrie(const UChar* mzID, const UChar* tzID, TextTrieMap& trie,
            UErrorCode& status) {
        if (U_FAILURE(status)) { return; }
        if (fDidAddIntoTrie) { return; }
        fDidAddIntoTrie = TRUE;

        for (int32_t i = 0; i < UTZNM_INDEX_COUNT; i++) {
            const UChar* name = fNames[i];
            if (name != NULL) {
                ZNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(ZNameInfo));
                if (nameinfo == NULL) {
                    status = U_MEMORY_ALLOCATION_ERROR;
                    return;
                }
                nameinfo->mzID = mzID;
                nameinfo->tzID = tzID;
                nameinfo->type = getTZNameType((UTimeZoneNameTypeIndex)i);
                trie.put(name, nameinfo, status); // trie.put() takes ownership of the key
                if (U_FAILURE(status)) {
                    return;
                }
            }
        }
    }

public:
    struct ZNamesLoader;
};

struct ZNames::ZNamesLoader : public ResourceSink {
    const UChar *names[UTZNM_INDEX_COUNT];

    ZNamesLoader() {
        clear();
    }
    virtual ~ZNamesLoader();

    /** Reset for loading another set of names. */
    void clear() {
        uprv_memcpy(names, EMPTY_NAMES, sizeof(names));
    }

    void loadMetaZone(const UResourceBundle* zoneStrings, const UnicodeString& mzID, UErrorCode& errorCode) {
        if (U_FAILURE(errorCode)) { return; }

        char key[ZID_KEY_MAX + 1];
        mergeTimeZoneKey(mzID, key);

        loadNames(zoneStrings, key, errorCode);
    }

    void loadTimeZone(const UResourceBundle* zoneStrings, const UnicodeString& tzID, UErrorCode& errorCode) {
        // Replace "/" with ":".
        UnicodeString uKey(tzID);
        for (int32_t i = 0; i < uKey.length(); i++) {
            if (uKey.charAt(i) == (UChar)0x2F) {
                uKey.setCharAt(i, (UChar)0x3A);
            }
        }

        char key[ZID_KEY_MAX + 1];
        uKey.extract(0, uKey.length(), key, sizeof(key), US_INV);

        loadNames(zoneStrings, key, errorCode);
    }

    void loadNames(const UResourceBundle* zoneStrings, const char* key, UErrorCode& errorCode) {
        U_ASSERT(zoneStrings != NULL);
        U_ASSERT(key != NULL);
        U_ASSERT(key[0] != '\0');

        UErrorCode localStatus = U_ZERO_ERROR;
        clear();
        ures_getAllItemsWithFallback(zoneStrings, key, *this, localStatus);

        // Ignore errors, but propagate possible warnings.
        if (U_SUCCESS(localStatus)) {
            errorCode = localStatus;
        }
    }

    void setNameIfEmpty(const char* key, const ResourceValue* value, UErrorCode& errorCode) {
        UTimeZoneNameTypeIndex type = nameTypeFromKey(key);
        if (type == UTZNM_INDEX_UNKNOWN) { return; }
        if (names[type] == NULL) {
            int32_t length;
            // 'NO_NAME' indicates internally that this field should remain empty.  It will be
            // replaced by 'NULL' in getNames()
            names[type] = (value == NULL) ? NO_NAME : value->getString(length, errorCode);
        }
    }

    virtual void put(const char* key, ResourceValue& value, UBool /*noFallback*/,
            UErrorCode &errorCode) override {
        ResourceTable namesTable = value.getTable(errorCode);
        if (U_FAILURE(errorCode)) { return; }
        for (int32_t i = 0; namesTable.getKeyAndValue(i, key, value); ++i) {
            if (value.isNoInheritanceMarker()) {
                setNameIfEmpty(key, NULL, errorCode);
            } else {
                setNameIfEmpty(key, &value, errorCode);
            }
        }
    }

    static UTimeZoneNameTypeIndex nameTypeFromKey(const char *key) {
        char c0, c1;
        if ((c0 = key[0]) == 0 || (c1 = key[1]) == 0 || key[2] != 0) {
            return UTZNM_INDEX_UNKNOWN;
        }
        if (c0 == 'l') {
            return c1 == 'g' ? UTZNM_INDEX_LONG_GENERIC :
                    c1 == 's' ? UTZNM_INDEX_LONG_STANDARD :
                        c1 == 'd' ? UTZNM_INDEX_LONG_DAYLIGHT : UTZNM_INDEX_UNKNOWN;
        } else if (c0 == 's') {
            return c1 == 'g' ? UTZNM_INDEX_SHORT_GENERIC :
                    c1 == 's' ? UTZNM_INDEX_SHORT_STANDARD :
                        c1 == 'd' ? UTZNM_INDEX_SHORT_DAYLIGHT : UTZNM_INDEX_UNKNOWN;
        } else if (c0 == 'e' && c1 == 'c') {
            return UTZNM_INDEX_EXEMPLAR_LOCATION;
        }
        return UTZNM_INDEX_UNKNOWN;
    }

    /**
    * Returns an array of names.  It is the caller's responsibility to copy the data into a
    * permanent location, as the returned array is owned by the loader instance and may be
    * cleared or leave scope.
    *
    * This is different than Java, where the array will no longer be modified and null
    * may be returned.
    */
    const UChar** getNames() {
        // Remove 'NO_NAME' references in the array and replace with 'NULL'
        for (int32_t i = 0; i < UTZNM_INDEX_COUNT; ++i) {
            if (names[i] == NO_NAME) {
                names[i] = NULL;
            }
        }
        return names;
    }
};

ZNames::ZNamesLoader::~ZNamesLoader() {}


// ---------------------------------------------------
// The meta zone ID enumeration class
// ---------------------------------------------------
class MetaZoneIDsEnumeration : public StringEnumeration {
public:
    MetaZoneIDsEnumeration();
    MetaZoneIDsEnumeration(const UVector& mzIDs);
    MetaZoneIDsEnumeration(LocalPointer<UVector> mzIDs);
    virtual ~MetaZoneIDsEnumeration();
    static UClassID U_EXPORT2 getStaticClassID(void);
    virtual UClassID getDynamicClassID(void) const override;
    virtual const UnicodeString* snext(UErrorCode& status) override;
    virtual void reset(UErrorCode& status) override;
    virtual int32_t count(UErrorCode& status) const override;
private:
    int32_t fLen;
    int32_t fPos;
    const UVector* fMetaZoneIDs;
    LocalPointer<UVector> fLocalVector;
};

UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MetaZoneIDsEnumeration)

MetaZoneIDsEnumeration::MetaZoneIDsEnumeration() 
: fLen(0), fPos(0), fMetaZoneIDs(NULL), fLocalVector(NULL) {
}

MetaZoneIDsEnumeration::MetaZoneIDsEnumeration(const UVector& mzIDs) 
: fPos(0), fMetaZoneIDs(&mzIDs), fLocalVector(NULL) {
    fLen = fMetaZoneIDs->size();
}

MetaZoneIDsEnumeration::MetaZoneIDsEnumeration(LocalPointer<UVector> mzIDs)
: fLen(0), fPos(0), fMetaZoneIDs(nullptr), fLocalVector(std::move(mzIDs)) {
    fMetaZoneIDs = fLocalVector.getAlias();
    if (fMetaZoneIDs) {
        fLen = fMetaZoneIDs->size();
    }
}

const UnicodeString*
MetaZoneIDsEnumeration::snext(UErrorCode& status) {
    if (U_SUCCESS(status) && fMetaZoneIDs != NULL && fPos < fLen) {
        unistr.setTo((const UChar*)fMetaZoneIDs->elementAt(fPos++), -1);
        return &unistr;
    }
    return NULL;
}

void
MetaZoneIDsEnumeration::reset(UErrorCode& /*status*/) {
    fPos = 0;
}

int32_t
MetaZoneIDsEnumeration::count(UErrorCode& /*status*/) const {
    return fLen;
}

MetaZoneIDsEnumeration::~MetaZoneIDsEnumeration() {
}


// ---------------------------------------------------
// ZNameSearchHandler
// ---------------------------------------------------
class ZNameSearchHandler : public TextTrieMapSearchResultHandler {
public:
    ZNameSearchHandler(uint32_t types);
    virtual ~ZNameSearchHandler();

    UBool handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) override;
    TimeZoneNames::MatchInfoCollection* getMatches(int32_t& maxMatchLen);

private:
    uint32_t fTypes;
    int32_t fMaxMatchLen;
    TimeZoneNames::MatchInfoCollection* fResults;
};

ZNameSearchHandler::ZNameSearchHandler(uint32_t types) 
: fTypes(types), fMaxMatchLen(0), fResults(NULL) {
}

ZNameSearchHandler::~ZNameSearchHandler() {
    if (fResults != NULL) {
        delete fResults;
    }
}

UBool
ZNameSearchHandler::handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return FALSE;
    }
    if (node->hasValues()) {
        int32_t valuesCount = node->countValues();
        for (int32_t i = 0; i < valuesCount; i++) {
            ZNameInfo *nameinfo = (ZNameInfo *)node->getValue(i);
            if (nameinfo == NULL) {
                continue;
            }
            if ((nameinfo->type & fTypes) != 0) {
                // matches a requested type
                if (fResults == NULL) {
                    fResults = new TimeZoneNames::MatchInfoCollection();
                    if (fResults == NULL) {
                        status = U_MEMORY_ALLOCATION_ERROR;
                    }
                }
                if (U_SUCCESS(status)) {
                    U_ASSERT(fResults != NULL);
                    if (nameinfo->tzID) {
                        fResults->addZone(nameinfo->type, matchLength, UnicodeString(nameinfo->tzID, -1), status);
                    } else {
                        U_ASSERT(nameinfo->mzID);
                        fResults->addMetaZone(nameinfo->type, matchLength, UnicodeString(nameinfo->mzID, -1), status);
                    }
                    if (U_SUCCESS(status) && matchLength > fMaxMatchLen) {
                        fMaxMatchLen = matchLength;
                    }
                }
            }
        }
    }
    return TRUE;
}

TimeZoneNames::MatchInfoCollection*
ZNameSearchHandler::getMatches(int32_t& maxMatchLen) {
    // give the ownership to the caller
    TimeZoneNames::MatchInfoCollection* results = fResults;
    maxMatchLen = fMaxMatchLen;

    // reset
    fResults = NULL;
    fMaxMatchLen = 0;
    return results;
}

// ---------------------------------------------------
// TimeZoneNamesImpl
//
// TimeZoneNames implementation class. This is the main
// part of this module.
// ---------------------------------------------------

U_CDECL_BEGIN
/**
 * Deleter for ZNames
 */
static void U_CALLCONV
deleteZNames(void *obj) {
    if (obj != EMPTY) {
        delete (ZNames*) obj;
    }
}

/**
 * Deleter for ZNameInfo
 */
static void U_CALLCONV
deleteZNameInfo(void *obj) {
    uprv_free(obj);
}

U_CDECL_END

TimeZoneNamesImpl::TimeZoneNamesImpl(const Locale& locale, UErrorCode& status)
: fLocale(locale),
  fZoneStrings(NULL),
  fTZNamesMap(NULL),
  fMZNamesMap(NULL),
  fNamesTrieFullyLoaded(FALSE),
  fNamesFullyLoaded(FALSE),
  fNamesTrie(TRUE, deleteZNameInfo) {
    initialize(locale, status);
}

void
TimeZoneNamesImpl::initialize(const Locale& locale, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return;
    }

    // Load zoneStrings bundle
    UErrorCode tmpsts = U_ZERO_ERROR;   // OK with fallback warning..
    fZoneStrings = ures_open(U_ICUDATA_ZONE, locale.getName(), &tmpsts);
    fZoneStrings = ures_getByKeyWithFallback(fZoneStrings, gZoneStrings, fZoneStrings, &tmpsts);
    if (U_FAILURE(tmpsts)) {
        status = tmpsts;
        cleanup();
        return;
    }

    // Initialize hashtables holding time zone/meta zone names
    fMZNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status);
    fTZNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status);
    if (U_FAILURE(status)) {
        cleanup();
        return;
    }

    uhash_setValueDeleter(fMZNamesMap, deleteZNames);
    uhash_setValueDeleter(fTZNamesMap, deleteZNames);
    // no key deleters for name maps

    // preload zone strings for the default zone
    TimeZone *tz = TimeZone::createDefault();
    const UChar *tzID = ZoneMeta::getCanonicalCLDRID(*tz);
    if (tzID != NULL) {
        loadStrings(UnicodeString(tzID), status);
    }
    delete tz;

    return;
}

/*
 * This method updates the cache and must be called with a lock,
 * except initializer.
 */
void
TimeZoneNamesImpl::loadStrings(const UnicodeString& tzCanonicalID, UErrorCode& status) {
    loadTimeZoneNames(tzCanonicalID, status);
    LocalPointer<StringEnumeration> mzIDs(getAvailableMetaZoneIDs(tzCanonicalID, status));
    if (U_FAILURE(status)) { return; }
    U_ASSERT(!mzIDs.isNull());

    const UnicodeString *mzID;
    while (((mzID = mzIDs->snext(status)) != NULL) && U_SUCCESS(status)) {
        loadMetaZoneNames(*mzID, status);
    }
}

TimeZoneNamesImpl::~TimeZoneNamesImpl() {
    cleanup();
}

void
TimeZoneNamesImpl::cleanup() {
    if (fZoneStrings != NULL) {
        ures_close(fZoneStrings);
        fZoneStrings = NULL;
    }
    if (fMZNamesMap != NULL) {
        uhash_close(fMZNamesMap);
        fMZNamesMap = NULL;
    }
    if (fTZNamesMap != NULL) {
        uhash_close(fTZNamesMap);
        fTZNamesMap = NULL;
    }
}

bool
TimeZoneNamesImpl::operator==(const TimeZoneNames& other) const {
    if (this == &other) {
        return true;
    }
    // No implementation for now
    return false;
}

TimeZoneNamesImpl*
TimeZoneNamesImpl::clone() const {
    UErrorCode status = U_ZERO_ERROR;
    return new TimeZoneNamesImpl(fLocale, status);
}

StringEnumeration*
TimeZoneNamesImpl::getAvailableMetaZoneIDs(UErrorCode& status) const {
    return TimeZoneNamesImpl::_getAvailableMetaZoneIDs(status);
}

// static implementation of getAvailableMetaZoneIDs(UErrorCode&)
StringEnumeration*
TimeZoneNamesImpl::_getAvailableMetaZoneIDs(UErrorCode& status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    const UVector* mzIDs = ZoneMeta::getAvailableMetazoneIDs();
    if (mzIDs == NULL) {
        return new MetaZoneIDsEnumeration();
    }
    return new MetaZoneIDsEnumeration(*mzIDs);
}

StringEnumeration*
TimeZoneNamesImpl::getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const {
    return TimeZoneNamesImpl::_getAvailableMetaZoneIDs(tzID, status);
}

// static implementation of getAvailableMetaZoneIDs(const UnicodeString&, UErrorCode&)
StringEnumeration*
TimeZoneNamesImpl::_getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    const UVector* mappings = ZoneMeta::getMetazoneMappings(tzID);
    if (mappings == NULL) {
        return new MetaZoneIDsEnumeration();
    }

    LocalPointer<MetaZoneIDsEnumeration> senum;
    LocalPointer<UVector> mzIDs(new UVector(NULL, uhash_compareUChars, status), status);
    if (U_SUCCESS(status)) {
        U_ASSERT(mzIDs.isValid());
        for (int32_t i = 0; U_SUCCESS(status) && i < mappings->size(); i++) {

            OlsonToMetaMappingEntry *map = (OlsonToMetaMappingEntry *)mappings->elementAt(i);
            const UChar *mzID = map->mzid;
            if (!mzIDs->contains((void *)mzID)) {
                mzIDs->addElement((void *)mzID, status);
            }
        }
        if (U_SUCCESS(status)) {
            senum.adoptInsteadAndCheckErrorCode(new MetaZoneIDsEnumeration(std::move(mzIDs)), status);
        }
    }
    return U_SUCCESS(status) ? senum.orphan() : nullptr;
}

UnicodeString&
TimeZoneNamesImpl::getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const {
    return TimeZoneNamesImpl::_getMetaZoneID(tzID, date, mzID);
}

// static implementation of getMetaZoneID
UnicodeString&
TimeZoneNamesImpl::_getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) {
    ZoneMeta::getMetazoneID(tzID, date, mzID);
    return mzID;
}

UnicodeString&
TimeZoneNamesImpl::getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const {
    return TimeZoneNamesImpl::_getReferenceZoneID(mzID, region, tzID);
}

// static implementation of getReferenceZoneID
UnicodeString&
TimeZoneNamesImpl::_getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) {
    ZoneMeta::getZoneIdByMetazone(mzID, UnicodeString(region, -1, US_INV), tzID);
    return tzID;
}

UnicodeString&
TimeZoneNamesImpl::getMetaZoneDisplayName(const UnicodeString& mzID,
                                          UTimeZoneNameType type,
                                          UnicodeString& name) const {
    name.setToBogus();  // cleanup result.
    if (mzID.isEmpty()) {
        return name;
    }

    ZNames *znames = NULL;
    TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this);

    {
        Mutex lock(&gDataMutex);
        UErrorCode status = U_ZERO_ERROR;
        znames = nonConstThis->loadMetaZoneNames(mzID, status);
        if (U_FAILURE(status)) { return name; }
    }

    if (znames != NULL) {
        const UChar* s = znames->getName(type);
        if (s != NULL) {
            name.setTo(TRUE, s, -1);
        }
    }
    return name;
}

UnicodeString&
TimeZoneNamesImpl::getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UnicodeString& name) const {
    name.setToBogus();  // cleanup result.
    if (tzID.isEmpty()) {
        return name;
    }

    ZNames *tznames = NULL;
    TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this);

    {
        Mutex lock(&gDataMutex);
        UErrorCode status = U_ZERO_ERROR;
        tznames = nonConstThis->loadTimeZoneNames(tzID, status);
        if (U_FAILURE(status)) { return name; }
    }

    if (tznames != NULL) {
        const UChar *s = tznames->getName(type);
        if (s != NULL) {
            name.setTo(TRUE, s, -1);
        }
    }
    return name;
}

UnicodeString&
TimeZoneNamesImpl::getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const {
    name.setToBogus();  // cleanup result.
    const UChar* locName = NULL;
    ZNames *tznames = NULL;
    TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this);

    {
        Mutex lock(&gDataMutex);
        UErrorCode status = U_ZERO_ERROR;
        tznames = nonConstThis->loadTimeZoneNames(tzID, status);
        if (U_FAILURE(status)) { return name; }
    }

    if (tznames != NULL) {
        locName = tznames->getName(UTZNM_EXEMPLAR_LOCATION);
    }
    if (locName != NULL) {
        name.setTo(TRUE, locName, -1);
    }

    return name;
}


// Merge the MZ_PREFIX and mzId
static void mergeTimeZoneKey(const UnicodeString& mzID, char* result) {
    if (mzID.isEmpty()) {
        result[0] = '\0';
        return;
    }

    char mzIdChar[ZID_KEY_MAX + 1];
    int32_t keyLen;
    int32_t prefixLen = static_cast<int32_t>(uprv_strlen(gMZPrefix));
    keyLen = mzID.extract(0, mzID.length(), mzIdChar, ZID_KEY_MAX + 1, US_INV);
    uprv_memcpy((void *)result, (void *)gMZPrefix, prefixLen);
    uprv_memcpy((void *)(result + prefixLen), (void *)mzIdChar, keyLen);
    result[keyLen + prefixLen] = '\0';
}

/*
 * This method updates the cache and must be called with a lock
 */
ZNames*
TimeZoneNamesImpl::loadMetaZoneNames(const UnicodeString& mzID, UErrorCode& status) {
    if (U_FAILURE(status)) { return NULL; }
    U_ASSERT(mzID.length() <= ZID_KEY_MAX - MZ_PREFIX_LEN);

    UChar mzIDKey[ZID_KEY_MAX + 1];
    mzID.extract(mzIDKey, ZID_KEY_MAX + 1, status);
    U_ASSERT(U_SUCCESS(status));   // already checked length above
    mzIDKey[mzID.length()] = 0;

    void* mznames = uhash_get(fMZNamesMap, mzIDKey);
    if (mznames == NULL) {
        ZNames::ZNamesLoader loader;
        loader.loadMetaZone(fZoneStrings, mzID, status);
        mznames = ZNames::createMetaZoneAndPutInCache(fMZNamesMap, loader.getNames(), mzID, status);
        if (U_FAILURE(status)) { return NULL; }
    }

    if (mznames != EMPTY) {
        return (ZNames*)mznames;
    } else {
        return NULL;
    }
}

/*
 * This method updates the cache and must be called with a lock
 */
ZNames*
TimeZoneNamesImpl::loadTimeZoneNames(const UnicodeString& tzID, UErrorCode& status) {
    if (U_FAILURE(status)) { return NULL; }
    U_ASSERT(tzID.length() <= ZID_KEY_MAX);

    UChar tzIDKey[ZID_KEY_MAX + 1];
    int32_t tzIDKeyLen = tzID.extract(tzIDKey, ZID_KEY_MAX + 1, status);
    U_ASSERT(U_SUCCESS(status));   // already checked length above
    tzIDKey[tzIDKeyLen] = 0;

    void *tznames = uhash_get(fTZNamesMap, tzIDKey);
    if (tznames == NULL) {
        ZNames::ZNamesLoader loader;
        loader.loadTimeZone(fZoneStrings, tzID, status);
        tznames = ZNames::createTimeZoneAndPutInCache(fTZNamesMap, loader.getNames(), tzID, status);
        if (U_FAILURE(status)) { return NULL; }
    }

    // tznames is never EMPTY
    return (ZNames*)tznames;
}

TimeZoneNames::MatchInfoCollection*
TimeZoneNamesImpl::find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const {
    ZNameSearchHandler handler(types);
    TimeZoneNames::MatchInfoCollection* matches;
    TimeZoneNamesImpl* nonConstThis = const_cast<TimeZoneNamesImpl*>(this);

    // Synchronize so that data is not loaded multiple times.
    // TODO: Consider more fine-grained synchronization.
    {
        Mutex lock(&gDataMutex);

        // First try of lookup.
        matches = doFind(handler, text, start, status);
        if (U_FAILURE(status)) { return NULL; }
        if (matches != NULL) {
            return matches;
        }

        // All names are not yet loaded into the trie.
        // We may have loaded names for formatting several time zones,
        // and might be parsing one of those.
        // Populate the parsing trie from all of the already-loaded names.
        nonConstThis->addAllNamesIntoTrie(status);

        // Second try of lookup.
        matches = doFind(handler, text, start, status);
        if (U_FAILURE(status)) { return NULL; }
        if (matches != NULL) {
            return matches;
        }

        // There are still some names we haven't loaded into the trie yet.
        // Load everything now.
        nonConstThis->internalLoadAllDisplayNames(status);
        nonConstThis->addAllNamesIntoTrie(status);
        nonConstThis->fNamesTrieFullyLoaded = TRUE;
        if (U_FAILURE(status)) { return NULL; }

        // Third try: we must return this one.
        return doFind(handler, text, start, status);
    }
}

TimeZoneNames::MatchInfoCollection*
TimeZoneNamesImpl::doFind(ZNameSearchHandler& handler,
        const UnicodeString& text, int32_t start, UErrorCode& status) const {

    fNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status);
    if (U_FAILURE(status)) { return NULL; }

    int32_t maxLen = 0;
    TimeZoneNames::MatchInfoCollection* matches = handler.getMatches(maxLen);
    if (matches != NULL && ((maxLen == (text.length() - start)) || fNamesTrieFullyLoaded)) {
        // perfect match, or no more names available
        return matches;
    }
    delete matches;
    return NULL;
}

// Caller must synchronize.
void TimeZoneNamesImpl::addAllNamesIntoTrie(UErrorCode& status) {
    if (U_FAILURE(status)) return;
    int32_t pos;
    const UHashElement* element;

    pos = UHASH_FIRST;
    while ((element = uhash_nextElement(fMZNamesMap, &pos)) != NULL) {
        if (element->value.pointer == EMPTY) { continue; }
        UChar* mzID = (UChar*) element->key.pointer;
        ZNames* znames = (ZNames*) element->value.pointer;
        znames->addAsMetaZoneIntoTrie(mzID, fNamesTrie, status);
        if (U_FAILURE(status)) { return; }
    }

    pos = UHASH_FIRST;
    while ((element = uhash_nextElement(fTZNamesMap, &pos)) != NULL) {
        if (element->value.pointer == EMPTY) { continue; }
        UChar* tzID = (UChar*) element->key.pointer;
        ZNames* znames = (ZNames*) element->value.pointer;
        znames->addAsTimeZoneIntoTrie(tzID, fNamesTrie, status);
        if (U_FAILURE(status)) { return; }
    }
}

U_CDECL_BEGIN
static void U_CALLCONV
deleteZNamesLoader(void* obj) {
    if (obj == DUMMY_LOADER) { return; }
    const ZNames::ZNamesLoader* loader = (const ZNames::ZNamesLoader*) obj;
    delete loader;
}
U_CDECL_END

struct TimeZoneNamesImpl::ZoneStringsLoader : public ResourceSink {
    TimeZoneNamesImpl& tzn;
    UHashtable* keyToLoader;

    ZoneStringsLoader(TimeZoneNamesImpl& _tzn, UErrorCode& status)
            : tzn(_tzn) {
        keyToLoader = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
        if (U_FAILURE(status)) { return; }
        uhash_setKeyDeleter(keyToLoader, uprv_free);
        uhash_setValueDeleter(keyToLoader, deleteZNamesLoader);
    }
    virtual ~ZoneStringsLoader();

    void* createKey(const char* key, UErrorCode& status) {
        int32_t len = sizeof(char) * (static_cast<int32_t>(uprv_strlen(key)) + 1);
        char* newKey = (char*) uprv_malloc(len);
        if (newKey == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return NULL;
        }
        uprv_memcpy(newKey, key, len);
        newKey[len-1] = '\0';
        return (void*) newKey;
    }

    UBool isMetaZone(const char* key) {
        return (uprv_strlen(key) >= MZ_PREFIX_LEN && uprv_memcmp(key, gMZPrefix, MZ_PREFIX_LEN) == 0);
    }

    UnicodeString mzIDFromKey(const char* key) {
        return UnicodeString(key + MZ_PREFIX_LEN, static_cast<int32_t>(uprv_strlen(key)) - MZ_PREFIX_LEN, US_INV);
    }

    UnicodeString tzIDFromKey(const char* key) {
        UnicodeString tzID(key, -1, US_INV);
        // Replace all colons ':' with slashes '/'
        for (int i=0; i<tzID.length(); i++) {
            if (tzID.charAt(i) == 0x003A) {
                tzID.setCharAt(i, 0x002F);
            }
        }
        return tzID;
    }

    void load(UErrorCode& status) {
        ures_getAllItemsWithFallback(tzn.fZoneStrings, "", *this, status);
        if (U_FAILURE(status)) { return; }

        int32_t pos = UHASH_FIRST;
        const UHashElement* element;
        while ((element = uhash_nextElement(keyToLoader, &pos)) != NULL) {
            if (element->value.pointer == DUMMY_LOADER) { continue; }
            ZNames::ZNamesLoader* loader = (ZNames::ZNamesLoader*) element->value.pointer;
            char* key = (char*) element->key.pointer;

            if (isMetaZone(key)) {
                UnicodeString mzID = mzIDFromKey(key);
                ZNames::createMetaZoneAndPutInCache(tzn.fMZNamesMap, loader->getNames(), mzID, status);
            } else {
                UnicodeString tzID = tzIDFromKey(key);
                ZNames::createTimeZoneAndPutInCache(tzn.fTZNamesMap, loader->getNames(), tzID, status);
            }
            if (U_FAILURE(status)) { return; }
        }
    }

    void consumeNamesTable(const char *key, ResourceValue &value, UBool noFallback,
            UErrorCode &status) {
        if (U_FAILURE(status)) { return; }

        void* loader = uhash_get(keyToLoader, key);
        if (loader == NULL) {
            if (isMetaZone(key)) {
                UnicodeString mzID = mzIDFromKey(key);
                void* cacheVal = uhash_get(tzn.fMZNamesMap, mzID.getTerminatedBuffer());
                if (cacheVal != NULL) {
                    // We have already loaded the names for this meta zone.
                    loader = (void*) DUMMY_LOADER;
                } else {
                    loader = (void*) new ZNames::ZNamesLoader();
                    if (loader == NULL) {
                        status = U_MEMORY_ALLOCATION_ERROR;
                        return;
                    }
                }
            } else {
                UnicodeString tzID = tzIDFromKey(key);
                void* cacheVal = uhash_get(tzn.fTZNamesMap, tzID.getTerminatedBuffer());
                if (cacheVal != NULL) {
                    // We have already loaded the names for this time zone.
                    loader = (void*) DUMMY_LOADER;
                } else {
                    loader = (void*) new ZNames::ZNamesLoader();
                    if (loader == NULL) {
                        status = U_MEMORY_ALLOCATION_ERROR;
                        return;
                    }
                }
            }

            void* newKey = createKey(key, status);
            if (U_FAILURE(status)) {
                deleteZNamesLoader(loader);
                return;
            }

            uhash_put(keyToLoader, newKey, loader, &status);
            if (U_FAILURE(status)) { return; }
        }

        if (loader != DUMMY_LOADER) {
            // Let the ZNamesLoader consume the names table.
            ((ZNames::ZNamesLoader*)loader)->put(key, value, noFallback, status);
        }
    }

    virtual void put(const char *key, ResourceValue &value, UBool noFallback,
            UErrorCode &status) override {
        ResourceTable timeZonesTable = value.getTable(status);
        if (U_FAILURE(status)) { return; }
        for (int32_t i = 0; timeZonesTable.getKeyAndValue(i, key, value); ++i) {
            U_ASSERT(!value.isNoInheritanceMarker());
            if (value.getType() == URES_TABLE) {
                consumeNamesTable(key, value, noFallback, status);
            } else {
                // Ignore fields that aren't tables (e.g., fallbackFormat and regionFormatStandard).
                // All time zone fields are tables.
            }
            if (U_FAILURE(status)) { return; }
        }
    }
};

// Virtual destructors must be defined out of line.
TimeZoneNamesImpl::ZoneStringsLoader::~ZoneStringsLoader() {
    uhash_close(keyToLoader);
}

void TimeZoneNamesImpl::loadAllDisplayNames(UErrorCode& status) {
    if (U_FAILURE(status)) return;

    {
        Mutex lock(&gDataMutex);
        internalLoadAllDisplayNames(status);
    }
}

void TimeZoneNamesImpl::getDisplayNames(const UnicodeString& tzID,
        const UTimeZoneNameType types[], int32_t numTypes,
        UDate date, UnicodeString dest[], UErrorCode& status) const {
    if (U_FAILURE(status)) return;

    if (tzID.isEmpty()) { return; }
    void* tznames = NULL;
    void* mznames = NULL;
    TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl*>(this);

    // Load the time zone strings
    {
        Mutex lock(&gDataMutex);
        tznames = (void*) nonConstThis->loadTimeZoneNames(tzID, status);
        if (U_FAILURE(status)) { return; }
    }
    U_ASSERT(tznames != NULL);

    // Load the values into the dest array
    for (int i = 0; i < numTypes; i++) {
        UTimeZoneNameType type = types[i];
        const UChar* name = ((ZNames*)tznames)->getName(type);
        if (name == NULL) {
            if (mznames == NULL) {
                // Load the meta zone name
                UnicodeString mzID;
                getMetaZoneID(tzID, date, mzID);
                if (mzID.isEmpty()) {
                    mznames = (void*) EMPTY;
                } else {
                    // Load the meta zone strings
                    // Mutex is scoped to the "else" statement
                    Mutex lock(&gDataMutex);
                    mznames = (void*) nonConstThis->loadMetaZoneNames(mzID, status);
                    if (U_FAILURE(status)) { return; }
                    // Note: when the metazone doesn't exist, in Java, loadMetaZoneNames returns
                    // a dummy object instead of NULL.
                    if (mznames == NULL) {
                        mznames = (void*) EMPTY;
                    }
                }
            }
            U_ASSERT(mznames != NULL);
            if (mznames != EMPTY) {
                name = ((ZNames*)mznames)->getName(type);
            }
        }
        if (name != NULL) {
            dest[i].setTo(TRUE, name, -1);
        } else {
            dest[i].setToBogus();
        }
    }
}

// Caller must synchronize.
void TimeZoneNamesImpl::internalLoadAllDisplayNames(UErrorCode& status) {
    if (!fNamesFullyLoaded) {
        fNamesFullyLoaded = TRUE;

        ZoneStringsLoader loader(*this, status);
        loader.load(status);
        if (U_FAILURE(status)) { return; }

        const UnicodeString *id;

        // load strings for all zones
        StringEnumeration *tzIDs = TimeZone::createTimeZoneIDEnumeration(
            UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status);
        if (U_SUCCESS(status)) {
            while ((id = tzIDs->snext(status)) != NULL) {
                if (U_FAILURE(status)) {
                    break;
                }
                UnicodeString copy(*id);
                void* value = uhash_get(fTZNamesMap, copy.getTerminatedBuffer());
                if (value == NULL) {
                    // loadStrings also loads related metazone strings
                    loadStrings(*id, status);
                }
            }
        }
        if (tzIDs != NULL) {
            delete tzIDs;
        }
    }
}



static const UChar gEtcPrefix[]         = { 0x45, 0x74, 0x63, 0x2F }; // "Etc/"
static const int32_t gEtcPrefixLen      = 4;
static const UChar gSystemVPrefix[]     = { 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x56, 0x2F }; // "SystemV/
static const int32_t gSystemVPrefixLen  = 8;
static const UChar gRiyadh8[]           = { 0x52, 0x69, 0x79, 0x61, 0x64, 0x68, 0x38 }; // "Riyadh8"
static const int32_t gRiyadh8Len       = 7;

UnicodeString& U_EXPORT2
TimeZoneNamesImpl::getDefaultExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) {
    if (tzID.isEmpty() || tzID.startsWith(gEtcPrefix, gEtcPrefixLen)
        || tzID.startsWith(gSystemVPrefix, gSystemVPrefixLen) || tzID.indexOf(gRiyadh8, gRiyadh8Len, 0) > 0) {
        name.setToBogus();
        return name;
    }

    int32_t sep = tzID.lastIndexOf((UChar)0x2F /* '/' */);
    if (sep > 0 && sep + 1 < tzID.length()) {
        name.setTo(tzID, sep + 1);
        name.findAndReplace(UnicodeString((UChar)0x5f /* _ */),
                            UnicodeString((UChar)0x20 /* space */));
    } else {
        name.setToBogus();
    }
    return name;
}

// ---------------------------------------------------
// TZDBTimeZoneNames and its supporting classes
//
// TZDBTimeZoneNames is an implementation class of
// TimeZoneNames holding the IANA tz database abbreviations.
// ---------------------------------------------------

class TZDBNames : public UMemory {
public:
    virtual ~TZDBNames();

    static TZDBNames* createInstance(UResourceBundle* rb, const char* key);
    const UChar* getName(UTimeZoneNameType type) const;
    const char** getParseRegions(int32_t& numRegions) const;

protected:
    TZDBNames(const UChar** names, char** regions, int32_t numRegions);

private:
    const UChar** fNames;
    char** fRegions;
    int32_t fNumRegions;
};

TZDBNames::TZDBNames(const UChar** names, char** regions, int32_t numRegions)
    :   fNames(names),
        fRegions(regions),
        fNumRegions(numRegions) {
}

TZDBNames::~TZDBNames() {
    if (fNames != NULL) {
        uprv_free(fNames);
    }
    if (fRegions != NULL) {
        char **p = fRegions;
        for (int32_t i = 0; i < fNumRegions; p++, i++) {
            uprv_free(*p);
        }
        uprv_free(fRegions);
    }
}

TZDBNames*
TZDBNames::createInstance(UResourceBundle* rb, const char* key) {
    if (rb == NULL || key == NULL || *key == 0) {
        return NULL;
    }

    UErrorCode status = U_ZERO_ERROR;

    const UChar **names = NULL;
    char** regions = NULL;
    int32_t numRegions = 0;

    int32_t len = 0;

    UResourceBundle* rbTable = NULL;
    rbTable = ures_getByKey(rb, key, rbTable, &status);
    if (U_FAILURE(status)) {
        return NULL;
    }

    names = (const UChar **)uprv_malloc(sizeof(const UChar*) * TZDBNAMES_KEYS_SIZE);
    UBool isEmpty = TRUE;
    if (names != NULL) {
        for (int32_t i = 0; i < TZDBNAMES_KEYS_SIZE; i++) {
            status = U_ZERO_ERROR;
            const UChar *value = ures_getStringByKey(rbTable, TZDBNAMES_KEYS[i], &len, &status);
            if (U_FAILURE(status) || len == 0) {
                names[i] = NULL;
            } else {
                names[i] = value;
                isEmpty = FALSE;
            }
        }
    }

    if (isEmpty) {
        if (names != NULL) {
            uprv_free(names);
        }
        return NULL;
    }

    UResourceBundle *regionsRes = ures_getByKey(rbTable, "parseRegions", NULL, &status);
    UBool regionError = FALSE;
    if (U_SUCCESS(status)) {
        numRegions = ures_getSize(regionsRes);
        if (numRegions > 0) {
            regions = (char**)uprv_malloc(sizeof(char*) * numRegions);
            if (regions != NULL) {
                char **pRegion = regions;
                for (int32_t i = 0; i < numRegions; i++, pRegion++) {
                    *pRegion = NULL;
                }
                // filling regions
                pRegion = regions;
                for (int32_t i = 0; i < numRegions; i++, pRegion++) {
                    status = U_ZERO_ERROR;
                    const UChar *uregion = ures_getStringByIndex(regionsRes, i, &len, &status);
                    if (U_FAILURE(status)) {
                        regionError = TRUE;
                        break;
                    }
                    *pRegion = (char*)uprv_malloc(sizeof(char) * (len + 1));
                    if (*pRegion == NULL) {
                        regionError = TRUE;
                        break;
                    }
                    u_UCharsToChars(uregion, *pRegion, len);
                    (*pRegion)[len] = 0;
                }
            }
        }
    }
    ures_close(regionsRes);
    ures_close(rbTable);

    if (regionError) {
        if (names != NULL) {
            uprv_free(names);
        }
        if (regions != NULL) {
            char **p = regions;
            for (int32_t i = 0; i < numRegions; p++, i++) {
                uprv_free(*p);
            }
            uprv_free(regions);
        }
        return NULL;
    }

    return new TZDBNames(names, regions, numRegions);
}

const UChar*
TZDBNames::getName(UTimeZoneNameType type) const {
    if (fNames == NULL) {
        return NULL;
    }
    const UChar *name = NULL;
    switch(type) {
    case UTZNM_SHORT_STANDARD:
        name = fNames[0];
        break;
    case UTZNM_SHORT_DAYLIGHT:
        name = fNames[1];
        break;
    default:
        name = NULL;
    }
    return name;
}

const char**
TZDBNames::getParseRegions(int32_t& numRegions) const {
    if (fRegions == NULL) {
        numRegions = 0;
    } else {
        numRegions = fNumRegions;
    }
    return (const char**)fRegions;
}

U_CDECL_BEGIN
/**
 * TZDBNameInfo stores metazone name information for the IANA abbreviations
 * in the trie
 */
typedef struct TZDBNameInfo {
    const UChar*        mzID;
    UTimeZoneNameType   type;
    UBool               ambiguousType;
    const char**        parseRegions;
    int32_t             nRegions;
} TZDBNameInfo;
U_CDECL_END


class TZDBNameSearchHandler : public TextTrieMapSearchResultHandler {
public:
    TZDBNameSearchHandler(uint32_t types, const char* region);
    virtual ~TZDBNameSearchHandler();

    UBool handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) override;
    TimeZoneNames::MatchInfoCollection* getMatches(int32_t& maxMatchLen);

private:
    uint32_t fTypes;
    int32_t fMaxMatchLen;
    TimeZoneNames::MatchInfoCollection* fResults;
    const char* fRegion;
};

TZDBNameSearchHandler::TZDBNameSearchHandler(uint32_t types, const char* region) 
: fTypes(types), fMaxMatchLen(0), fResults(NULL), fRegion(region) {
}

TZDBNameSearchHandler::~TZDBNameSearchHandler() {
    if (fResults != NULL) {
        delete fResults;
    }
}

UBool
TZDBNameSearchHandler::handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return FALSE;
    }

    TZDBNameInfo *match = NULL;
    TZDBNameInfo *defaultRegionMatch = NULL;

    if (node->hasValues()) {
        int32_t valuesCount = node->countValues();
        for (int32_t i = 0; i < valuesCount; i++) {
            TZDBNameInfo *ninfo = (TZDBNameInfo *)node->getValue(i);
            if (ninfo == NULL) {
                continue;
            }
            if ((ninfo->type & fTypes) != 0) {
                // Some tz database abbreviations are ambiguous. For example,
                // CST means either Central Standard Time or China Standard Time.
                // Unlike CLDR time zone display names, this implementation
                // does not use unique names. And TimeZoneFormat does not expect
                // multiple results returned for the same time zone type.
                // For this reason, this implementation resolve one among same
                // zone type with a same name at this level.
                if (ninfo->parseRegions == NULL) {
                    // parseRegions == null means this is the default metazone
                    // mapping for the abbreviation.
                    if (defaultRegionMatch == NULL) {
                        match = defaultRegionMatch = ninfo;
                    }
                } else {
                    UBool matchRegion = FALSE;
                    // non-default metazone mapping for an abbreviation
                    // comes with applicable regions. For example, the default
                    // metazone mapping for "CST" is America_Central,
                    // but if region is one of CN/MO/TW, "CST" is parsed
                    // as metazone China (China Standard Time).
                    for (int32_t j = 0; j < ninfo->nRegions; j++) {
                        const char *region = ninfo->parseRegions[j];
                        if (uprv_strcmp(fRegion, region) == 0) {
                            match = ninfo;
                            matchRegion = TRUE;
                            break;
                        }
                    }
                    if (matchRegion) {
                        break;
                    }
                    if (match == NULL) {
                        match = ninfo;
                    }
                }
            }
        }

        if (match != NULL) {
            UTimeZoneNameType ntype = match->type;
            // Note: Workaround for duplicated standard/daylight names
            // The tz database contains a few zones sharing a
            // same name for both standard time and daylight saving
            // time. For example, Australia/Sydney observes DST,
            // but "EST" is used for both standard and daylight.
            // When both SHORT_STANDARD and SHORT_DAYLIGHT are included
            // in the find operation, we cannot tell which one was
            // actually matched.
            // TimeZoneFormat#parse returns a matched name type (standard
            // or daylight) and DateFormat implementation uses the info to
            // to adjust actual time. To avoid false type information,
            // this implementation replaces the name type with SHORT_GENERIC.
            if (match->ambiguousType
                    && (ntype == UTZNM_SHORT_STANDARD || ntype == UTZNM_SHORT_DAYLIGHT)
                    && (fTypes & UTZNM_SHORT_STANDARD) != 0
                    && (fTypes & UTZNM_SHORT_DAYLIGHT) != 0) {
                ntype = UTZNM_SHORT_GENERIC;
            }

            if (fResults == NULL) {
                fResults = new TimeZoneNames::MatchInfoCollection();
                if (fResults == NULL) {
                    status = U_MEMORY_ALLOCATION_ERROR;
                }
            }
            if (U_SUCCESS(status)) {
                U_ASSERT(fResults != NULL);
                U_ASSERT(match->mzID != NULL);
                fResults->addMetaZone(ntype, matchLength, UnicodeString(match->mzID, -1), status);
                if (U_SUCCESS(status) && matchLength > fMaxMatchLen) {
                    fMaxMatchLen = matchLength;
                }
            }
        }
    }
    return TRUE;
}

TimeZoneNames::MatchInfoCollection*
TZDBNameSearchHandler::getMatches(int32_t& maxMatchLen) {
    // give the ownership to the caller
    TimeZoneNames::MatchInfoCollection* results = fResults;
    maxMatchLen = fMaxMatchLen;

    // reset
    fResults = NULL;
    fMaxMatchLen = 0;
    return results;
}

U_CDECL_BEGIN
/**
 * Deleter for TZDBNames
 */
static void U_CALLCONV
deleteTZDBNames(void *obj) {
    if (obj != EMPTY) {
        delete (TZDBNames *)obj;
    }
}

static void U_CALLCONV initTZDBNamesMap(UErrorCode &status) {
    gTZDBNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status);
    if (U_FAILURE(status)) {
        gTZDBNamesMap = NULL;
        return;
    }
    // no key deleters for tzdb name maps
    uhash_setValueDeleter(gTZDBNamesMap, deleteTZDBNames);
    ucln_i18n_registerCleanup(UCLN_I18N_TZDBTIMEZONENAMES, tzdbTimeZoneNames_cleanup);
}

/**
 * Deleter for TZDBNameInfo
 */
static void U_CALLCONV
deleteTZDBNameInfo(void *obj) {
    if (obj != NULL) {
        uprv_free(obj);
    }
}

static void U_CALLCONV prepareFind(UErrorCode &status) {
    if (U_FAILURE(status)) {
        return;
    }
    gTZDBNamesTrie = new TextTrieMap(TRUE, deleteTZDBNameInfo);
    if (gTZDBNamesTrie == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }

    const UnicodeString *mzID;
    StringEnumeration *mzIDs = TimeZoneNamesImpl::_getAvailableMetaZoneIDs(status);
    if (U_SUCCESS(status)) {
        while ((mzID = mzIDs->snext(status)) != 0 && U_SUCCESS(status)) {
            const TZDBNames *names = TZDBTimeZoneNames::getMetaZoneNames(*mzID, status);
            if (U_FAILURE(status)) {
                break;
            }
            if (names == NULL) {
                continue;
            }
            const UChar *std = names->getName(UTZNM_SHORT_STANDARD);
            const UChar *dst = names->getName(UTZNM_SHORT_DAYLIGHT);
            if (std == NULL && dst == NULL) {
                continue;
            }
            int32_t numRegions = 0;
            const char **parseRegions = names->getParseRegions(numRegions);

            // The tz database contains a few zones sharing a
            // same name for both standard time and daylight saving
            // time. For example, Australia/Sydney observes DST,
            // but "EST" is used for both standard and daylight.
            // we need to store the information for later processing.
            UBool ambiguousType = (std != NULL && dst != NULL && u_strcmp(std, dst) == 0);

            const UChar *uMzID = ZoneMeta::findMetaZoneID(*mzID);
            if (std != NULL) {
                TZDBNameInfo *stdInf = (TZDBNameInfo *)uprv_malloc(sizeof(TZDBNameInfo));
                if (stdInf == NULL) {
                    status = U_MEMORY_ALLOCATION_ERROR;
                    break;
                }
                stdInf->mzID = uMzID;
                stdInf->type = UTZNM_SHORT_STANDARD;
                stdInf->ambiguousType = ambiguousType;
                stdInf->parseRegions = parseRegions;
                stdInf->nRegions = numRegions;
                gTZDBNamesTrie->put(std, stdInf, status);
            }
            if (U_SUCCESS(status) && dst != NULL) {
                TZDBNameInfo *dstInf = (TZDBNameInfo *)uprv_malloc(sizeof(TZDBNameInfo));
                if (dstInf == NULL) {
                    status = U_MEMORY_ALLOCATION_ERROR;
                    break;
                }
                dstInf->mzID = uMzID;
                dstInf->type = UTZNM_SHORT_DAYLIGHT;
                dstInf->ambiguousType = ambiguousType;
                dstInf->parseRegions = parseRegions;
                dstInf->nRegions = numRegions;
                gTZDBNamesTrie->put(dst, dstInf, status);
            }
        }
    }
    delete mzIDs;

    if (U_FAILURE(status)) {
        delete gTZDBNamesTrie;
        gTZDBNamesTrie = NULL;
        return;
    }

    ucln_i18n_registerCleanup(UCLN_I18N_TZDBTIMEZONENAMES, tzdbTimeZoneNames_cleanup);
}

U_CDECL_END

TZDBTimeZoneNames::TZDBTimeZoneNames(const Locale& locale)
: fLocale(locale) {
    UBool useWorld = TRUE;
    const char* region = fLocale.getCountry();
    int32_t regionLen = static_cast<int32_t>(uprv_strlen(region));
    if (regionLen == 0) {
        UErrorCode status = U_ZERO_ERROR;
        CharString loc;
        {
            CharStringByteSink sink(&loc);
            ulocimp_addLikelySubtags(fLocale.getName(), sink, &status);
        }
        regionLen = uloc_getCountry(loc.data(), fRegion, sizeof(fRegion), &status);
        if (U_SUCCESS(status) && regionLen < (int32_t)sizeof(fRegion)) {
            useWorld = FALSE;
        }
    } else if (regionLen < (int32_t)sizeof(fRegion)) {
        uprv_strcpy(fRegion, region);
        useWorld = FALSE;
    }
    if (useWorld) {
        uprv_strcpy(fRegion, "001");
    }
}

TZDBTimeZoneNames::~TZDBTimeZoneNames() {
}

bool
TZDBTimeZoneNames::operator==(const TimeZoneNames& other) const {
    if (this == &other) {
        return true;
    }
    // No implementation for now
    return false;
}

TZDBTimeZoneNames*
TZDBTimeZoneNames::clone() const {
    return new TZDBTimeZoneNames(fLocale);
}

StringEnumeration*
TZDBTimeZoneNames::getAvailableMetaZoneIDs(UErrorCode& status) const {
    return TimeZoneNamesImpl::_getAvailableMetaZoneIDs(status);
}

StringEnumeration*
TZDBTimeZoneNames::getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const {
    return TimeZoneNamesImpl::_getAvailableMetaZoneIDs(tzID, status);
}

UnicodeString&
TZDBTimeZoneNames::getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const {
    return TimeZoneNamesImpl::_getMetaZoneID(tzID, date, mzID);
}

UnicodeString&
TZDBTimeZoneNames::getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const {
    return TimeZoneNamesImpl::_getReferenceZoneID(mzID, region, tzID);
}

UnicodeString&
TZDBTimeZoneNames::getMetaZoneDisplayName(const UnicodeString& mzID,
                                          UTimeZoneNameType type,
                                          UnicodeString& name) const {
    name.setToBogus();
    if (mzID.isEmpty()) {
        return name;
    }

    UErrorCode status = U_ZERO_ERROR;
    const TZDBNames *tzdbNames = TZDBTimeZoneNames::getMetaZoneNames(mzID, status);
    if (U_SUCCESS(status)) {
        if (tzdbNames != NULL) {
            const UChar *s = tzdbNames->getName(type);
            if (s != NULL) {
                name.setTo(TRUE, s, -1);
            }
        }
    }

    return name;
}

UnicodeString&
TZDBTimeZoneNames::getTimeZoneDisplayName(const UnicodeString& /* tzID */, UTimeZoneNameType /* type */, UnicodeString& name) const {
    // No abbreviations associated a zone directly for now.
    name.setToBogus();
    return name;
}

TZDBTimeZoneNames::MatchInfoCollection*
TZDBTimeZoneNames::find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const {
    umtx_initOnce(gTZDBNamesTrieInitOnce, &prepareFind, status);
    if (U_FAILURE(status)) {
        return NULL;
    }

    TZDBNameSearchHandler handler(types, fRegion);
    gTZDBNamesTrie->search(text, start, (TextTrieMapSearchResultHandler *)&handler, status);
    if (U_FAILURE(status)) {
        return NULL;
    }
    int32_t maxLen = 0;
    return handler.getMatches(maxLen);
}

const TZDBNames*
TZDBTimeZoneNames::getMetaZoneNames(const UnicodeString& mzID, UErrorCode& status) {
    umtx_initOnce(gTZDBNamesMapInitOnce, &initTZDBNamesMap, status);
    if (U_FAILURE(status)) {
        return NULL;
    }

    TZDBNames* tzdbNames = NULL;

    UChar mzIDKey[ZID_KEY_MAX + 1];
    mzID.extract(mzIDKey, ZID_KEY_MAX + 1, status);
    U_ASSERT(status == U_ZERO_ERROR);   // already checked length above
    mzIDKey[mzID.length()] = 0;

    static UMutex gTZDBNamesMapLock;
    umtx_lock(&gTZDBNamesMapLock);
    {
        void *cacheVal = uhash_get(gTZDBNamesMap, mzIDKey);
        if (cacheVal == NULL) {
            UResourceBundle *zoneStringsRes = ures_openDirect(U_ICUDATA_ZONE, "tzdbNames", &status);
            zoneStringsRes = ures_getByKey(zoneStringsRes, gZoneStrings, zoneStringsRes, &status);
            if (U_SUCCESS(status)) {
                char key[ZID_KEY_MAX + 1];
                mergeTimeZoneKey(mzID, key);
                tzdbNames = TZDBNames::createInstance(zoneStringsRes, key);

                if (tzdbNames == NULL) {
                    cacheVal = (void *)EMPTY;
                } else {
                    cacheVal = tzdbNames;
                }
                // Use the persistent ID as the resource key, so we can
                // avoid duplications.
                // TODO: Is there a more efficient way, like intern() in Java?
                void* newKey = (void*) ZoneMeta::findMetaZoneID(mzID);
                if (newKey != NULL) {
                    uhash_put(gTZDBNamesMap, newKey, cacheVal, &status);
                    if (U_FAILURE(status)) {
                        if (tzdbNames != NULL) {
                            delete tzdbNames;
                            tzdbNames = NULL;
                        }
                    }
                } else {
                    // Should never happen with a valid input
                    if (tzdbNames != NULL) {
                        // It's not possible that we get a valid tzdbNames with unknown ID.
                        // But just in case..
                        delete tzdbNames;
                        tzdbNames = NULL;
                    }
                }
            }
            ures_close(zoneStringsRes);
        } else if (cacheVal != EMPTY) {
            tzdbNames = (TZDBNames *)cacheVal;
        }
    }
    umtx_unlock(&gTZDBNamesMapLock);

    return tzdbNames;
}

U_NAMESPACE_END


#endif /* #if !UCONFIG_NO_FORMATTING */

//eof
