/*
*******************************************************************************
* Copyright (C) 2007-2010, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*/

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "zstrfmt.h"

#include "unicode/ustring.h"
#include "unicode/putil.h"
#include "unicode/msgfmt.h"
#include "unicode/basictz.h"
#include "unicode/simpletz.h"
#include "unicode/rbtz.h"
#include "unicode/vtzone.h"

#include "uvector.h"
#include "cstring.h"
#include "cmemory.h"
#include "uresimp.h"
#include "zonemeta.h"
#include "olsontz.h"
#include "umutex.h"
#include "ucln_in.h"
#include "uassert.h"
#include "ureslocs.h"

/**
 * global ZoneStringFormatCache stuffs
 */
static UMTX gZSFCacheLock = NULL;
static U_NAMESPACE_QUALIFIER ZSFCache *gZoneStringFormatCache = NULL;

U_CDECL_BEGIN
/**
 * ZoneStringFormatCache cleanup callback func
 */
static UBool U_CALLCONV zoneStringFormat_cleanup(void)
{
    umtx_destroy(&gZSFCacheLock);
    if (gZoneStringFormatCache != NULL) {
        delete gZoneStringFormatCache;
        gZoneStringFormatCache = NULL;
    }
    gZoneStringFormatCache = NULL;
    return TRUE;
}

/**
 * Deleter for ZoneStringInfo
 */
static void U_CALLCONV
deleteZoneStringInfo(void *obj) {
    delete (U_NAMESPACE_QUALIFIER ZoneStringInfo*)obj;
}

/**
 * Deleter for ZoneStrings
 */
static void U_CALLCONV
deleteZoneStrings(void *obj) {
    delete (U_NAMESPACE_QUALIFIER ZoneStrings*)obj;
}
U_CDECL_END

U_NAMESPACE_BEGIN

#define ZID_KEY_MAX 128

static const char gCountriesTag[]       = "Countries";
static const char gZoneStringsTag[]     = "zoneStrings";
static const char gShortGenericTag[]    = "sg";
static const char gShortStandardTag[]   = "ss";
static const char gShortDaylightTag[]   = "sd";
static const char gLongGenericTag[]     = "lg";
static const char gLongStandardTag[]    = "ls";
static const char gLongDaylightTag[]    = "ld";
static const char gExemplarCityTag[]    = "ec";
static const char gCommonlyUsedTag[]    = "cu";
static const char gFallbackFormatTag[]  = "fallbackFormat";
static const char gRegionFormatTag[]    = "regionFormat";

#define MZID_PREFIX_LEN 5
static const char gMetazoneIdPrefix[]   = "meta:";

#define MAX_METAZONES_PER_ZONE 10

static const UChar gDefFallbackPattern[]    = {0x7B, 0x31, 0x7D, 0x20, 0x28, 0x7B, 0x30, 0x7D, 0x29, 0x00}; // "{1} ({0})"
static const UChar gDefRegionPattern[]      = {0x7B, 0x30, 0x7D, 0x00}; // "{0}"
static const UChar gCommonlyUsedTrue[]      = {0x31, 0x00}; // "1"

static const double kDstCheckRange      = (double)184*U_MILLIS_PER_DAY;

static int32_t
getTimeZoneTranslationTypeIndex(TimeZoneTranslationType type) {
    int32_t typeIdx = 0;
    switch (type) {
        case LOCATION:
            typeIdx = ZSIDX_LOCATION;
            break;
        case GENERIC_LONG:
            typeIdx = ZSIDX_LONG_GENERIC;
            break;
        case GENERIC_SHORT:
            typeIdx = ZSIDX_SHORT_GENERIC;
            break;
        case STANDARD_LONG:
            typeIdx = ZSIDX_LONG_STANDARD;
            break;
        case STANDARD_SHORT:
            typeIdx = ZSIDX_SHORT_STANDARD;
            break;
        case DAYLIGHT_LONG:
            typeIdx = ZSIDX_LONG_DAYLIGHT;
            break;
        case DAYLIGHT_SHORT:
            typeIdx = ZSIDX_SHORT_DAYLIGHT;
            break;
    }
    return typeIdx;
}

static int32_t
getTimeZoneTranslationType(TimeZoneTranslationTypeIndex typeIdx) {
    int32_t type = 0;
    switch (typeIdx) {
        case ZSIDX_LOCATION:
            type = LOCATION;
            break;
        case ZSIDX_LONG_GENERIC:
            type = GENERIC_LONG;
            break;
        case ZSIDX_SHORT_GENERIC:
            type = GENERIC_SHORT;
            break;
        case ZSIDX_LONG_STANDARD:
            type = STANDARD_LONG;
            break;
        case ZSIDX_SHORT_STANDARD:
            type = STANDARD_SHORT;
            break;
        case ZSIDX_LONG_DAYLIGHT:
            type = DAYLIGHT_LONG;
            break;
        case ZSIDX_COUNT:
        case ZSIDX_SHORT_DAYLIGHT:
            type = DAYLIGHT_SHORT;
            break;
        default:
            break;
    }
    return type;
}

#define DEFAULT_CHARACTERNODE_CAPACITY 1

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

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

void
CharacterNode::addValue(void *value, UErrorCode &status) {
    if (U_FAILURE(status)) {
        deleteZoneStringInfo(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.
            UVector *values = new UVector(deleteZoneStringInfo, NULL, DEFAULT_CHARACTERNODE_CAPACITY, status);
            if (U_FAILURE(status)) {
                deleteZoneStringInfo(value);
                return;
            }
            values->addElement(fValues, status);
            fValues = values;
            fHasValuesVector = TRUE;
        }
        // Add the new value.
        ((UVector *)fValues)->addElement(value, status);
    }
}

//----------------------------------------------------------------------------
// Virtual destructor to avoid warning
TextTrieMapSearchResultHandler::~TextTrieMapSearchResultHandler(){
}

// ----------------------------------------------------------------------------
TextTrieMap::TextTrieMap(UBool ignoreCase)
: fIgnoreCase(ignoreCase), fNodes(NULL), fNodesCapacity(0), fNodesCount(0), 
  fLazyContents(NULL), fIsEmpty(TRUE) {
}

TextTrieMap::~TextTrieMap() {
    int32_t index;
    for (index = 0; index < fNodesCount; ++index) {
        fNodes[index].deleteValues();
    }
    uprv_free(fNodes);
    if (fLazyContents != NULL) {
        for (int32_t i=0; i<fLazyContents->size(); i+=2) {
            ZoneStringInfo *zsinf = (ZoneStringInfo *)fLazyContents->elementAt(i+1);
            delete zsinf;
        } 
        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, ZSFStringPool &sp, UErrorCode &status) {
    fIsEmpty = FALSE;
    if (fLazyContents == NULL) {
        fLazyContents = new UVector(status);
        if (fLazyContents == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
        }
    }
    if (U_FAILURE(status)) {
        return;
    }
    UChar *s = const_cast<UChar *>(sp.get(key, status));
    fLazyContents->addElement(s, status);
    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));
        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, 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;
}

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

// 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) {
    umtx_lock(&TextTrieMutex);
    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; 
    }
    umtx_unlock(&TextTrieMutex);
}


void
TextTrieMap::search(const UnicodeString &text, int32_t start,
                  TextTrieMapSearchResultHandler *handler, UErrorCode &status) const {
    UBool trieNeedsInitialization = FALSE;
    UMTX_CHECK(&TextTrieMutex, fLazyContents != NULL, trieNeedsInitialization);
    if (trieNeedsInitialization) {
        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;
        }
    }
    UChar32 c = text.char32At(index);
    if (fIgnoreCase) {
        // size of character may grow after fold operation
        UnicodeString tmp(c);
        tmp.foldCase();
        int32_t tmpidx = 0;
        while (tmpidx < tmp.length()) {
            c = tmp.char32At(tmpidx);
            node = getChildNode(node, c);
            if (node == NULL) {
                break;
            }
            tmpidx = tmp.moveIndex32(tmpidx, 1);
        }
    } else {
        node = getChildNode(node, c);
    }
    if (node != NULL) {
        search(node, text, start, index+1, handler, status);
    }
}

// ----------------------------------------------------------------------------
ZoneStringInfo::ZoneStringInfo(const UnicodeString &id, const UnicodeString &str,
                               TimeZoneTranslationType type, ZSFStringPool &sp, UErrorCode &status)
: fType(type) {
    fId = sp.get(id, status);
    fStr = sp.get(str, status);
}

ZoneStringInfo::~ZoneStringInfo() {
}


// ----------------------------------------------------------------------------
ZoneStringSearchResultHandler::ZoneStringSearchResultHandler(UErrorCode &status)
: fResults(status)
{
    clear();
}

ZoneStringSearchResultHandler::~ZoneStringSearchResultHandler() {
    clear();
}

UBool
ZoneStringSearchResultHandler::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++) {
            ZoneStringInfo *zsinfo = (ZoneStringInfo*)node->getValue(i);
            if (zsinfo == NULL) {
                break;
            }
            // Update the results
            UBool foundType = FALSE;
            for (int32_t j = 0; j < fResults.size(); j++) {
                ZoneStringInfo *tmp = (ZoneStringInfo*)fResults.elementAt(j);
                if (zsinfo->fType == tmp->fType) {
                    int32_t lenidx = getTimeZoneTranslationTypeIndex(tmp->fType);
                    if (matchLength > fMatchLen[lenidx]) {
                        // Same type, longer match
                        fResults.setElementAt(zsinfo, j);
                        fMatchLen[lenidx] = matchLength;
                    }
                    foundType = TRUE;
                    break;
                }
            }
            if (!foundType) {
                // not found in the current list
                fResults.addElement(zsinfo, status);
                fMatchLen[getTimeZoneTranslationTypeIndex(zsinfo->fType)] = matchLength;
            }
        }
    }
    return TRUE;
}

int32_t
ZoneStringSearchResultHandler::countMatches(void) {
    return fResults.size();
}

const ZoneStringInfo*
ZoneStringSearchResultHandler::getMatch(int32_t index, int32_t &matchLength) {
    ZoneStringInfo *zsinfo = NULL;
    if (index < fResults.size()) {
        zsinfo = (ZoneStringInfo*)fResults.elementAt(index);
        matchLength = fMatchLen[getTimeZoneTranslationTypeIndex(zsinfo->fType)];
    }
    return zsinfo;
}

void
ZoneStringSearchResultHandler::clear(void) {
    fResults.removeAllElements();
    for (int32_t i = 0; i < (int32_t)(sizeof(fMatchLen)/sizeof(fMatchLen[0])); i++) {
        fMatchLen[i] = 0;
    }
}
// ----------------------------------------------------------------------------
ZoneStringFormat::ZoneStringFormat(const UnicodeString* const* strings,
                                   int32_t rowCount, int32_t columnCount, UErrorCode &status)
: fLocale(""),
  fTzidToStrings(NULL),
  fMzidToStrings(NULL),
  fZoneStringsTrie(TRUE),
  fStringPool(status),
  fZoneStringsArray(NULL),
  fMetazoneItem(NULL),
  fZoneItem(NULL)
{
    if (U_FAILURE(status)) {
        return;
    }
    fLocale.setToBogus();
    if (strings == NULL || columnCount <= 0 || rowCount <= 0) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    fTzidToStrings = uhash_open(uhash_hashUChars,     // key hash function
                                uhash_compareUChars,  // key comparison function
                                NULL,                 // Value comparison function
                                &status);
    fMzidToStrings = uhash_open(uhash_hashUChars,   
                                uhash_compareUChars,
                                NULL,
                                &status);

    uhash_setValueDeleter(fTzidToStrings, deleteZoneStrings);
    uhash_setValueDeleter(fMzidToStrings, deleteZoneStrings);

    for (int32_t row = 0; row < rowCount; row++) {
        if (strings[row][0].isEmpty()) {
            continue;
        }
        UnicodeString *names = new UnicodeString[ZSIDX_COUNT];
        for (int32_t col = 1; col < columnCount; col++) {
            if (!strings[row][col].isEmpty()) {
                int32_t typeIdx = -1;
                switch (col) {
                    case 1:
                        typeIdx = ZSIDX_LONG_STANDARD;
                        break;
                    case 2:
                        typeIdx = ZSIDX_SHORT_STANDARD;
                        break;
                    case 3:
                        typeIdx = ZSIDX_LONG_DAYLIGHT;
                        break;
                    case 4:
                        typeIdx = ZSIDX_SHORT_DAYLIGHT;
                        break;
                    case 5:
                        typeIdx = ZSIDX_LOCATION;
                        break;
                    case 6:
                        typeIdx = ZSIDX_LONG_GENERIC;
                        break;
                    case 7:
                        typeIdx = ZSIDX_SHORT_GENERIC;
                        break;
                }
                if (typeIdx != -1) {
                    names[typeIdx].setTo(strings[row][col]);

                    // Put the name into the trie
                    int32_t type = getTimeZoneTranslationType((TimeZoneTranslationTypeIndex)typeIdx);
                    ZoneStringInfo *zsinf = new ZoneStringInfo(strings[row][0], 
                                                               strings[row][col], 
                                                               (TimeZoneTranslationType)type, 
                                                               fStringPool,
                                                               status);
                    fZoneStringsTrie.put(strings[row][col], zsinf, fStringPool, status);
                    if (U_FAILURE(status)) {
                        delete zsinf;
                        goto error_cleanup;
                    }
                }
            }
        }
        // Note:  ZoneStrings constructor adopts and delete the names array.
        ZoneStrings *zstrings = new ZoneStrings(names, ZSIDX_COUNT, TRUE, NULL, 0, 0,
                                                fStringPool, status);
        UChar *utzid = const_cast<UChar *>(fStringPool.get(strings[row][0], status));
        uhash_put(fTzidToStrings, utzid, zstrings, &status);
        if (U_FAILURE(status)) {
            delete zstrings;
            goto error_cleanup;
        }
    }
    fStringPool.freeze();
    return;

error_cleanup:
    return;
}

ZoneStringFormat::ZoneStringFormat(const Locale &locale, UErrorCode &status)
: fLocale(locale),
  fTzidToStrings(NULL),
  fMzidToStrings(NULL),
  fZoneStringsTrie(TRUE),
  fStringPool(status),
  fZoneStringsArray(NULL),
  fMetazoneItem(NULL),
  fZoneItem(NULL)
{
    if (U_FAILURE(status)) {
        return;
    }
    fTzidToStrings = uhash_open(uhash_hashUChars,     // key hash function
                                uhash_compareUChars,  // key comparison function
                                NULL,                 // Value comparison function
                                &status);
    fMzidToStrings = uhash_open(uhash_hashUChars,     // key hash function
                                uhash_compareUChars,  // key comparison function
                                NULL,                 // Value comparison function
                                &status);
    uhash_setValueDeleter(fTzidToStrings, deleteZoneStrings);
    uhash_setValueDeleter(fMzidToStrings, deleteZoneStrings);

    fZoneStringsArray = ures_open(U_ICUDATA_ZONE, locale.getName(), &status);
    fZoneStringsArray = ures_getByKeyWithFallback(fZoneStringsArray, gZoneStringsTag, fZoneStringsArray, &status);
    if (U_FAILURE(status)) {
        // If no locale bundles are available, zoneStrings will be null.
        // We still want to go through the rest of zone strings initialization,
        // because generic location format is generated from tzid for the case.
        // The rest of code should work even zoneStrings is null.
        status = U_ZERO_ERROR;
        ures_close(fZoneStringsArray);
        fZoneStringsArray = NULL;
    }

    StringEnumeration *tzids = NULL;
    MessageFormat *fallbackFmt = NULL;
    MessageFormat *regionFmt = NULL;

    char zidkey[ZID_KEY_MAX];
    const UChar *zstrarray[ZSIDX_COUNT];
    const UChar *mzstrarray[ZSIDX_COUNT];
    UnicodeString mzPartialLoc[MAX_METAZONES_PER_ZONE][4];

    UnicodeString region;
    getRegion(region);

    fallbackFmt = getFallbackFormat(locale, status);
    if (U_FAILURE(status)) {
        goto error_cleanup;
    }
    regionFmt = getRegionFormat(locale, status);
    if (U_FAILURE(status)) {
        goto error_cleanup;
    }

    tzids = TimeZone::createEnumeration();
    const char *tzid;
    while ((tzid = tzids->next(NULL, status))) {
        if (U_FAILURE(status)) {
            goto error_cleanup;
        }
        // Skip non-canonical IDs
        UnicodeString utzid(tzid, -1, US_INV);
        UnicodeString canonicalID;
        TimeZone::getCanonicalID(utzid, canonicalID, status);
        if (U_FAILURE(status)) {
            // Ignore unknown ID - we should not get here, but just in case.
            status = U_ZERO_ERROR;
            continue;
        }
        if (utzid != canonicalID) {
            continue;
        }

        uprv_strcpy(zidkey, tzid);

        // Replace '/' with ':'
        char *pCity = NULL;
        char *p = zidkey;
        while (*p) {
            if (*p == '/') {
                *p = ':';
                pCity = p + 1;
            }
            p++;
        }

        if (fZoneStringsArray != NULL) {
            fZoneItem = ures_getByKeyWithFallback(fZoneStringsArray, zidkey, fZoneItem, &status);
            if (U_FAILURE(status)) {
                // If failed to open the zone item, create only location string
                ures_close(fZoneItem);
                fZoneItem = NULL;
                status = U_ZERO_ERROR;
            }
        }
        zstrarray[ZSIDX_LONG_STANDARD]  = getZoneStringFromBundle(fZoneItem, gLongStandardTag);
        zstrarray[ZSIDX_SHORT_STANDARD] = getZoneStringFromBundle(fZoneItem, gShortStandardTag);
        zstrarray[ZSIDX_LONG_DAYLIGHT]  = getZoneStringFromBundle(fZoneItem, gLongDaylightTag);
        zstrarray[ZSIDX_SHORT_DAYLIGHT] = getZoneStringFromBundle(fZoneItem, gShortDaylightTag);
        zstrarray[ZSIDX_LONG_GENERIC]   = getZoneStringFromBundle(fZoneItem, gLongGenericTag);
        zstrarray[ZSIDX_SHORT_GENERIC]  = getZoneStringFromBundle(fZoneItem, gShortGenericTag);

        // Compose location format string
        UnicodeString location;
        UnicodeString country;
        UnicodeString city;
        UnicodeString countryCode;
        ZoneMeta::getCanonicalCountry(utzid, countryCode);
        if (!countryCode.isEmpty()) {
            const UChar* tmpCity = getZoneStringFromBundle(fZoneItem, gExemplarCityTag);
            if (tmpCity != NULL) {
                city.setTo(TRUE, tmpCity, -1);
            } else {
                city.setTo(UnicodeString(pCity, -1, US_INV));
                // Replace '_' with ' '
                for (int32_t i = 0; i < city.length(); i++) {
                    if (city.charAt(i) == (UChar)0x5F /*'_'*/) {
                        city.setCharAt(i, (UChar)0x20 /*' '*/);
                    }
                }
            }
            getLocalizedCountry(countryCode, locale, country);
            UnicodeString singleCountry;
            ZoneMeta::getSingleCountry(utzid, singleCountry);
            FieldPosition fpos;
            if (singleCountry.isEmpty()) {
                Formattable params [] = {
                    Formattable(city),
                    Formattable(country)
                };
                fallbackFmt->format(params, 2, location, fpos, status);
            } else {
                // If the zone is only one zone in the country, do not add city
                Formattable params [] = {
                    Formattable(country)
                };
                regionFmt->format(params, 1, location, fpos, status);
            }
            if (U_FAILURE(status)) {
                goto error_cleanup;
            }

            zstrarray[ZSIDX_LOCATION] = location.getTerminatedBuffer();
        } else {
            if (uprv_strlen(tzid) > 4 && uprv_strncmp(tzid, "Etc/", 4) == 0) {
                // "Etc/xxx" is not associated with a specific location, so localized
                // GMT format is always used as generic location format.
                zstrarray[ZSIDX_LOCATION] = NULL;
            } else {
                // When a new time zone ID, which is actually associated with a specific
                // location, is added in tzdata, but the current CLDR data does not have
                // the information yet, ICU creates a generic location string based on
                // the ID.  This implementation supports canonical time zone round trip
                // with format pattern "VVVV".  See #6602 for the details.
                UnicodeString loc(utzid);
                int32_t slashIdx = loc.lastIndexOf((UChar)0x2f);
                if (slashIdx == -1) {
                    // A time zone ID without slash in the tz database is not
                    // associated with a specific location.  For instances,
                    // MET, CET, EET and WET fall into this category.
                    // In this case, we still use GMT format as fallback.
                    zstrarray[ZSIDX_LOCATION] = NULL;
                } else {
                    FieldPosition fpos;
                    Formattable params[] = {
                        Formattable(loc)
                    };
                    regionFmt->format(params, 1, location, fpos, status);
                    if (U_FAILURE(status)) {
                        goto error_cleanup;
                    }
                    zstrarray[ZSIDX_LOCATION] = location.getTerminatedBuffer();
                }
            }
        }

        UBool commonlyUsed = isCommonlyUsed(fZoneItem);

        // Resolve metazones used by this zone
        int32_t mzPartialLocIdx = 0;
        const UVector *metazoneMappings = ZoneMeta::getMetazoneMappings(utzid);
        if (metazoneMappings != NULL) {
            for (int32_t i = 0; i < metazoneMappings->size(); i++) {
                const OlsonToMetaMappingEntry *mzmap = 
                        (const OlsonToMetaMappingEntry*)metazoneMappings->elementAt(i);
                UnicodeString mzid(mzmap->mzid);
                const ZoneStrings *mzStrings = 
                    (const ZoneStrings*)uhash_get(fMzidToStrings, mzid.getTerminatedBuffer());
                if (mzStrings == NULL) {
                    // If the metazone strings are not yet processed, do it now.
                    char mzidkey[ZID_KEY_MAX];
                    uprv_strcpy(mzidkey, gMetazoneIdPrefix);
                    u_UCharsToChars(mzmap->mzid, mzidkey + MZID_PREFIX_LEN, u_strlen(mzmap->mzid) + 1);
                    fMetazoneItem = ures_getByKeyWithFallback(fZoneStringsArray, mzidkey, fMetazoneItem, &status);
                    if (U_FAILURE(status)) {
                        // No resources available for this metazone
                        // Resource bundle will be cleaned up after end of the loop.
                        status = U_ZERO_ERROR;
                        continue;
                    }
                    UBool mzCommonlyUsed = isCommonlyUsed(fMetazoneItem);
                    mzstrarray[ZSIDX_LONG_STANDARD] = getZoneStringFromBundle(fMetazoneItem, gLongStandardTag);
                    mzstrarray[ZSIDX_SHORT_STANDARD] = getZoneStringFromBundle(fMetazoneItem, gShortStandardTag);
                    mzstrarray[ZSIDX_LONG_DAYLIGHT] = getZoneStringFromBundle(fMetazoneItem, gLongDaylightTag);
                    mzstrarray[ZSIDX_SHORT_DAYLIGHT] = getZoneStringFromBundle(fMetazoneItem, gShortDaylightTag);
                    mzstrarray[ZSIDX_LONG_GENERIC] = getZoneStringFromBundle(fMetazoneItem, gLongGenericTag);
                    mzstrarray[ZSIDX_SHORT_GENERIC] = getZoneStringFromBundle(fMetazoneItem, gShortGenericTag);
                    mzstrarray[ZSIDX_LOCATION] = NULL;

                    int32_t lastNonNullIdx = ZSIDX_COUNT - 1;
                    while (lastNonNullIdx >= 0) {
                        if (mzstrarray[lastNonNullIdx] != NULL) {
                            break;
                        }
                        lastNonNullIdx--;
                    }
                    UnicodeString *strings_mz = NULL;
                    ZoneStrings *tmp_mzStrings = NULL;
                    if (lastNonNullIdx >= 0) {
                        // Create UnicodeString array and put strings to the zone string trie
                        strings_mz = new UnicodeString[lastNonNullIdx + 1];

                        UnicodeString preferredIdForLocale;
                        ZoneMeta::getZoneIdByMetazone(mzid, region, preferredIdForLocale);

                        for (int32_t typeidx = 0; typeidx <= lastNonNullIdx; typeidx++) {
                            if (mzstrarray[typeidx] != NULL) {
                                strings_mz[typeidx].setTo(TRUE, mzstrarray[typeidx], -1);

                                // Add a metazone string to the zone string trie
                                int32_t type = getTimeZoneTranslationType((TimeZoneTranslationTypeIndex)typeidx);
                                ZoneStringInfo *zsinfo = new ZoneStringInfo(
                                                                preferredIdForLocale, 
                                                                strings_mz[typeidx], 
                                                                (TimeZoneTranslationType)type, 
                                                                fStringPool,
                                                                status);
                                fZoneStringsTrie.put(strings_mz[typeidx], zsinfo, fStringPool, status);
                                if (U_FAILURE(status)) {
                                    delete []strings_mz;
                                    goto error_cleanup;
                                }
                            }
                        }
                        // Note: ZoneStrings constructor adopts and deletes the strings_mz array.
                        tmp_mzStrings = new ZoneStrings(strings_mz, lastNonNullIdx + 1, 
                                                        mzCommonlyUsed, NULL, 0, 0, fStringPool, status);
                    } else {
                        // Create ZoneStrings with empty contents
                        tmp_mzStrings = new ZoneStrings(NULL, 0, FALSE, NULL, 0, 0, fStringPool, status);
                    }

                    UChar *umzid = const_cast<UChar *>(fStringPool.get(mzid, status));
                    uhash_put(fMzidToStrings, umzid, tmp_mzStrings, &status);
                    if (U_FAILURE(status)) {
                        goto error_cleanup;
                    }

                    mzStrings = tmp_mzStrings;
                }

                // Compose generic partial location format
                UnicodeString lg;
                UnicodeString sg;

                mzStrings->getString(ZSIDX_LONG_GENERIC, lg);
                mzStrings->getString(ZSIDX_SHORT_GENERIC, sg);

                if (!lg.isEmpty() || !sg.isEmpty()) {
                    UBool addMzPartialLocationNames = TRUE;
                    for (int32_t j = 0; j < mzPartialLocIdx; j++) {
                        if (mzPartialLoc[j][0] == mzid) {
                            // already processed
                            addMzPartialLocationNames = FALSE;
                            break;
                        }
                    }
                    if (addMzPartialLocationNames) {
                        UnicodeString *locationPart = NULL;
                        // Check if the zone is the preferred zone for the territory associated with the zone
                        UnicodeString preferredID;
                        ZoneMeta::getZoneIdByMetazone(mzid, countryCode, preferredID);
                        if (utzid == preferredID) {
                            // Use country for the location
                            locationPart = &country;
                        } else {
                            // Use city for the location
                            locationPart = &city;
                        }
                        // Reset the partial location string array
                        mzPartialLoc[mzPartialLocIdx][0].setTo(mzid);
                        mzPartialLoc[mzPartialLocIdx][1].remove();
                        mzPartialLoc[mzPartialLocIdx][2].remove();
                        mzPartialLoc[mzPartialLocIdx][3].remove();

                        if (locationPart->length() != 0) {
                            FieldPosition fpos;
                            if (!lg.isEmpty()) {
                                Formattable params [] = {
                                    Formattable(*locationPart),
                                    Formattable(lg)
                                };
                                fallbackFmt->format(params, 2, mzPartialLoc[mzPartialLocIdx][1], fpos, status);
                            }
                            if (!sg.isEmpty()) {
                                Formattable params [] = {
                                    Formattable(*locationPart),
                                    Formattable(sg)
                                };
                                fallbackFmt->format(params, 2, mzPartialLoc[mzPartialLocIdx][2], fpos, status);
                                if (mzStrings->isShortFormatCommonlyUsed()) {
                                    mzPartialLoc[mzPartialLocIdx][3].setTo(TRUE, gCommonlyUsedTrue, -1);
                                }
                            }
                            if (U_FAILURE(status)) {
                                goto error_cleanup;
                            }
                        }
                        mzPartialLocIdx++;
                    }
                }
            }
        }
        // Collected names for a zone

        // Create UnicodeString array for localized zone strings
        int32_t lastIdx = ZSIDX_COUNT - 1;
        while (lastIdx >= 0) {
            if (zstrarray[lastIdx] != NULL) {
                break;
            }
            lastIdx--;
        }
        UnicodeString *strings = NULL;
        int32_t stringsCount = lastIdx + 1;

        if (stringsCount > 0) {
            strings = new UnicodeString[stringsCount];
            for (int32_t i = 0; i < stringsCount; i++) {
                if (zstrarray[i] != NULL) {
                    strings[i].setTo(zstrarray[i], -1);

                    // Add names to the trie
                    int32_t type = getTimeZoneTranslationType((TimeZoneTranslationTypeIndex)i);
                    ZoneStringInfo *zsinfo = new ZoneStringInfo(utzid, 
                                                                strings[i], 
                                                                (TimeZoneTranslationType)type,
                                                                fStringPool,
                                                                status);
                    fZoneStringsTrie.put(strings[i], zsinfo, fStringPool, status);
                    if (U_FAILURE(status)) {
                        delete zsinfo;
                        delete[] strings;
                        goto error_cleanup;
                    }
                }
            }
        }

        // Create UnicodeString array for generic partial location strings
        UnicodeString **genericPartialLocationNames = NULL;
        int32_t genericPartialRowCount = mzPartialLocIdx;
        int32_t genericPartialColCount = 4;

        if (genericPartialRowCount != 0) {
            genericPartialLocationNames = 
                     (UnicodeString**)uprv_malloc(genericPartialRowCount * sizeof(UnicodeString*));
            if (genericPartialLocationNames == NULL) {
                status = U_MEMORY_ALLOCATION_ERROR;
                delete[] strings;
                goto error_cleanup;
            }
            for (int32_t i = 0; i < genericPartialRowCount; i++) {
                genericPartialLocationNames[i] = new UnicodeString[genericPartialColCount];
                for (int32_t j = 0; j < genericPartialColCount; j++) {
                    genericPartialLocationNames[i][j].setTo(mzPartialLoc[i][j]);
                    // Add names to the trie
                    if ((j == 1 || j == 2) &&!genericPartialLocationNames[i][j].isEmpty()) {
                        ZoneStringInfo *zsinfo;
                        TimeZoneTranslationType type = (j == 1) ? GENERIC_LONG : GENERIC_SHORT;
                        zsinfo = new ZoneStringInfo(utzid, genericPartialLocationNames[i][j], type, 
                                                    fStringPool, status);
                        fZoneStringsTrie.put(genericPartialLocationNames[i][j], zsinfo, fStringPool, status);
                        if (U_FAILURE(status)) {
                            delete[] genericPartialLocationNames[i];
                            uprv_free(genericPartialLocationNames);
                            delete[] strings;
                            goto error_cleanup;
                        }
                    }
                }
            }
        }

        // Finally, create ZoneStrings instance and put it into the tzidToStinrgs map
        ZoneStrings *zstrings = new ZoneStrings(strings, stringsCount, commonlyUsed,
                                                genericPartialLocationNames, genericPartialRowCount, 
                                                genericPartialColCount, fStringPool, status);

        UChar *uutzid = const_cast<UChar *>(fStringPool.get(utzid, status));
        uhash_put(fTzidToStrings, uutzid, zstrings, &status);
        if (U_FAILURE(status)) {
            delete zstrings;
            goto error_cleanup;
        }
    }

error_cleanup:
    if (fallbackFmt != NULL) {
        delete fallbackFmt;
    }
    if (regionFmt != NULL) {
        delete regionFmt;
    }
    if (tzids != NULL) {
        delete tzids;
    }
    fStringPool.freeze();
}

ZoneStringFormat::~ZoneStringFormat() {
    uhash_close(fTzidToStrings);
    uhash_close(fMzidToStrings);
    ures_close(fZoneItem);
    ures_close(fMetazoneItem);
    ures_close(fZoneStringsArray);
}

SafeZoneStringFormatPtr*
ZoneStringFormat::getZoneStringFormat(const Locale& locale, UErrorCode &status) {
    umtx_lock(&gZSFCacheLock);
    if (gZoneStringFormatCache == NULL) {
        gZoneStringFormatCache = new ZSFCache(10 /* capacity */);
        ucln_i18n_registerCleanup(UCLN_I18N_ZSFORMAT, zoneStringFormat_cleanup);
    }
    umtx_unlock(&gZSFCacheLock);

    return gZoneStringFormatCache->get(locale, status);
}


UnicodeString**
ZoneStringFormat::createZoneStringsArray(UDate date, int32_t &rowCount, int32_t &colCount, UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return NULL;
    }
    UnicodeString **result = NULL;
    rowCount = 0;
    colCount = 0;

    // Collect canonical time zone IDs
    UVector canonicalIDs(uhash_deleteUnicodeString, uhash_compareUnicodeString, status);
    if (U_FAILURE(status)) {
        return NULL;
    }
    StringEnumeration *tzids = TimeZone::createEnumeration();
    const UChar *tzid;
    while ((tzid = tzids->unext(NULL, status))) {
        if (U_FAILURE(status)) {
            delete tzids;
            return NULL;
        }
        UnicodeString utzid(tzid);
        UnicodeString canonicalID;
        TimeZone::getCanonicalID(UnicodeString(tzid), canonicalID, status);
        if (U_FAILURE(status)) {
            // Ignore unknown ID - we should not get here, but just in case.
            status = U_ZERO_ERROR;
            continue;
        }
        if (utzid == canonicalID) {
            canonicalIDs.addElement(new UnicodeString(utzid), status);
            if (U_FAILURE(status)) {
                delete tzids;
                return NULL;
            }
        }
    }
    delete tzids;

    // Allocate array
    result = (UnicodeString**)uprv_malloc(canonicalIDs.size() * sizeof(UnicodeString*));
    if (result == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    for (int32_t i = 0; i < canonicalIDs.size(); i++) {
        result[i] = new UnicodeString[8];
        UnicodeString *id = (UnicodeString*)canonicalIDs.elementAt(i);
        result[i][0].setTo(*id);
        getLongStandard(*id, date, result[i][1]);
        getShortStandard(*id, date, FALSE, result[i][2]);
        getLongDaylight(*id, date, result[i][3]);
        getShortDaylight(*id, date, FALSE, result[i][4]);
        getGenericLocation(*id, result[i][5]);
        getLongGenericNonLocation(*id, date, result[i][6]);
        getShortGenericNonLocation(*id, date, FALSE, result[i][7]);
    }

    rowCount = canonicalIDs.size();
    colCount = 8;
    return result;
}

UnicodeString&
ZoneStringFormat::getSpecificLongString(const Calendar &cal, UnicodeString &result,
                                        UErrorCode &status) const {
    result.remove();
    if (U_FAILURE(status)) {
        return result;
    }
    UnicodeString tzid;
    cal.getTimeZone().getID(tzid);
    UDate date = cal.getTime(status);
    if (cal.get(UCAL_DST_OFFSET, status) == 0) {
        return getString(tzid, ZSIDX_LONG_STANDARD, date, FALSE /*not used*/, result);
    } else {
        return getString(tzid, ZSIDX_LONG_DAYLIGHT, date, FALSE /*not used*/, result);
    }
}

UnicodeString&
ZoneStringFormat::getSpecificShortString(const Calendar &cal, UBool commonlyUsedOnly,
                                         UnicodeString &result, UErrorCode &status) const {
    result.remove();
    if (U_FAILURE(status)) {
        return result;
    }
    UnicodeString tzid;
    cal.getTimeZone().getID(tzid);
    UDate date = cal.getTime(status);
    if (cal.get(UCAL_DST_OFFSET, status) == 0) {
        return getString(tzid, ZSIDX_SHORT_STANDARD, date, commonlyUsedOnly, result);
    } else {
        return getString(tzid, ZSIDX_SHORT_DAYLIGHT, date, commonlyUsedOnly, result);
    }
}

UnicodeString&
ZoneStringFormat::getGenericLongString(const Calendar &cal, UnicodeString &result,
                                       UErrorCode &status) const {
    return getGenericString(cal, FALSE /*long*/, FALSE /* not used */, result, status);
}

UnicodeString&
ZoneStringFormat::getGenericShortString(const Calendar &cal, UBool commonlyUsedOnly,
                                        UnicodeString &result, UErrorCode &status) const {
    return getGenericString(cal, TRUE /*short*/, commonlyUsedOnly, result, status);
}

UnicodeString&
ZoneStringFormat::getGenericLocationString(const Calendar &cal, UnicodeString &result,
                                           UErrorCode &status) const {
    UnicodeString tzid;
    cal.getTimeZone().getID(tzid);
    UDate date = cal.getTime(status);
    return getString(tzid, ZSIDX_LOCATION, date, FALSE /*not used*/, result);
}

const ZoneStringInfo*
ZoneStringFormat::findSpecificLong(const UnicodeString &text, int32_t start,
                                   int32_t &matchLength, UErrorCode &status) const {
    return find(text, start, STANDARD_LONG | DAYLIGHT_LONG, matchLength, status);
}

const ZoneStringInfo*
ZoneStringFormat::findSpecificShort(const UnicodeString &text, int32_t start,
                                    int32_t &matchLength, UErrorCode &status) const {
    return find(text, start, STANDARD_SHORT | DAYLIGHT_SHORT, matchLength, status);
}

const ZoneStringInfo*
ZoneStringFormat::findGenericLong(const UnicodeString &text, int32_t start,
                                  int32_t &matchLength, UErrorCode &status) const {
    return find(text, start, GENERIC_LONG | STANDARD_LONG | LOCATION, matchLength, status);
}

const ZoneStringInfo*
ZoneStringFormat::findGenericShort(const UnicodeString &text, int32_t start,
                                   int32_t &matchLength, UErrorCode &status) const {
    return find(text, start, GENERIC_SHORT | STANDARD_SHORT | LOCATION, matchLength, status);
}

const ZoneStringInfo*
ZoneStringFormat::findGenericLocation(const UnicodeString &text, int32_t start,
                                      int32_t &matchLength, UErrorCode &status) const {
    return find(text, start, LOCATION, matchLength, status);
}

UnicodeString&
ZoneStringFormat::getString(const UnicodeString &tzid, TimeZoneTranslationTypeIndex typeIdx, UDate date,
                            UBool commonlyUsedOnly, UnicodeString& result) const {
    result.remove();

    // ICU's own array does not have entries for aliases
    UnicodeString canonicalID;
    UErrorCode status = U_ZERO_ERROR;
    TimeZone::getCanonicalID(tzid, canonicalID, status);
    if (U_FAILURE(status)) {
        // Unknown ID, but users might have their own data.
        canonicalID.setTo(tzid);
    }

    if (uhash_count(fTzidToStrings) > 0) {
        ZoneStrings *zstrings = (ZoneStrings*)uhash_get(fTzidToStrings, canonicalID.getTerminatedBuffer());
        if (zstrings != NULL) {
            switch (typeIdx) {
                case ZSIDX_LONG_STANDARD:
                case ZSIDX_LONG_DAYLIGHT:
                case ZSIDX_LONG_GENERIC:
                case ZSIDX_LOCATION:
                    zstrings->getString(typeIdx, result);
                    break;
                case ZSIDX_SHORT_STANDARD:
                case ZSIDX_SHORT_DAYLIGHT:
                case ZSIDX_COUNT: //added to avoid warning
                case ZSIDX_SHORT_GENERIC:
                    if (!commonlyUsedOnly || zstrings->isShortFormatCommonlyUsed()) {
                        zstrings->getString(typeIdx, result);
                    }
                    break;
                default:
                    break;
            }
        }
    }
    if (result.isEmpty() && uhash_count(fMzidToStrings) > 0 && typeIdx != ZSIDX_LOCATION) {
        // Try metazone
        UnicodeString mzid;
        ZoneMeta::getMetazoneID(canonicalID, date, mzid);
        if (!mzid.isEmpty()) {
            ZoneStrings *mzstrings = (ZoneStrings*)uhash_get(fMzidToStrings, mzid.getTerminatedBuffer());
            if (mzstrings != NULL) {
                switch (typeIdx) {
                    case ZSIDX_LONG_STANDARD:
                    case ZSIDX_LONG_DAYLIGHT:
                    case ZSIDX_LONG_GENERIC:
                    case ZSIDX_LOCATION:
                        mzstrings->getString(typeIdx, result);
                        break;
                    case ZSIDX_SHORT_STANDARD:
                    case ZSIDX_SHORT_DAYLIGHT:
                    case ZSIDX_COUNT: //added to avoid warning
                    case ZSIDX_SHORT_GENERIC:
                        if (!commonlyUsedOnly || mzstrings->isShortFormatCommonlyUsed()) {
                            mzstrings->getString(typeIdx, result);
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }
    return result;
}

UnicodeString&
ZoneStringFormat::getGenericString(const Calendar &cal, UBool isShort, UBool commonlyUsedOnly,
                                   UnicodeString &result, UErrorCode &status) const {
    result.remove();
    UDate time = cal.getTime(status);
    if (U_FAILURE(status)) {
        return result;
    }
    const TimeZone &tz = cal.getTimeZone();
    UnicodeString tzid;
    tz.getID(tzid);

    // ICU's own array does not have entries for aliases
    UnicodeString canonicalID;
    TimeZone::getCanonicalID(tzid, canonicalID, status);
    if (U_FAILURE(status)) {
        // Unknown ID, but users might have their own data.
        status = U_ZERO_ERROR;
        canonicalID.setTo(tzid);
    }

    ZoneStrings *zstrings = NULL;
    if (uhash_count(fTzidToStrings) > 0) {
        zstrings = (ZoneStrings*)uhash_get(fTzidToStrings, canonicalID.getTerminatedBuffer());
        if (zstrings != NULL) {
            if (isShort) {
                if (!commonlyUsedOnly || zstrings->isShortFormatCommonlyUsed()) {
                    zstrings->getString(ZSIDX_SHORT_GENERIC, result);
                }
            } else {
                zstrings->getString(ZSIDX_LONG_GENERIC, result);
            }
        }
    }
    if (result.isEmpty() && uhash_count(fMzidToStrings) > 0) {
        // try metazone
        int32_t raw, sav;
        UnicodeString mzid;
        ZoneMeta::getMetazoneID(canonicalID, time, mzid);
        if (!mzid.isEmpty()) {
            UBool useStandard = FALSE;
            sav = cal.get(UCAL_DST_OFFSET, status);
            if (U_FAILURE(status)) {
                return result;
            }
            if (sav == 0) {
                useStandard = TRUE;
                // Check if the zone actually uses daylight saving time around the time
                TimeZone *tmptz = tz.clone();
                BasicTimeZone *btz = NULL;
                if (dynamic_cast<OlsonTimeZone *>(tmptz) != NULL
                    || dynamic_cast<SimpleTimeZone *>(tmptz) != NULL
                    || dynamic_cast<RuleBasedTimeZone *>(tmptz) != NULL
                    || dynamic_cast<VTimeZone *>(tmptz) != NULL) {
                    btz = (BasicTimeZone*)tmptz;
                }

                if (btz != NULL) {
                    TimeZoneTransition before;
                    UBool beforTrs = btz->getPreviousTransition(time, TRUE, before);
                    if (beforTrs
                            && (time - before.getTime() < kDstCheckRange)
                            && before.getFrom()->getDSTSavings() != 0) {
                        useStandard = FALSE;
                    } else {
                        TimeZoneTransition after;
                        UBool afterTrs = btz->getNextTransition(time, FALSE, after);
                        if (afterTrs
                                && (after.getTime() - time < kDstCheckRange)
                                && after.getTo()->getDSTSavings() != 0) {
                            useStandard = FALSE;
                        }
                    }
                } else {
                    // If not BasicTimeZone... only if the instance is not an ICU's implementation.
                    // We may get a wrong answer in edge case, but it should practically work OK.
                    tmptz->getOffset(time - kDstCheckRange, FALSE, raw, sav, status);
                    if (sav != 0) {
                        useStandard = FALSE;
                    } else {
                        tmptz->getOffset(time + kDstCheckRange, FALSE, raw, sav, status);
                        if (sav != 0){
                            useStandard = FALSE;
                        }
                    }
                    if (U_FAILURE(status)) {
                        delete tmptz;
                        result.remove();
                        return result;
                    }
                }
                delete tmptz;
            }
            if (useStandard) {
                getString(canonicalID, (isShort ? ZSIDX_SHORT_STANDARD : ZSIDX_LONG_STANDARD),
                    time, commonlyUsedOnly, result);

                // Note:
                // In CLDR 1.5.1, a same localization is used for both generic and standard
                // for some metazones in some locales.  This is actually data bugs and should
                // be resolved in later versions of CLDR.  For now, we check if the standard
                // name is different from its generic name below.
                if (!result.isEmpty()) {
                    UnicodeString genericNonLocation;
                    getString(canonicalID, (isShort ? ZSIDX_SHORT_GENERIC : ZSIDX_LONG_GENERIC),
                        time, commonlyUsedOnly, genericNonLocation);
                    if (!genericNonLocation.isEmpty() && result == genericNonLocation) {
                        result.remove();
                    }
                }
            }
            if (result.isEmpty()) {
                ZoneStrings *mzstrings = (ZoneStrings*)uhash_get(fMzidToStrings, mzid.getTerminatedBuffer());
                if (mzstrings != NULL) {
                    if (isShort) {
                        if (!commonlyUsedOnly || mzstrings->isShortFormatCommonlyUsed()) {
                            mzstrings->getString(ZSIDX_SHORT_GENERIC, result);
                        }
                    } else {
                        mzstrings->getString(ZSIDX_LONG_GENERIC, result);
                    }
                }
                if (!result.isEmpty()) {
                    // Check if the offsets at the given time matches the preferred zone's offsets
                    UnicodeString preferredId;
                    UnicodeString region;
                    ZoneMeta::getZoneIdByMetazone(mzid, getRegion(region), preferredId);
                    if (canonicalID != preferredId) {
                        // Check if the offsets at the given time are identical with the preferred zone
                        raw = cal.get(UCAL_ZONE_OFFSET, status);
                        if (U_FAILURE(status)) {
                            result.remove();
                            return result;
                        }
                        TimeZone *preferredZone = TimeZone::createTimeZone(preferredId);
                        int32_t prfRaw, prfSav;
                        // Check offset in preferred time zone with wall time.
                        // With getOffset(time, false, preferredOffsets),
                        // you may get incorrect results because of time overlap at DST->STD
                        // transition.
                        preferredZone->getOffset(time + raw + sav, TRUE, prfRaw, prfSav, status);
                        delete preferredZone;

                        if (U_FAILURE(status)) {
                            result.remove();
                            return result;
                        }
                        if ((raw != prfRaw || sav != prfSav) && zstrings != NULL) {
                            // Use generic partial location string as fallback
                            zstrings->getGenericPartialLocationString(mzid, isShort, commonlyUsedOnly, result);
                        }
                    }
                }
            }
        }
    }
    if (result.isEmpty()) {
        // Use location format as the final fallback
        getString(canonicalID, ZSIDX_LOCATION, time, FALSE /*not used*/, result);
    }

    return result;
}

UnicodeString&
ZoneStringFormat::getGenericPartialLocationString(const UnicodeString &tzid, UBool isShort,
                                                  UDate date, UBool commonlyUsedOnly, UnicodeString &result) const {
    result.remove();
    if (uhash_count(fTzidToStrings) <= 0) {
        return result;
    }

    UnicodeString canonicalID;
    UErrorCode status = U_ZERO_ERROR;
    TimeZone::getCanonicalID(tzid, canonicalID, status);
    if (U_FAILURE(status)) {
        // Unknown ID, so no corresponding meta data.
        return result;
    }

    UnicodeString mzid;
    ZoneMeta::getMetazoneID(canonicalID, date, mzid);

    if (!mzid.isEmpty()) {
        ZoneStrings *zstrings = (ZoneStrings*)uhash_get(fTzidToStrings, canonicalID.getTerminatedBuffer());
        if (zstrings != NULL) {
            zstrings->getGenericPartialLocationString(mzid, isShort, commonlyUsedOnly, result);
        }
    }
    return result;
}

const ZoneStringInfo*
ZoneStringFormat::find(const UnicodeString &text, int32_t start, int32_t types,
                       int32_t &matchLength, UErrorCode &status) const {
    matchLength = 0;
    if (U_FAILURE(status)) {
        return NULL;
    }
    if (fZoneStringsTrie.isEmpty()) {
        return NULL;
    }
    const ZoneStringInfo *result = NULL;
    const ZoneStringInfo *fallback = NULL;
    int32_t fallbackMatchLen = 0;

    ZoneStringSearchResultHandler handler(status);
    fZoneStringsTrie.search(text, start, (TextTrieMapSearchResultHandler*)&handler, status);
    if (U_SUCCESS(status)) {
        int32_t numMatches = handler.countMatches();
        for (int32_t i = 0; i < numMatches; i++) {
            int32_t tmpMatchLen = 0; // init. output only param to silence gcc
            const ZoneStringInfo *tmp = handler.getMatch(i, tmpMatchLen);
            if ((types & tmp->fType) != 0) {
                if (result == NULL || matchLength < tmpMatchLen) {
                    result = tmp;
                    matchLength = tmpMatchLen;
                } else if (matchLength == tmpMatchLen) {
                    // Tie breaker - there are some examples that a
                    // long standard name is identical with a location
                    // name - for example, "Uruguay Time".  In this case,
                    // we interpret it as generic, not specific.
                    if (tmp->isGeneric() && !result->isGeneric()) {
                        result = tmp;
                    }
                }
            } else if (result == NULL) {
                if (fallback == NULL || fallbackMatchLen < tmpMatchLen) {
                    fallback = tmp;
                    fallbackMatchLen = tmpMatchLen;
                } else if (fallbackMatchLen == tmpMatchLen) {
                    if (tmp->isGeneric() && !fallback->isGeneric()) {
                        fallback = tmp;
                    }
                }
            }
        }
        if (result == NULL && fallback != NULL) {
            result = fallback;
            matchLength = fallbackMatchLen;
        }
    }
    return result;
}


UnicodeString&
ZoneStringFormat::getRegion(UnicodeString &region) const {
    const char* country = fLocale.getCountry();
    // TODO: Utilize addLikelySubtag in Locale to resolve default region
    // when the implementation is ready.
    region.setTo(UnicodeString(country, -1, US_INV));
    return region;
}

MessageFormat*
ZoneStringFormat::getFallbackFormat(const Locale &locale, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    UnicodeString pattern(TRUE, gDefFallbackPattern, -1);
    UResourceBundle *zoneStringsArray = ures_open(U_ICUDATA_ZONE, locale.getName(), &status);
    zoneStringsArray = ures_getByKeyWithFallback(zoneStringsArray, gZoneStringsTag, zoneStringsArray, &status);
    int32_t len;
    const UChar *flbkfmt = ures_getStringByKeyWithFallback(zoneStringsArray, gFallbackFormatTag, &len, &status);
    if (U_SUCCESS(status)) {
        pattern.setTo(flbkfmt);
    } else {
        status = U_ZERO_ERROR;
    }
    ures_close(zoneStringsArray);

    MessageFormat *fallbackFmt = new MessageFormat(pattern, status);
    return fallbackFmt;
}

MessageFormat*
ZoneStringFormat::getRegionFormat(const Locale& locale, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    UnicodeString pattern(TRUE, gDefRegionPattern, -1);
    UResourceBundle *zoneStringsArray = ures_open(U_ICUDATA_ZONE, locale.getName(), &status);
    zoneStringsArray = ures_getByKeyWithFallback(zoneStringsArray, gZoneStringsTag, zoneStringsArray, &status);
    int32_t len;
    const UChar *regionfmt = ures_getStringByKeyWithFallback(zoneStringsArray, gRegionFormatTag, &len, &status);
    if (U_SUCCESS(status)) {
        pattern.setTo(regionfmt);
    } else {
        status = U_ZERO_ERROR;
    }
    ures_close(zoneStringsArray);

    MessageFormat *regionFmt = new MessageFormat(pattern, status);
    return regionFmt;
}

const UChar*
ZoneStringFormat::getZoneStringFromBundle(const UResourceBundle *zoneitem, const char *key) {
    const UChar *str = NULL;
    if (zoneitem != NULL) {
        UErrorCode status = U_ZERO_ERROR;
        int32_t len;
        str = ures_getStringByKeyWithFallback(zoneitem, key, &len, &status);
        str = fStringPool.adopt(str, status);
        if (U_FAILURE(status)) {
            str = NULL;
        }
    }
    return str;
}

UBool
ZoneStringFormat::isCommonlyUsed(const UResourceBundle *zoneitem) {
    if (zoneitem == NULL) {
        return TRUE;
    }

    UBool commonlyUsed = FALSE;
    UErrorCode status = U_ZERO_ERROR;
    UResourceBundle *cuRes = ures_getByKey(zoneitem, gCommonlyUsedTag, NULL, &status);
    int32_t cuValue = ures_getInt(cuRes, &status);
    if (U_SUCCESS(status)) {
        if (cuValue == 1) {
            commonlyUsed = TRUE;
        }
    }
    ures_close(cuRes);
    return commonlyUsed;
}

UnicodeString&
ZoneStringFormat::getLocalizedCountry(const UnicodeString &countryCode, const Locale &locale, UnicodeString &displayCountry) {
    // We do not want to use display country names only from the target language bundle
    // Note: we should do this in better way.
    displayCountry.remove();
    int32_t ccLen = countryCode.length();
    if (ccLen > 0 && ccLen < ULOC_COUNTRY_CAPACITY) {
        UErrorCode status = U_ZERO_ERROR;
        UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &status);
        if (U_SUCCESS(status)) {
            const char *bundleLocStr = ures_getLocale(localeBundle, &status);
            if (U_SUCCESS(status) && uprv_strlen(bundleLocStr) > 0) {
                Locale bundleLoc(bundleLocStr);
                if (uprv_strcmp(bundleLocStr, "root") != 0 && 
                    uprv_strcmp(bundleLoc.getLanguage(), locale.getLanguage()) == 0) {
                    // Create a fake locale strings
                    char tmpLocStr[ULOC_COUNTRY_CAPACITY + 3];
                    uprv_strcpy(tmpLocStr, "xx_");
                    u_UCharsToChars(countryCode.getBuffer(), &tmpLocStr[3], ccLen);
                    tmpLocStr[3 + ccLen] = 0;

                    Locale tmpLoc(tmpLocStr);
                    tmpLoc.getDisplayCountry(locale, displayCountry);
                }
            }
        }
        ures_close(localeBundle);
    }
    if (displayCountry.isEmpty()) {
        // Use the country code as the fallback
        displayCountry.setTo(countryCode);
    }
    return displayCountry;
}

// ----------------------------------------------------------------------------
/*
 * ZoneStrings constructor adopts (and promptly copies and deletes) 
 *    the input UnicodeString arrays.
 */
ZoneStrings::ZoneStrings(UnicodeString *strings, 
                         int32_t stringsCount, 
                         UBool commonlyUsed,
                         UnicodeString **genericPartialLocationStrings, 
                         int32_t genericRowCount, 
                         int32_t genericColCount,
                         ZSFStringPool &sp,
                         UErrorCode &status)
:   fStrings(NULL),
    fStringsCount(stringsCount), 
    fIsCommonlyUsed(commonlyUsed),
    fGenericPartialLocationStrings(NULL), 
    fGenericPartialLocationRowCount(genericRowCount), 
    fGenericPartialLocationColCount(genericColCount) 
{
    if (U_FAILURE(status)) {
        return;
    }
    int32_t i, j;
    if (strings != NULL) {
        fStrings = (const UChar **)uprv_malloc(sizeof(const UChar **) * stringsCount);
        if (fStrings == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        for (i=0; i<fStringsCount; i++) {
            fStrings[i] = sp.get(strings[i], status);
        }
        delete[] strings;
    }
    if (genericPartialLocationStrings != NULL) {
        fGenericPartialLocationStrings = 
            (const UChar ***)uprv_malloc(sizeof(const UChar ***) * genericRowCount);
        if (fGenericPartialLocationStrings == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        for (i=0; i < fGenericPartialLocationRowCount; i++) {
            fGenericPartialLocationStrings[i] =
                (const UChar **)uprv_malloc(sizeof(const UChar **) * genericColCount);
            if (fGenericPartialLocationStrings[i] == NULL) {
                status = U_MEMORY_ALLOCATION_ERROR;
                continue;   // Continue so that fGenericPartialLocationStrings will not contain uninitialized junk,
            }               //   which would crash the destructor.
            for (j=0; j<genericColCount; j++) {
                fGenericPartialLocationStrings[i][j] = 
                        sp.get(genericPartialLocationStrings[i][j], status);
            }
            delete[] genericPartialLocationStrings[i];
        }
        uprv_free(genericPartialLocationStrings);
    }
}

ZoneStrings::~ZoneStrings() {
    uprv_free(fStrings);
    if (fGenericPartialLocationStrings != NULL) {
        for (int32_t i = 0; i < fGenericPartialLocationRowCount; i++) {
            uprv_free(fGenericPartialLocationStrings[i]);
        }
        uprv_free(fGenericPartialLocationStrings);
    }
}


UnicodeString&
ZoneStrings::getString(int32_t typeIdx, UnicodeString &result) const {
    if (typeIdx >= 0 && typeIdx < fStringsCount) {
        result.setTo(fStrings[typeIdx], -1);
    } else {
        result.remove();
    }
    return result;
}

UnicodeString&
ZoneStrings::getGenericPartialLocationString(const UnicodeString &mzid, UBool isShort,
                                        UBool commonlyUsedOnly, UnicodeString &result) const {
    UBool isSet = FALSE;
    if (fGenericPartialLocationColCount >= 2) {
        for (int32_t i = 0; i < fGenericPartialLocationRowCount; i++) {
            if (mzid.compare(fGenericPartialLocationStrings[i][0], -1) == 0) {
                if (isShort) {
                    if (fGenericPartialLocationColCount >= 3) {
                        if (!commonlyUsedOnly || 
                            fGenericPartialLocationColCount == 3 || 
                            fGenericPartialLocationStrings[i][3][0] != 0) {
                                result.setTo(fGenericPartialLocationStrings[i][2], -1);
                            isSet = TRUE;
                        }
                    }
                } else {
                    result.setTo(fGenericPartialLocationStrings[i][1], -1);
                    isSet = TRUE;
                }
                break;
            }
        }
    }
    if (!isSet) {
        result.remove();
    }
    return result;
}

// --------------------------------------------------------------
SafeZoneStringFormatPtr::SafeZoneStringFormatPtr(ZSFCacheEntry *cacheEntry)
: fCacheEntry(cacheEntry) {
}

SafeZoneStringFormatPtr::~SafeZoneStringFormatPtr() {
    fCacheEntry->delRef();
}

const ZoneStringFormat*
SafeZoneStringFormatPtr::get() const {
    return fCacheEntry->getZoneStringFormat();
}

ZSFCacheEntry::ZSFCacheEntry(const Locale &locale, ZoneStringFormat *zsf, ZSFCacheEntry *next)
: fLocale(locale), fZoneStringFormat(zsf),
 fNext(next), fRefCount(1)
{
}

ZSFCacheEntry::~ZSFCacheEntry () {
    delete fZoneStringFormat;
}

const ZoneStringFormat*
ZSFCacheEntry::getZoneStringFormat(void) {
    return (const ZoneStringFormat*)fZoneStringFormat;
}

void
ZSFCacheEntry::delRef(void) {
    umtx_lock(&gZSFCacheLock);
    --fRefCount;
    umtx_unlock(&gZSFCacheLock);
}

ZSFCache::ZSFCache(int32_t capacity)
: fCapacity(capacity), fFirst(NULL) {
}

ZSFCache::~ZSFCache() {
    ZSFCacheEntry *entry = fFirst;
    while (entry) {
        ZSFCacheEntry *next = entry->fNext;
        delete entry;
        entry = next;
    }
}

SafeZoneStringFormatPtr*
ZSFCache::get(const Locale &locale, UErrorCode &status) {
    SafeZoneStringFormatPtr *result = NULL;

    // Search the cache entry list
    ZSFCacheEntry *entry = NULL;
    ZSFCacheEntry *next, *prev;

    umtx_lock(&gZSFCacheLock);
    entry = fFirst;
    prev = NULL;
    while (entry) {
        next = entry->fNext;
        if (entry->fLocale == locale) {
            // Add reference count
            entry->fRefCount++;

            // move the entry to the top
            if (entry != fFirst) {
                prev->fNext = next;
                entry->fNext = fFirst;
                fFirst = entry;
            }
            break;
        }
        prev = entry;
        entry = next;
    }
    umtx_unlock(&gZSFCacheLock);

    // Create a new ZoneStringFormat
    if (entry == NULL) {
        ZoneStringFormat *zsf = new ZoneStringFormat(locale, status);
        if (U_FAILURE(status)) {
            delete zsf;
            return NULL;
        }
        if (zsf == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return NULL;
        }
        // Now add the new entry
        umtx_lock(&gZSFCacheLock);
        // Make sure no other threads already created the one for the same locale
        entry = fFirst;
        prev = NULL;
        while (entry) {
            next = entry->fNext;
            if (entry->fLocale == locale) {
                // Add reference count
                entry->fRefCount++;

                // move the entry to the top
                if (entry != fFirst) {
                    prev->fNext = next;
                    entry->fNext = fFirst;
                    fFirst = entry;
                }
                break;
            }
            prev = entry;
            entry = next;
        }
        if (entry == NULL) {
            // Add the new one to the top
            next = fFirst;
            entry = new ZSFCacheEntry(locale, zsf, next);
            fFirst = entry;
        } else {
            delete zsf;
        }
        umtx_unlock(&gZSFCacheLock);
    }

    result = new SafeZoneStringFormatPtr(entry);

    // Now, delete unused cache entries beyond the capacity
    umtx_lock(&gZSFCacheLock);
    entry = fFirst;
    prev = NULL;
    int32_t idx = 1;
    while (entry) {
        next = entry->fNext;
        if (idx >= fCapacity && entry->fRefCount == 0) {
            if (entry == fFirst) {
                fFirst = next;
            } else {
                prev->fNext = next;
            }
            delete entry;
        } else {
            prev = entry;
        }
        entry = next;
        idx++;
    }
    umtx_unlock(&gZSFCacheLock);

    return result;
}


/*
 * Zone String Formatter String Pool Implementation
 *
 *    String pool for (UChar *) strings.  Avoids having repeated copies of the same string.
 */

static const int32_t POOL_CHUNK_SIZE = 2000;
struct ZSFStringPoolChunk: public UMemory {
    ZSFStringPoolChunk    *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
    ZSFStringPoolChunk();
};

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

ZSFStringPool::ZSFStringPool(UErrorCode &status) {
    fChunks = NULL;
    fHash   = NULL;
    if (U_FAILURE(status)) {
        return;
    }
    fChunks = new ZSFStringPoolChunk;
    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;
    }
}


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

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

static const UChar EmptyString = 0;

const UChar *ZSFStringPool::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;
        }
        ZSFStringPoolChunk *oldChunk = fChunks;
        fChunks = new ZSFStringPoolChunk;
        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;
}        


//
//  ZSFStringPool::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 perisist for the life of the zone string formatter, and
//                           therefore can be used directly without copying.
const UChar *ZSFStringPool::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 *ZSFStringPool::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 ZSFStringPool::freeze() {
    uhash_close(fHash);
    fHash = NULL;
}

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */
