/*
*******************************************************************************
* Copyright (C) 1997-2007, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*
* File DTFMTSYM.CPP
*
* Modification History:
*
*   Date        Name        Description
*   02/19/97    aliu        Converted from java.
*   07/21/98    stephen     Added getZoneIndex
*                            Changed weekdays/short weekdays to be one-based
*   06/14/99    stephen     Removed SimpleDateFormat::fgTimeZoneDataSuffix
*   11/16/99    weiv        Added 'Y' and 'e' to fgPatternChars
*   03/27/00    weiv        Keeping resource bundle around!
*   06/30/05    emmons      Added eraNames, narrow month/day, standalone context
*   10/12/05    emmons      Added setters for eraNames, month/day by width/context
*******************************************************************************
*/
 
#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/ustring.h"
#include "unicode/dtfmtsym.h"
#include "unicode/smpdtfmt.h"
#include "cpputils.h"
#include "ucln_in.h"
#include "umutex.h"
#include "cmemory.h"
#include "cstring.h"
#include "locbased.h"
#include "gregoimp.h"
#include "hash.h"
#include "uresimp.h" 

// *****************************************************************************
// class DateFormatSymbols
// *****************************************************************************
/**
 * These are static arrays we use only in the case where we have no
 * resource data.
 */

#define PATTERN_CHARS_LEN 29

/**
 * Unlocalized date-time pattern characters. For example: 'y', 'd', etc. All
 * locales use the same these unlocalized pattern characters.
 */
static const UChar gPatternChars[] = {
    // GyMdkHmsSEDFwWahKzYeugAZvcLQq
    0x47, 0x79, 0x4D, 0x64, 0x6B, 0x48, 0x6D, 0x73, 0x53, 0x45,
    0x44, 0x46, 0x77, 0x57, 0x61, 0x68, 0x4B, 0x7A, 0x59, 0x65,
    0x75, 0x67, 0x41, 0x5A, 0x76, 0x63, 0x4c, 0x51, 0x71, 0
};

/* length of an array */
#define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))

//------------------------------------------------------
// Strings of last resort.  These are only used if we have no resource
// files.  They aren't designed for actual use, just for backup.

// These are the month names and abbreviations of last resort.
static const UChar gLastResortMonthNames[13][3] =
{
    {0x0030, 0x0031, 0x0000}, /* "01" */
    {0x0030, 0x0032, 0x0000}, /* "02" */
    {0x0030, 0x0033, 0x0000}, /* "03" */
    {0x0030, 0x0034, 0x0000}, /* "04" */
    {0x0030, 0x0035, 0x0000}, /* "05" */
    {0x0030, 0x0036, 0x0000}, /* "06" */
    {0x0030, 0x0037, 0x0000}, /* "07" */
    {0x0030, 0x0038, 0x0000}, /* "08" */
    {0x0030, 0x0039, 0x0000}, /* "09" */
    {0x0031, 0x0030, 0x0000}, /* "10" */
    {0x0031, 0x0031, 0x0000}, /* "11" */
    {0x0031, 0x0032, 0x0000}, /* "12" */
    {0x0031, 0x0033, 0x0000}  /* "13" */
};

// These are the weekday names and abbreviations of last resort.
static const UChar gLastResortDayNames[8][2] =
{
    {0x0030, 0x0000}, /* "0" */
    {0x0031, 0x0000}, /* "1" */
    {0x0032, 0x0000}, /* "2" */
    {0x0033, 0x0000}, /* "3" */
    {0x0034, 0x0000}, /* "4" */
    {0x0035, 0x0000}, /* "5" */
    {0x0036, 0x0000}, /* "6" */
    {0x0037, 0x0000}  /* "7" */
};

// These are the quarter names and abbreviations of last resort.
static const UChar gLastResortQuarters[4][2] =
{
    {0x0031, 0x0000}, /* "1" */
    {0x0032, 0x0000}, /* "2" */
    {0x0033, 0x0000}, /* "3" */
    {0x0034, 0x0000}, /* "4" */
};

// These are the am/pm and BC/AD markers of last resort.
static const UChar gLastResortAmPmMarkers[2][3] =
{
    {0x0041, 0x004D, 0x0000}, /* "AM" */
    {0x0050, 0x004D, 0x0000}  /* "PM" */
};

static const UChar gLastResortEras[2][3] =
{
    {0x0042, 0x0043, 0x0000}, /* "BC" */
    {0x0041, 0x0044, 0x0000}  /* "AD" */
};


// These are the zone strings of last resort.
static const UChar gLastResortZoneStrings[7][4] =
{
    {0x0047, 0x004D, 0x0054, 0x0000}, /* "GMT" */
    {0x0047, 0x004D, 0x0054, 0x0000}, /* "GMT" */
    {0x0047, 0x004D, 0x0054, 0x0000}, /* "GMT" */
    {0x0047, 0x004D, 0x0054, 0x0000}, /* "GMT" */
    {0x0047, 0x004D, 0x0054, 0x0000}, /* "GMT" */
    {0x0047, 0x004D, 0x0054, 0x0000}, /* "GMT" */
    {0x0047, 0x004D, 0x0054, 0x0000}  /* "GMT" */
};

/* Sizes for the last resort string arrays */
typedef enum LastResortSize {
    kMonthNum = 13,
    kMonthLen = 3,

    kDayNum = 8,
    kDayLen = 2,

    kAmPmNum = 2,
    kAmPmLen = 3,

    kQuarterNum = 4,
    kQuarterLen = 2,

    kEraNum = 2,
    kEraLen = 3,

    kZoneNum = 5,
    kZoneLen = 4
} LastResortSize;

U_NAMESPACE_BEGIN

UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateFormatSymbols)

/**
 * These are the tags we expect to see in normal resource bundle files associated
 * with a locale and calendar
 */
static const char gErasTag[]="eras";
static const char gAbbreviatedTag[] = "abbreviated";
static const char gMonthNamesTag[]="monthNames";
static const char gDayNamesTag[]="dayNames";
static const char gNamesWideTag[]="wide";
static const char gNamesAbbrTag[]="abbreviated";
static const char gNamesNarrowTag[]="narrow";
static const char gNamesStandaloneTag[]="stand-alone";
static const char gAmPmMarkersTag[]="AmPmMarkers";
static const char gQuartersTag[]="quarters";

/**
 * These are the tags we expect to see in time zone data resource bundle files
 * associated with a locale.
 */
static const char gZoneStringsTag[]="zoneStrings";
static const char gLocalPatternCharsTag[]="localPatternChars";

static UMTX LOCK;

/*
 * Keep this variable in synch with max length of display strings
 */
#define ZID_KEY_MAX 128
#define UTZ_MAX_DISPLAY_STRINGS_LENGTH 7
#define UTZ_SHORT_GENERIC   "sg"
#define UTZ_SHORT_STANDARD  "ss"
#define UTZ_SHORT_DAYLIGHT  "sd"
#define UTZ_LONG_GENERIC    "lg"
#define UTZ_LONG_STANDARD   "ls"
#define UTZ_LONG_DAYLIGHT   "ld"
#define UTZ_EXEMPLAR_CITY   "ec"
#define UTZ_USES_METAZONE   "um"

/**
 * Jitterbug 2974: MSVC has a bug whereby new X[0] behaves badly.
 * Work around this.
 */
static inline UnicodeString* newUnicodeStringArray(size_t count) {
    return new UnicodeString[count ? count : 1];
}

U_CDECL_BEGIN
static void deleteUnicodeStringArray(void* obj) {
    delete[] (UnicodeString*)obj;
}
U_CDECL_END

//------------------------------------------------------

DateFormatSymbols::DateFormatSymbols(const Locale& locale,
                                     UErrorCode& status)
    : UObject()
{
  initializeData(locale, NULL,  status);
}

DateFormatSymbols::DateFormatSymbols(UErrorCode& status)
    : UObject()
{
  initializeData(Locale::getDefault(), NULL, status, TRUE);
}


DateFormatSymbols::DateFormatSymbols(const Locale& locale,
                                     const char *type,
                                     UErrorCode& status)
    : UObject()
{
  initializeData(locale, type,  status);
}

DateFormatSymbols::DateFormatSymbols(const char *type, UErrorCode& status)
    : UObject()
{
  initializeData(Locale::getDefault(), type, status, TRUE);
}

DateFormatSymbols::DateFormatSymbols(const DateFormatSymbols& other)
    : UObject(other)
{
    copyData(other);
}

void
DateFormatSymbols::assignArray(UnicodeString*& dstArray,
                               int32_t& dstCount,
                               const UnicodeString* srcArray,
                               int32_t srcCount)
{
    // assignArray() is only called by copyData(), which in turn implements the
    // copy constructor and the assignment operator.
    // All strings in a DateFormatSymbols object are created in one of the following
    // three ways that all allow to safely use UnicodeString::fastCopyFrom():
    // - readonly-aliases from resource bundles
    // - readonly-aliases or allocated strings from constants
    // - safely cloned strings (with owned buffers) from setXYZ() functions
    //
    // Note that this is true for as long as DateFormatSymbols can be constructed
    // only from a locale bundle or set via the cloning API,
    // *and* for as long as all the strings are in *private* fields, preventing
    // a subclass from creating these strings in an "unsafe" way (with respect to fastCopyFrom()).
    dstCount = srcCount;
    dstArray = newUnicodeStringArray(srcCount);
    if(dstArray != NULL) {
        int32_t i;
        for(i=0; i<srcCount; ++i) {
            dstArray[i].fastCopyFrom(srcArray[i]);
        }
    }
}

/**
 * Create a copy, in fZoneStrings, of the given zone strings array.  The
 * member variables fZoneStringsRowCount and fZoneStringsColCount should
 * be set already by the caller.
 */
void
DateFormatSymbols::createZoneStrings(const UnicodeString *const * otherStrings)
{
    int32_t row, col;

    fZoneStrings = (UnicodeString **)uprv_malloc(fZoneStringsRowCount * sizeof(UnicodeString *));
    for (row=0; row<fZoneStringsRowCount; ++row)
    {
        fZoneStrings[row] = newUnicodeStringArray(fZoneStringsColCount);
        for (col=0; col<fZoneStringsColCount; ++col) {
            // fastCopyFrom() - see assignArray comments
            fZoneStrings[row][col].fastCopyFrom(otherStrings[row][col]);
        }
    }
}

/**
 * Copy all of the other's data to this.
 */
void
DateFormatSymbols::copyData(const DateFormatSymbols& other) {
    assignArray(fEras, fErasCount, other.fEras, other.fErasCount);
    assignArray(fEraNames, fEraNamesCount, other.fEraNames, other.fEraNamesCount);
    assignArray(fMonths, fMonthsCount, other.fMonths, other.fMonthsCount);
    assignArray(fShortMonths, fShortMonthsCount, other.fShortMonths, other.fShortMonthsCount);
    assignArray(fNarrowMonths, fNarrowMonthsCount, other.fNarrowMonths, other.fNarrowMonthsCount);
    assignArray(fStandaloneMonths, fStandaloneMonthsCount, other.fStandaloneMonths, other.fStandaloneMonthsCount);
    assignArray(fStandaloneShortMonths, fStandaloneShortMonthsCount, other.fStandaloneShortMonths, other.fStandaloneShortMonthsCount);
    assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, other.fStandaloneNarrowMonths, other.fStandaloneNarrowMonthsCount);
    assignArray(fWeekdays, fWeekdaysCount, other.fWeekdays, other.fWeekdaysCount);
    assignArray(fShortWeekdays, fShortWeekdaysCount, other.fShortWeekdays, other.fShortWeekdaysCount);
    assignArray(fNarrowWeekdays, fNarrowWeekdaysCount, other.fNarrowWeekdays, other.fNarrowWeekdaysCount);
    assignArray(fStandaloneWeekdays, fStandaloneWeekdaysCount, other.fStandaloneWeekdays, other.fStandaloneWeekdaysCount);
    assignArray(fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, other.fStandaloneShortWeekdays, other.fStandaloneShortWeekdaysCount);
    assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, other.fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdaysCount);
    assignArray(fAmPms, fAmPmsCount, other.fAmPms, other.fAmPmsCount);
    assignArray(fQuarters, fQuartersCount, other.fQuarters, other.fQuartersCount);
    assignArray(fShortQuarters, fShortQuartersCount, other.fShortQuarters, other.fShortQuartersCount);
    assignArray(fStandaloneQuarters, fStandaloneQuartersCount, other.fStandaloneQuarters, other.fStandaloneQuartersCount);
    assignArray(fStandaloneShortQuarters, fStandaloneShortQuartersCount, other.fStandaloneShortQuarters, other.fStandaloneShortQuartersCount);
    // the zoneStrings data is initialized on demand
    //fZoneStringsRowCount = other.fZoneStringsRowCount;
    //fZoneStringsColCount = other.fZoneStringsColCount;
    //createZoneStrings((const UnicodeString**)other.fZoneStrings);
    // initialize on demand
    fZoneStringsHash = NULL;
    fZoneIDEnumeration = NULL;
    fZoneStrings = NULL;
    fZoneStringsColCount = 0;
    fZoneStringsRowCount = 0;
    fResourceBundle = NULL;
    if(other.fZoneStringsHash!=NULL){
        fZoneStringsHash = createZoneStringsHash(other.fZoneStringsHash);
        fZoneIDEnumeration = other.fZoneIDEnumeration->clone();
    }else{
        UErrorCode status =U_ZERO_ERROR;
        fResourceBundle = ures_clone(other.fResourceBundle, &status);
        // TODO: what should be done in case of error?
    }

    // fastCopyFrom() - see assignArray comments
    fLocalPatternChars.fastCopyFrom(other.fLocalPatternChars);
}

/**
 * Assignment operator.
 */
DateFormatSymbols& DateFormatSymbols::operator=(const DateFormatSymbols& other)
{
    dispose();
    copyData(other);

    return *this;
}

DateFormatSymbols::~DateFormatSymbols()
{
    dispose();
}

void DateFormatSymbols::dispose()
{
    if (fEras)                     delete[] fEras;
    if (fEraNames)                 delete[] fEraNames;
    if (fMonths)                   delete[] fMonths;
    if (fShortMonths)              delete[] fShortMonths;
    if (fNarrowMonths)             delete[] fNarrowMonths;
    if (fStandaloneMonths)         delete[] fStandaloneMonths;
    if (fStandaloneShortMonths)    delete[] fStandaloneShortMonths;
    if (fStandaloneNarrowMonths)   delete[] fStandaloneNarrowMonths;
    if (fWeekdays)                 delete[] fWeekdays;
    if (fShortWeekdays)            delete[] fShortWeekdays;
    if (fNarrowWeekdays)           delete[] fNarrowWeekdays;
    if (fStandaloneWeekdays)       delete[] fStandaloneWeekdays;
    if (fStandaloneShortWeekdays)  delete[] fStandaloneShortWeekdays;
    if (fStandaloneNarrowWeekdays) delete[] fStandaloneNarrowWeekdays;
    if (fAmPms)                    delete[] fAmPms;
    if (fQuarters)                 delete[] fQuarters;
    if (fShortQuarters)            delete[] fShortQuarters;
    if (fStandaloneQuarters)       delete[] fStandaloneQuarters;
    if (fStandaloneShortQuarters)  delete[] fStandaloneShortQuarters;

    disposeZoneStrings();
}

void DateFormatSymbols::disposeZoneStrings()
{
    if (fZoneStrings) {
        for (int32_t row=0; row<fZoneStringsRowCount; ++row)
            delete[] fZoneStrings[row];
        uprv_free(fZoneStrings);
    } 
    if(fZoneStringsHash){
        delete fZoneStringsHash;
        fZoneStringsHash =  NULL;
    }
    if(fZoneIDEnumeration){
        delete fZoneIDEnumeration; 
        fZoneIDEnumeration = NULL;
    }
    ures_close(fResourceBundle);
    fResourceBundle = NULL;
}

UBool
DateFormatSymbols::arrayCompare(const UnicodeString* array1,
                                const UnicodeString* array2,
                                int32_t count)
{
    if (array1 == array2) return TRUE;
    while (count>0)
    {
        --count;
        if (array1[count] != array2[count]) return FALSE;
    }
    return TRUE;
}

UBool
DateFormatSymbols::operator==(const DateFormatSymbols& other) const
{
    // First do cheap comparisons
    if (this == &other) {
        return TRUE;
    }
    if (fErasCount == other.fErasCount &&
        fEraNamesCount == other.fEraNamesCount &&
        fMonthsCount == other.fMonthsCount &&
        fShortMonthsCount == other.fShortMonthsCount &&
        fNarrowMonthsCount == other.fNarrowMonthsCount &&
        fStandaloneMonthsCount == other.fStandaloneMonthsCount &&
        fStandaloneShortMonthsCount == other.fStandaloneShortMonthsCount &&
        fStandaloneNarrowMonthsCount == other.fStandaloneNarrowMonthsCount &&
        fWeekdaysCount == other.fWeekdaysCount &&
        fShortWeekdaysCount == other.fShortWeekdaysCount &&
        fNarrowWeekdaysCount == other.fNarrowWeekdaysCount &&
        fStandaloneWeekdaysCount == other.fStandaloneWeekdaysCount &&
        fStandaloneShortWeekdaysCount == other.fStandaloneShortWeekdaysCount &&
        fStandaloneNarrowWeekdaysCount == other.fStandaloneNarrowWeekdaysCount &&
        fAmPmsCount == other.fAmPmsCount &&
        fQuartersCount == other.fQuartersCount &&
        fShortQuartersCount == other.fShortQuartersCount &&
        fStandaloneQuartersCount == other.fStandaloneQuartersCount &&
        fStandaloneShortQuartersCount == other.fStandaloneShortQuartersCount)
    {
        // Now compare the arrays themselves
        if (arrayCompare(fEras, other.fEras, fErasCount) &&
            arrayCompare(fEraNames, other.fEraNames, fEraNamesCount) &&
            arrayCompare(fMonths, other.fMonths, fMonthsCount) &&
            arrayCompare(fShortMonths, other.fShortMonths, fShortMonthsCount) &&
            arrayCompare(fNarrowMonths, other.fNarrowMonths, fNarrowMonthsCount) &&
            arrayCompare(fStandaloneMonths, other.fStandaloneMonths, fStandaloneMonthsCount) &&
            arrayCompare(fStandaloneShortMonths, other.fStandaloneShortMonths, fStandaloneShortMonthsCount) &&
            arrayCompare(fStandaloneNarrowMonths, other.fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount) &&
            arrayCompare(fWeekdays, other.fWeekdays, fWeekdaysCount) &&
            arrayCompare(fShortWeekdays, other.fShortWeekdays, fShortWeekdaysCount) &&
            arrayCompare(fNarrowWeekdays, other.fNarrowWeekdays, fNarrowWeekdaysCount) &&
            arrayCompare(fStandaloneWeekdays, other.fStandaloneWeekdays, fStandaloneWeekdaysCount) &&
            arrayCompare(fStandaloneShortWeekdays, other.fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount) &&
            arrayCompare(fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount) &&
            arrayCompare(fAmPms, other.fAmPms, fAmPmsCount) &&
            arrayCompare(fQuarters, other.fQuarters, fQuartersCount) &&
            arrayCompare(fShortQuarters, other.fShortQuarters, fShortQuartersCount) &&
            arrayCompare(fStandaloneQuarters, other.fStandaloneQuarters, fStandaloneQuartersCount) &&
            arrayCompare(fStandaloneShortQuarters, other.fStandaloneShortQuarters, fStandaloneShortQuartersCount))
        {
            
            if(fZoneStringsHash == NULL || other.fZoneStringsHash == NULL){
                // fZoneStringsHash is not initialized compare the resource bundles
                if(ures_equal(fResourceBundle, other.fResourceBundle)== FALSE){
                    return FALSE;
                }
            }else{
                if(fZoneStringsHash->equals(*other.fZoneStringsHash) == FALSE){
                    return FALSE;
                }
                // we always make sure that we update the enumeration when the hash is
                // updated. So we can be sure that once we compare the hashes  the 
                // enumerations are also equal
            }
            // since fZoneStrings data member is deprecated .. and may not be initialized
            // so don't compare them
            return TRUE;
        }
    }
    return FALSE;
}

//------------------------------------------------------

const UnicodeString*
DateFormatSymbols::getEras(int32_t &count) const
{
    count = fErasCount;
    return fEras;
}

const UnicodeString*
DateFormatSymbols::getEraNames(int32_t &count) const
{
    count = fEraNamesCount;
    return fEraNames;
}

const UnicodeString*
DateFormatSymbols::getMonths(int32_t &count) const
{
    count = fMonthsCount;
    return fMonths;
}

const UnicodeString*
DateFormatSymbols::getShortMonths(int32_t &count) const
{
    count = fShortMonthsCount;
    return fShortMonths;
}

const UnicodeString*
DateFormatSymbols::getMonths(int32_t &count, DtContextType context, DtWidthType width ) const
{
    UnicodeString *returnValue = NULL;

    switch (context) {
    case FORMAT :
        switch(width) {
        case WIDE :
            count = fMonthsCount;
            returnValue = fMonths;
            break;
        case ABBREVIATED :
            count = fShortMonthsCount;
            returnValue = fShortMonths;
            break;
        case NARROW :
            count = fNarrowMonthsCount;
            returnValue = fNarrowMonths;
            break;
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case STANDALONE :
        switch(width) {
        case WIDE :
            count = fStandaloneMonthsCount;
            returnValue = fStandaloneMonths;
            break;
        case ABBREVIATED :
            count = fStandaloneShortMonthsCount;
            returnValue = fStandaloneShortMonths;
            break;
        case NARROW :
            count = fStandaloneNarrowMonthsCount;
            returnValue = fStandaloneNarrowMonths;
            break;
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case DT_CONTEXT_COUNT :
        break;
    }
    return returnValue;
}

const UnicodeString*
DateFormatSymbols::getWeekdays(int32_t &count) const
{
    count = fWeekdaysCount;
    return fWeekdays;
}

const UnicodeString*
DateFormatSymbols::getShortWeekdays(int32_t &count) const
{
    count = fShortWeekdaysCount;
    return fShortWeekdays;
}

const UnicodeString*
DateFormatSymbols::getWeekdays(int32_t &count, DtContextType context, DtWidthType width) const
{
    UnicodeString *returnValue = NULL;
    switch (context) {
    case FORMAT :
        switch(width) {
            case WIDE :
                count = fWeekdaysCount;
                returnValue = fWeekdays;
                break;
            case ABBREVIATED :
                count = fShortWeekdaysCount;
                returnValue = fShortWeekdays;
                break;
            case NARROW :
                count = fNarrowWeekdaysCount;
                returnValue = fNarrowWeekdays;
                break;
            case DT_WIDTH_COUNT :
                break;
        }
        break;
    case STANDALONE :
        switch(width) {
            case WIDE :
                count = fStandaloneWeekdaysCount;
                returnValue = fStandaloneWeekdays;
                break;
            case ABBREVIATED :
                count = fStandaloneShortWeekdaysCount;
                returnValue = fStandaloneShortWeekdays;
                break;
            case NARROW :
                count = fStandaloneNarrowWeekdaysCount;
                returnValue = fStandaloneNarrowWeekdays;
                break;
            case DT_WIDTH_COUNT :
                break;
        }
        break;
    case DT_CONTEXT_COUNT :
        break;
    }
    return returnValue;
}

const UnicodeString*
DateFormatSymbols::getQuarters(int32_t &count, DtContextType context, DtWidthType width ) const
{
    UnicodeString *returnValue = NULL;

    switch (context) {
    case FORMAT :
        switch(width) {
        case WIDE :
            count = fQuartersCount;
            returnValue = fQuarters;
            break;
        case ABBREVIATED :
            count = fShortQuartersCount;
            returnValue = fShortQuarters;
            break;
        case NARROW :
            count = 0;
            returnValue = NULL;
            break;
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case STANDALONE :
        switch(width) {
        case WIDE :
            count = fStandaloneQuartersCount;
            returnValue = fStandaloneQuarters;
            break;
        case ABBREVIATED :
            count = fStandaloneShortQuartersCount;
            returnValue = fStandaloneShortQuarters;
            break;
        case NARROW :
            count = 0;
            returnValue = NULL;
            break;
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case DT_CONTEXT_COUNT :
        break;
    }
    return returnValue;
}

const UnicodeString*
DateFormatSymbols::getAmPmStrings(int32_t &count) const
{
    count = fAmPmsCount;
    return fAmPms;
}

//------------------------------------------------------

void
DateFormatSymbols::setEras(const UnicodeString* erasArray, int32_t count)
{
    // delete the old list if we own it
    if (fEras)
        delete[] fEras;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fEras = newUnicodeStringArray(count);
    uprv_arrayCopy(erasArray,fEras,  count);
    fErasCount = count;
}

void
DateFormatSymbols::setEraNames(const UnicodeString* eraNamesArray, int32_t count)
{
    // delete the old list if we own it
    if (fEraNames)
        delete[] fEraNames;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fEraNames = newUnicodeStringArray(count);
    uprv_arrayCopy(eraNamesArray,fEraNames,  count);
    fEraNamesCount = count;
}

void
DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count)
{
    // delete the old list if we own it
    if (fMonths)
        delete[] fMonths;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fMonths = newUnicodeStringArray(count);
    uprv_arrayCopy( monthsArray,fMonths,count);
    fMonthsCount = count;
}

void
DateFormatSymbols::setShortMonths(const UnicodeString* shortMonthsArray, int32_t count)
{
    // delete the old list if we own it
    if (fShortMonths)
        delete[] fShortMonths;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fShortMonths = newUnicodeStringArray(count);
    uprv_arrayCopy(shortMonthsArray,fShortMonths,  count);
    fShortMonthsCount = count;
}

void
DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count, DtContextType context, DtWidthType width)
{
    // delete the old list if we own it
    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)

    switch (context) {
    case FORMAT :
        switch (width) {
        case WIDE :
            if (fMonths)
                delete[] fMonths;
            fMonths = newUnicodeStringArray(count);
            uprv_arrayCopy( monthsArray,fMonths,count);
            fMonthsCount = count;
            break;
        case ABBREVIATED :
            if (fShortMonths)
                delete[] fShortMonths;
            fShortMonths = newUnicodeStringArray(count);
            uprv_arrayCopy( monthsArray,fShortMonths,count);
            fShortMonthsCount = count;
            break;
        case NARROW :
            if (fNarrowMonths)
                delete[] fNarrowMonths;
            fNarrowMonths = newUnicodeStringArray(count);
            uprv_arrayCopy( monthsArray,fNarrowMonths,count);
            fNarrowMonthsCount = count;
            break; 
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case STANDALONE :
        switch (width) {
        case WIDE :
            if (fStandaloneMonths)
                delete[] fStandaloneMonths;
            fStandaloneMonths = newUnicodeStringArray(count);
            uprv_arrayCopy( monthsArray,fStandaloneMonths,count);
            fStandaloneMonthsCount = count;
            break;
        case ABBREVIATED :
            if (fStandaloneShortMonths)
                delete[] fStandaloneShortMonths;
            fStandaloneShortMonths = newUnicodeStringArray(count);
            uprv_arrayCopy( monthsArray,fStandaloneShortMonths,count);
            fStandaloneShortMonthsCount = count;
            break;
        case NARROW :
           if (fStandaloneNarrowMonths)
                delete[] fStandaloneNarrowMonths;
            fStandaloneNarrowMonths = newUnicodeStringArray(count);
            uprv_arrayCopy( monthsArray,fStandaloneNarrowMonths,count);
            fStandaloneNarrowMonthsCount = count;
            break; 
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case DT_CONTEXT_COUNT :
        break;
    }
}

void DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count)
{
    // delete the old list if we own it
    if (fWeekdays)
        delete[] fWeekdays;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fWeekdays = newUnicodeStringArray(count);
    uprv_arrayCopy(weekdaysArray,fWeekdays,count);
    fWeekdaysCount = count;
}

void
DateFormatSymbols::setShortWeekdays(const UnicodeString* shortWeekdaysArray, int32_t count)
{
    // delete the old list if we own it
    if (fShortWeekdays)
        delete[] fShortWeekdays;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fShortWeekdays = newUnicodeStringArray(count);
    uprv_arrayCopy(shortWeekdaysArray, fShortWeekdays, count);
    fShortWeekdaysCount = count;
}

void
DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count, DtContextType context, DtWidthType width)
{
    // delete the old list if we own it
    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)

    switch (context) {
    case FORMAT :
        switch (width) {
        case WIDE :
            if (fWeekdays)
                delete[] fWeekdays;
            fWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fWeekdays, count);
            fWeekdaysCount = count;
            break;
        case ABBREVIATED :
            if (fShortWeekdays)
                delete[] fShortWeekdays;
            fShortWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fShortWeekdays, count);
            fShortWeekdaysCount = count;
            break;
        case NARROW :
            if (fNarrowWeekdays)
                delete[] fNarrowWeekdays;
            fNarrowWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fNarrowWeekdays, count);
            fNarrowWeekdaysCount = count;
            break; 
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case STANDALONE :
        switch (width) {
        case WIDE :
            if (fStandaloneWeekdays)
                delete[] fStandaloneWeekdays;
            fStandaloneWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fStandaloneWeekdays, count);
            fStandaloneWeekdaysCount = count;
            break;
        case ABBREVIATED :
            if (fStandaloneShortWeekdays)
                delete[] fStandaloneShortWeekdays;
            fStandaloneShortWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fStandaloneShortWeekdays, count);
            fStandaloneShortWeekdaysCount = count;
            break;
        case NARROW :
            if (fStandaloneNarrowWeekdays)
                delete[] fStandaloneNarrowWeekdays;
            fStandaloneNarrowWeekdays = newUnicodeStringArray(count);
            uprv_arrayCopy(weekdaysArray, fStandaloneNarrowWeekdays, count);
            fStandaloneNarrowWeekdaysCount = count;
            break; 
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case DT_CONTEXT_COUNT :
        break;
    }
}

void
DateFormatSymbols::setQuarters(const UnicodeString* quartersArray, int32_t count, DtContextType context, DtWidthType width)
{
    // delete the old list if we own it
    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)

    switch (context) {
    case FORMAT :
        switch (width) {
        case WIDE :
            if (fQuarters)
                delete[] fQuarters;
            fQuarters = newUnicodeStringArray(count);
            uprv_arrayCopy( quartersArray,fQuarters,count);
            fQuartersCount = count;
            break;
        case ABBREVIATED :
            if (fShortQuarters)
                delete[] fShortQuarters;
            fShortQuarters = newUnicodeStringArray(count);
            uprv_arrayCopy( quartersArray,fShortQuarters,count);
            fShortQuartersCount = count;
            break;
        case NARROW :
        /*
            if (fNarrowQuarters)
                delete[] fNarrowQuarters;
            fNarrowQuarters = newUnicodeStringArray(count);
            uprv_arrayCopy( quartersArray,fNarrowQuarters,count);
            fNarrowQuartersCount = count;
        */
            break; 
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case STANDALONE :
        switch (width) {
        case WIDE :
            if (fStandaloneQuarters)
                delete[] fStandaloneQuarters;
            fStandaloneQuarters = newUnicodeStringArray(count);
            uprv_arrayCopy( quartersArray,fStandaloneQuarters,count);
            fStandaloneQuartersCount = count;
            break;
        case ABBREVIATED :
            if (fStandaloneShortQuarters)
                delete[] fStandaloneShortQuarters;
            fStandaloneShortQuarters = newUnicodeStringArray(count);
            uprv_arrayCopy( quartersArray,fStandaloneShortQuarters,count);
            fStandaloneShortQuartersCount = count;
            break;
        case NARROW :
        /*
           if (fStandaloneNarrowQuarters)
                delete[] fStandaloneNarrowQuarters;
            fStandaloneNarrowQuarters = newUnicodeStringArray(count);
            uprv_arrayCopy( quartersArray,fStandaloneNarrowQuarters,count);
            fStandaloneNarrowQuartersCount = count;
        */
            break; 
        case DT_WIDTH_COUNT :
            break;
        }
        break;
    case DT_CONTEXT_COUNT :
        break;
    }
}

void
DateFormatSymbols::setAmPmStrings(const UnicodeString* amPmsArray, int32_t count)
{
    // delete the old list if we own it
    if (fAmPms) delete[] fAmPms;

    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fAmPms = newUnicodeStringArray(count);
    uprv_arrayCopy(amPmsArray,fAmPms,count);
    fAmPmsCount = count;
}

//------------------------------------------------------

const UnicodeString**
DateFormatSymbols::getZoneStrings(int32_t& rowCount, int32_t& columnCount) const
{
    umtx_lock(&LOCK);
    UErrorCode status = U_ZERO_ERROR;
    if(fZoneStrings==NULL){
        // cast away const to get around the problem for lazy initialization
        ((DateFormatSymbols*)this)->initZoneStringsArray(status);
    }
    rowCount = fZoneStringsRowCount;
    columnCount = fZoneStringsColCount;
    umtx_unlock(&LOCK);
    if(U_FAILURE(status)){
        rowCount = 0;
        columnCount = 0;
        return NULL;
    }
    return (const UnicodeString**)fZoneStrings; // Compiler requires cast
}

void
DateFormatSymbols::setZoneStrings(const UnicodeString* const *strings, int32_t rowCount, int32_t columnCount)
{
    // since deleting a 2-d array is a pain in the butt, we offload that task to
    // a separate function
    disposeZoneStrings();
    UErrorCode status = U_ZERO_ERROR;
    // we always own the new list, which we create here (we duplicate rather
    // than adopting the list passed in)
    fZoneStringsRowCount = rowCount;
    fZoneStringsColCount = columnCount;
    createZoneStrings((const UnicodeString**)strings);
    initZoneStrings((const UnicodeString**)strings, rowCount,columnCount, status);
}

//------------------------------------------------------

const UChar * U_EXPORT2
DateFormatSymbols::getPatternUChars(void)
{
    return gPatternChars;
}

//------------------------------------------------------

UnicodeString&
DateFormatSymbols::getLocalPatternChars(UnicodeString& result) const
{
    // fastCopyFrom() - see assignArray comments
    return result.fastCopyFrom(fLocalPatternChars);
}

//------------------------------------------------------

void
DateFormatSymbols::setLocalPatternChars(const UnicodeString& newLocalPatternChars)
{
    fLocalPatternChars = newLocalPatternChars;
}

//------------------------------------------------------

static void
initField(UnicodeString **field, int32_t& length, const UResourceBundle *data, UErrorCode &status) {
    if (U_SUCCESS(status)) {
        int32_t strLen = 0;
        length = ures_getSize(data);
        *field = newUnicodeStringArray(length);
        if (*field) {
            for(int32_t i = 0; i<length; i++) {
                const UChar *resStr = ures_getStringByIndex(data, i, &strLen, &status);
                // setTo() - see assignArray comments
                (*(field)+i)->setTo(TRUE, resStr, strLen);
            }
        }
        else {
            length = 0;
            status = U_MEMORY_ALLOCATION_ERROR;
        }
    }
}

static void
initField(UnicodeString **field, int32_t& length, const UChar *data, LastResortSize numStr, LastResortSize strLen, UErrorCode &status) {
    if (U_SUCCESS(status)) {
        length = numStr;
        *field = newUnicodeStringArray((size_t)numStr);
        if (*field) {
            for(int32_t i = 0; i<length; i++) {
                // readonly aliases - all "data" strings are constant
                // -1 as length for variable-length strings (gLastResortDayNames[0] is empty)
                (*(field)+i)->setTo(TRUE, data+(i*((int32_t)strLen)), -1);
            }
        }
        else {
            length = 0;
            status = U_MEMORY_ALLOCATION_ERROR;
        }
    }
}

void
DateFormatSymbols::initializeData(const Locale& locale, const char *type, UErrorCode& status, UBool useLastResortData)
{
    int32_t i;
    int32_t len = 0;
    const UChar *resStr;
    /* In case something goes wrong, initialize all of the data to NULL. */
    fEras = NULL;
    fErasCount = 0;
    fEraNames = NULL;
    fEraNamesCount = 0;
    fMonths = NULL;
    fMonthsCount=0;
    fShortMonths = NULL;
    fShortMonthsCount=0;
    fNarrowMonths = NULL;
    fNarrowMonthsCount=0;
    fStandaloneMonths = NULL;
    fStandaloneMonthsCount=0;
    fStandaloneShortMonths = NULL;
    fStandaloneShortMonthsCount=0;
    fStandaloneNarrowMonths = NULL;
    fStandaloneNarrowMonthsCount=0;
    fWeekdays = NULL;
    fWeekdaysCount=0;
    fShortWeekdays = NULL;
    fShortWeekdaysCount=0;
    fNarrowWeekdays = NULL;
    fNarrowWeekdaysCount=0;
    fStandaloneWeekdays = NULL;
    fStandaloneWeekdaysCount=0;
    fStandaloneShortWeekdays = NULL;
    fStandaloneShortWeekdaysCount=0;
    fStandaloneNarrowWeekdays = NULL;
    fStandaloneNarrowWeekdaysCount=0;
    fAmPms = NULL;
    fAmPmsCount=0;
    fQuarters = NULL;
    fQuartersCount = 0;
    fShortQuarters = NULL;
    fShortQuartersCount = 0;
    fStandaloneQuarters = NULL;
    fStandaloneQuartersCount = 0;
    fStandaloneShortQuarters = NULL;
    fStandaloneShortQuartersCount = 0;
    fZoneStringsRowCount = 0;
    fZoneStringsColCount = 0;
    fZoneStrings = NULL;
    fZoneStringsHash = NULL;
    fZoneIDEnumeration = NULL;
    fResourceBundle   = NULL;
    
      
    if (U_FAILURE(status)) return;

    /**
     * Retrieve the string arrays we need from the resource bundle file.
     * We cast away const here, but that's okay; we won't delete any of
     * these.
     */
    CalendarData calData(locale, type, status);
    fResourceBundle = ures_open((char*)0, locale.getName(), &status);

    // load the first data item
    UResourceBundle *erasMain = calData.getByKey(gErasTag, status);
    UResourceBundle *eras = ures_getByKeyWithFallback(erasMain, gAbbreviatedTag, NULL, &status);
    UErrorCode oldStatus = status;
    UResourceBundle *eraNames = ures_getByKeyWithFallback(erasMain, gNamesWideTag, NULL, &status);
    if ( status == U_MISSING_RESOURCE_ERROR ) { // Workaround because eras/wide was omitted from CLDR 1.3
       status = oldStatus;
       eraNames = ures_getByKeyWithFallback(erasMain, gAbbreviatedTag, NULL, &status);
    }

    UResourceBundle *lsweekdaysData = NULL; // Data closed by calData
    UResourceBundle *weekdaysData = NULL; // Data closed by calData
    UResourceBundle *narrowWeekdaysData = NULL; // Data closed by calData
    UResourceBundle *standaloneWeekdaysData = NULL; // Data closed by calData
    UResourceBundle *standaloneShortWeekdaysData = NULL; // Data closed by calData
    UResourceBundle *standaloneNarrowWeekdaysData = NULL; // Data closed by calData

    U_LOCALE_BASED(locBased, *this);
    if (U_FAILURE(status))
    {
        if (useLastResortData)
        {
            // Handle the case in which there is no resource data present.
            // We don't have to generate usable patterns in this situation;
            // we just need to produce something that will be semi-intelligible
            // in most locales.

            status = U_USING_FALLBACK_WARNING;

            initField(&fEras, fErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
            initField(&fEraNames, fEraNamesCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
            initField(&fMonths, fMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen,  status);
            initField(&fShortMonths, fShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
            initField(&fNarrowMonths, fNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
            initField(&fStandaloneMonths, fStandaloneMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen,  status);
            initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
            initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
            initField(&fWeekdays, fWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fShortWeekdays, fShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fNarrowWeekdays, fNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fStandaloneWeekdays, fStandaloneWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fStandaloneShortWeekdays, fStandaloneShortWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
            initField(&fAmPms, fAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status);
            initField(&fQuarters, fQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
            initField(&fShortQuarters, fShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
            initField(&fStandaloneQuarters, fStandaloneQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
            initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
            fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN);
        }
        goto cleanup;
    }

    // if we make it to here, the resource data is cool, and we can get everything out
    // of it that we need except for the time-zone and localized-pattern data, which
    // are stored in a separate file
    locBased.setLocaleIDs(ures_getLocaleByType(eras, ULOC_VALID_LOCALE, &status),
                          ures_getLocaleByType(eras, ULOC_ACTUAL_LOCALE, &status));

    initField(&fEras, fErasCount, eras, status);
    initField(&fEraNames, fEraNamesCount, eraNames, status);

    initField(&fMonths, fMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status);
    initField(&fShortMonths, fShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);

    initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesNarrowTag, status), status);
    if(status == U_MISSING_RESOURCE_ERROR) {
        status = U_ZERO_ERROR;
        initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), status);
    }
    if ( status == U_MISSING_RESOURCE_ERROR ) { /* If format/narrow not available, use format/abbreviated */
       status = U_ZERO_ERROR;
       initField(&fNarrowMonths, fNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
    }

    initField(&fStandaloneMonths, fStandaloneMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesWideTag, status), status);
    if ( status == U_MISSING_RESOURCE_ERROR ) { /* If standalone/wide not available, use format/wide */
       status = U_ZERO_ERROR;
       initField(&fStandaloneMonths, fStandaloneMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status);
    }
    initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status), status);
    if ( status == U_MISSING_RESOURCE_ERROR ) { /* If standalone/abbreviated not available, use format/abbreviated */
       status = U_ZERO_ERROR;
       initField(&fStandaloneShortMonths, fStandaloneShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
    }
    initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey3(gMonthNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status), status);
    if ( status == U_MISSING_RESOURCE_ERROR ) { /* if standalone/narrow not availabe, try format/narrow */
       status = U_ZERO_ERROR;
       initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesNarrowTag, status), status);
       if ( status == U_MISSING_RESOURCE_ERROR ) { /* if still not there, use format/abbreviated */
          status = U_ZERO_ERROR;
          initField(&fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
       }
    }
    initField(&fAmPms, fAmPmsCount, calData.getByKey(gAmPmMarkersTag, status), status);

    initField(&fQuarters, fQuartersCount, calData.getByKey2(gQuartersTag, gNamesWideTag, status), status);
    initField(&fShortQuarters, fShortQuartersCount, calData.getByKey2(gQuartersTag, gNamesAbbrTag, status), status);

    initField(&fStandaloneQuarters, fStandaloneQuartersCount, calData.getByKey3(gQuartersTag, gNamesStandaloneTag, gNamesWideTag, status), status);
    if(status == U_MISSING_RESOURCE_ERROR) {
        status = U_ZERO_ERROR;
        initField(&fStandaloneQuarters, fStandaloneQuartersCount, calData.getByKey2(gQuartersTag, gNamesWideTag, status), status);
    }

    initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calData.getByKey3(gQuartersTag, gNamesStandaloneTag, gNamesAbbrTag, status), status);
    if(status == U_MISSING_RESOURCE_ERROR) {
        status = U_ZERO_ERROR;
        initField(&fStandaloneShortQuarters, fStandaloneShortQuartersCount, calData.getByKey2(gQuartersTag, gNamesAbbrTag, status), status);
    }
    // ICU 3.8 or later version no longer uses localized date-time pattern characters by default (ticket#5597)
    /*
    // fastCopyFrom()/setTo() - see assignArray comments
    resStr = ures_getStringByKey(fResourceBundle, gLocalPatternCharsTag, &len, &status);
    fLocalPatternChars.setTo(TRUE, resStr, len);
    // If the locale data does not include new pattern chars, use the defaults
    // TODO: Consider making this an error, since this may add conflicting characters.
    if (len < PATTERN_CHARS_LEN) {
        fLocalPatternChars.append(UnicodeString(TRUE, &gPatternChars[len], PATTERN_CHARS_LEN-len));
    }
    */
    fLocalPatternChars.setTo(TRUE, gPatternChars, PATTERN_CHARS_LEN);

    // {sfb} fixed to handle 1-based weekdays
    weekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status);
    fWeekdaysCount = ures_getSize(weekdaysData);
    fWeekdays = new UnicodeString[fWeekdaysCount+1];
    /* pin the blame on system. If we cannot get a chunk of memory .. the system is dying!*/
    if (fWeekdays == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        goto cleanup;
    }
    // leave fWeekdays[0] empty
    for(i = 0; i<fWeekdaysCount; i++) {
        resStr = ures_getStringByIndex(weekdaysData, i, &len, &status);
        // setTo() - see assignArray comments
        fWeekdays[i+1].setTo(TRUE, resStr, len);
    }
    fWeekdaysCount++;

    lsweekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
    fShortWeekdaysCount = ures_getSize(lsweekdaysData);
    fShortWeekdays = new UnicodeString[fShortWeekdaysCount+1];
    /* test for NULL */
    if (fShortWeekdays == 0) {
        status = U_MEMORY_ALLOCATION_ERROR;
        goto cleanup;
    }
    // leave fShortWeekdays[0] empty
    for(i = 0; i<fShortWeekdaysCount; i++) {
        resStr = ures_getStringByIndex(lsweekdaysData, i, &len, &status);
        // setTo() - see assignArray comments
        fShortWeekdays[i+1].setTo(TRUE, resStr, len);
    }
    fShortWeekdaysCount++;

    narrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesNarrowTag, status);
    if(status == U_MISSING_RESOURCE_ERROR) {
        status = U_ZERO_ERROR;
        narrowWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status);
    }
    if ( status == U_MISSING_RESOURCE_ERROR ) {
       status = U_ZERO_ERROR;
       narrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
    }
    fNarrowWeekdaysCount = ures_getSize(narrowWeekdaysData);
    fNarrowWeekdays = new UnicodeString[fNarrowWeekdaysCount+1];
    /* test for NULL */
    if (fNarrowWeekdays == 0) {
        status = U_MEMORY_ALLOCATION_ERROR;
        goto cleanup;
    }
    // leave fNarrowWeekdays[0] empty
    for(i = 0; i<fNarrowWeekdaysCount; i++) {
        resStr = ures_getStringByIndex(narrowWeekdaysData, i, &len, &status);
        // setTo() - see assignArray comments
        fNarrowWeekdays[i+1].setTo(TRUE, resStr, len);
    }
    fNarrowWeekdaysCount++;

    standaloneWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesWideTag, status);
    if ( status == U_MISSING_RESOURCE_ERROR ) {
       status = U_ZERO_ERROR;
       standaloneWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesWideTag, status);
    }
    fStandaloneWeekdaysCount = ures_getSize(standaloneWeekdaysData);
    fStandaloneWeekdays = new UnicodeString[fStandaloneWeekdaysCount+1];
    /* test for NULL */
    if (fStandaloneWeekdays == 0) {
        status = U_MEMORY_ALLOCATION_ERROR;
        goto cleanup;
    }
    // leave fStandaloneWeekdays[0] empty
    for(i = 0; i<fStandaloneWeekdaysCount; i++) {
        resStr = ures_getStringByIndex(standaloneWeekdaysData, i, &len, &status);
        // setTo() - see assignArray comments
        fStandaloneWeekdays[i+1].setTo(TRUE, resStr, len);
    }
    fStandaloneWeekdaysCount++;

    standaloneShortWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesAbbrTag, status);
    if ( status == U_MISSING_RESOURCE_ERROR ) {
       status = U_ZERO_ERROR;
       standaloneShortWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
    }
    fStandaloneShortWeekdaysCount = ures_getSize(standaloneShortWeekdaysData);
    fStandaloneShortWeekdays = new UnicodeString[fStandaloneShortWeekdaysCount+1];
    /* test for NULL */
    if (fStandaloneShortWeekdays == 0) {
        status = U_MEMORY_ALLOCATION_ERROR;
        goto cleanup;
    }
    // leave fStandaloneShortWeekdays[0] empty
    for(i = 0; i<fStandaloneShortWeekdaysCount; i++) {
        resStr = ures_getStringByIndex(standaloneShortWeekdaysData, i, &len, &status);
        // setTo() - see assignArray comments
        fStandaloneShortWeekdays[i+1].setTo(TRUE, resStr, len);
    }
    fStandaloneShortWeekdaysCount++;

    standaloneNarrowWeekdaysData = calData.getByKey3(gDayNamesTag, gNamesStandaloneTag, gNamesNarrowTag, status);
    if ( status == U_MISSING_RESOURCE_ERROR ) {
       status = U_ZERO_ERROR;
       standaloneNarrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesNarrowTag, status);
       if ( status == U_MISSING_RESOURCE_ERROR ) {
          status = U_ZERO_ERROR;
          standaloneNarrowWeekdaysData = calData.getByKey2(gDayNamesTag, gNamesAbbrTag, status);
       }
    }
    fStandaloneNarrowWeekdaysCount = ures_getSize(standaloneNarrowWeekdaysData);
    fStandaloneNarrowWeekdays = new UnicodeString[fStandaloneNarrowWeekdaysCount+1];
    /* test for NULL */
    if (fStandaloneNarrowWeekdays == 0) {
        status = U_MEMORY_ALLOCATION_ERROR;
        goto cleanup;
    }
    // leave fStandaloneNarrowWeekdays[0] empty
    for(i = 0; i<fStandaloneNarrowWeekdaysCount; i++) {
        resStr = ures_getStringByIndex(standaloneNarrowWeekdaysData, i, &len, &status);
        // setTo() - see assignArray comments
        fStandaloneNarrowWeekdays[i+1].setTo(TRUE, resStr, len);
    }
    fStandaloneNarrowWeekdaysCount++;

cleanup:
    ures_close(eras);
    ures_close(eraNames);
}

/**
 * Package private: used by SimpleDateFormat
 * Gets the index for the given time zone ID to obtain the timezone
 * strings for formatting. The time zone ID is just for programmatic
 * lookup. NOT LOCALIZED!!!
 * @param ID the given time zone ID.
 * @return the index of the given time zone ID.  Returns -1 if
 * the given time zone ID can't be located in the DateFormatSymbols object.
 * @see java.util.SimpleTimeZone
 */
int32_t DateFormatSymbols::getZoneIndex(const UnicodeString& ID) const
{
    int32_t result = _getZoneIndex(ID);
    if (result >= 0) {
        return result;
    }

    // Do a search through the equivalency group for the given ID
    int32_t n = TimeZone::countEquivalentIDs(ID);
    if (n > 1) {
        int32_t i;
        for (i=0; i<n; ++i) {
            UnicodeString equivID = TimeZone::getEquivalentID(ID, i);
            if (equivID != ID) {
                int32_t equivResult = _getZoneIndex(equivID);
                if (equivResult >= 0) {
                    return equivResult;
                }
            }
        }
    }

    return -1;
}

/**
 * Lookup the given ID.  Do NOT do an equivalency search.
 */
int32_t DateFormatSymbols::_getZoneIndex(const UnicodeString& ID) const
{
    for(int32_t index = 0; index < fZoneStringsRowCount; index++) {
        if (0 == ID.caseCompare(fZoneStrings[index][0], 0)) {
            return index;
        }
    }

    return -1;
}

Locale 
DateFormatSymbols::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
    U_LOCALE_BASED(locBased, *this);
    return locBased.getLocale(type, status);
}

class TimeZoneKeysEnumeration : public StringEnumeration {
private:
    UnicodeString* strings;
    int32_t length;
    int32_t current;
    int32_t capacity;
    TimeZoneKeysEnumeration(UnicodeString* oldStrs, int32_t count){
        strings = newUnicodeStringArray(count);
        if(strings==NULL){
            return;
        }
        capacity = count;
        current = 0;
        for(length = 0; length<capacity; length++){
            strings[length].setTo(oldStrs[length]);
        }
    }    
public:
    static UClassID U_EXPORT2 getStaticClassID(void);
    virtual UClassID getDynamicClassID(void) const;

    TimeZoneKeysEnumeration(int32_t count, UErrorCode status){
        strings = newUnicodeStringArray(count);
        if(strings == NULL){
            status = U_MEMORY_ALLOCATION_ERROR;
        }
        length = 0; 
        current = 0;
        capacity = count;
    }

    void put(const UnicodeString& str, UErrorCode& status){
        if(length < capacity){
            strings[length++].setTo(str);
        }else{
            status = U_INDEX_OUTOFBOUNDS_ERROR;
        }
    }
    virtual ~TimeZoneKeysEnumeration() {
        delete[] strings;
    }

    virtual StringEnumeration * clone() const
    {
        return new TimeZoneKeysEnumeration(strings, length);
    }

    virtual int32_t count(UErrorCode &/*status*/) const {
        return length;
    }
    virtual const UChar* unext(int32_t *resultLength, UErrorCode& /*status*/){
        if(current < length){
            const UChar* ret = strings[current].getBuffer();
            *resultLength = strings[current].length();
            current++;
            return ret;
        }
        return NULL;
    }

    virtual const UnicodeString* snext(UErrorCode& status) {
        if(U_FAILURE(status)){
            return NULL;
        }
        if(current < length){
            return &strings[current++];
        }
        return NULL;
    }
    /* this method is for thread safe iteration */
    const UnicodeString* snext(int32_t& pos, UErrorCode& status)const {
        if(U_FAILURE(status)){
            return NULL;
        }
        if(pos < length){
            return &strings[pos++];
        }
        return NULL;
    }

    virtual void reset(UErrorCode& /*status*/) {
        current = 0;

    }
private:
    UBool equals(const StringEnumeration& other) const{
        if (other.getDynamicClassID() != TimeZoneKeysEnumeration::getStaticClassID()) {
            return FALSE;
        }
        TimeZoneKeysEnumeration& enum2 =  (TimeZoneKeysEnumeration&)(other);
        UErrorCode status = U_ZERO_ERROR;

        int32_t count1 = count(status);
        int32_t count2 = other.count(status);
        if(count1 != count2){
            return FALSE;
        }
        int32_t pos1 = 0; 
        int32_t pos2 = 0;
        const UnicodeString* str1 = NULL;
        const UnicodeString* str2 = NULL;

        while((str1 = snext(pos1, status))!=NULL){ 
            str2 = enum2.snext(pos2, status);
            if(U_FAILURE(status)){
                return FALSE;
            }
            if(*str1 != *str2){
                // bail out at the first failure
                return FALSE;
            }
            
        }
        // if we reached here that means that the enumerations are equal
        return TRUE;
    }
public:
    virtual UBool operator==(const StringEnumeration& that)const{
        return ((this == &that) ||
            (getDynamicClassID() == that.getDynamicClassID() &&
            StringEnumeration::operator==(that) &&
            equals(that)));
    }
};

UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeZoneKeysEnumeration)

void
DateFormatSymbols::initZoneStringsArray(UErrorCode& status){
    if(fZoneStringsHash == NULL){
        initZoneStrings(status);
    }
    if(U_FAILURE(status)){
        return;
    }
    fZoneStringsRowCount = fZoneIDEnumeration->count(status);
    fZoneStringsColCount = 8;
    fZoneStrings = (UnicodeString **)uprv_malloc(fZoneStringsRowCount * sizeof(UnicodeString *));
    /* if we can't get a chunk of heap then the system is going down. Pin the blame on system*/
    if (fZoneStrings == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    const UnicodeString *zid = NULL;
    TimeZoneKeysEnumeration *keys = (TimeZoneKeysEnumeration*) fZoneIDEnumeration;
    int32_t pos = 0;
    int32_t i = 0;
    while((zid=keys->snext(pos,status))!=NULL){
        *(fZoneStrings+i) = newUnicodeStringArray(fZoneStringsColCount);
        /* test for NULL */
        if ((*(fZoneStrings+i)) == 0) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        UnicodeString* strings = (UnicodeString*)fZoneStringsHash->get(*zid);
        fZoneStrings[i][0].setTo(*zid);
        fZoneStrings[i][1].setTo(strings[TIMEZONE_LONG_STANDARD]);
        fZoneStrings[i][2].setTo(strings[TIMEZONE_SHORT_STANDARD]);
        fZoneStrings[i][3].setTo(strings[TIMEZONE_LONG_DAYLIGHT]);
        fZoneStrings[i][4].setTo(strings[TIMEZONE_SHORT_DAYLIGHT]);
        fZoneStrings[i][5].setTo(strings[TIMEZONE_EXEMPLAR_CITY]);
        fZoneStrings[i][6].setTo(strings[TIMEZONE_LONG_GENERIC]);
        fZoneStrings[i][7].setTo(strings[TIMEZONE_SHORT_GENERIC]);
        i++;
    }
}

U_CDECL_BEGIN
static UBool U_CALLCONV 
compareTZHashValues(const UHashTok val1, const UHashTok val2){

    const UnicodeString* array1 = (UnicodeString*) val1.pointer;
    const UnicodeString* array2 = (UnicodeString*) val2.pointer;
    if(array1==array2){
        return TRUE;
    }
    if(array1==NULL || array2==NULL){
        return FALSE;
    }
    for(int32_t j=0; j< UTZ_MAX_DISPLAY_STRINGS_LENGTH; j++){
        if(array1[j] != array2[j]){
            return FALSE;
        }
    }
    return TRUE;
}
U_CDECL_END

void
DateFormatSymbols::initZoneStrings(UErrorCode &status){
    if(U_FAILURE(status)){
        return;
    }  

    if(fZoneStringsHash != NULL){
        return;
    }
    int32_t i;

    fZoneStringsHash = new Hashtable(uhash_compareUnicodeString, compareTZHashValues, status);
    if(fZoneStringsHash==NULL){
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    fZoneStringsHash->setValueDeleter(deleteUnicodeStringArray);

    if(fResourceBundle != NULL){
        UnicodeString solidus = UNICODE_STRING_SIMPLE("/");
        UnicodeString colon = UNICODE_STRING_SIMPLE(":");
        UResourceBundle *zoneArray, *zoneItem;
        for(const UResourceBundle* rb = fResourceBundle; rb!=NULL; rb=ures_getParentBundle(rb)){
            zoneArray = ures_getByKey(rb, gZoneStringsTag, NULL, &status);
            if(U_FAILURE(status)){
                break;
            }
            while(ures_hasNext(zoneArray)){
                UErrorCode tempStatus = U_ZERO_ERROR;
                zoneItem = ures_getNextResource(zoneArray, NULL, &status);
                UnicodeString key(ures_getKey(zoneItem), -1, US_INV);
                if (key.indexOf(colon) == -1) {
                    ures_close(zoneItem);
                    continue;
                }
                UnicodeString* strArray = newUnicodeStringArray(UTZ_MAX_DISPLAY_STRINGS_LENGTH);
                key.findAndReplace(colon, solidus);
                int32_t len = 0;
                //fetch the strings with fine grained fallback
                const UChar* str = ures_getStringByKeyWithFallback(zoneItem,UTZ_SHORT_STANDARD, &len, &tempStatus);
                if(U_SUCCESS(tempStatus)){
                    strArray[TIMEZONE_SHORT_STANDARD].setTo(TRUE, str, len);
                }else{
                    tempStatus = U_ZERO_ERROR;
                }
                str = ures_getStringByKeyWithFallback(zoneItem,UTZ_SHORT_GENERIC, &len, &tempStatus);
                if(U_SUCCESS(tempStatus)){
                    strArray[TIMEZONE_SHORT_GENERIC].setTo(TRUE, str, len);
                }else{
                    tempStatus = U_ZERO_ERROR;
                }                
                str = ures_getStringByKeyWithFallback(zoneItem,UTZ_SHORT_DAYLIGHT, &len, &tempStatus);
                if(U_SUCCESS(tempStatus)){
                    strArray[TIMEZONE_SHORT_DAYLIGHT].setTo(TRUE, str, len);
                }else{
                    tempStatus = U_ZERO_ERROR;
                }
                str = ures_getStringByKeyWithFallback(zoneItem,UTZ_LONG_STANDARD, &len, &tempStatus);
                if(U_SUCCESS(tempStatus)){
                    strArray[TIMEZONE_LONG_STANDARD].setTo(TRUE, str, len);
                }else{
                    tempStatus = U_ZERO_ERROR;
                }
                str = ures_getStringByKeyWithFallback(zoneItem,UTZ_LONG_GENERIC, &len, &tempStatus);
                if(U_SUCCESS(tempStatus)){
                    strArray[TIMEZONE_LONG_GENERIC].setTo(TRUE, str, len);
                }else{
                    tempStatus = U_ZERO_ERROR;
                }                
                str = ures_getStringByKeyWithFallback(zoneItem,UTZ_LONG_DAYLIGHT, &len, &tempStatus);
                if(U_SUCCESS(tempStatus)){
                    strArray[TIMEZONE_LONG_DAYLIGHT].setTo(TRUE, str, len);
                }else{
                    tempStatus = U_ZERO_ERROR;
                }
                str = ures_getStringByKeyWithFallback(zoneItem,UTZ_EXEMPLAR_CITY, &len, &tempStatus);
                if(U_SUCCESS(tempStatus)){
                    strArray[TIMEZONE_EXEMPLAR_CITY].setTo(TRUE, str, len);
                }else{
                    tempStatus = U_ZERO_ERROR;
                }
                // store the strings in hash
                fZoneStringsHash->put(key, strArray, status);
                ures_close(zoneItem);
            }

            ures_close(zoneArray);
        }

        // Need to make sure that all zoneStrings in root are covered as well, otherwise metazone lookups won't
        // work properly
        UResourceBundle* root_res = ures_open(NULL, "", &status);
        zoneArray = ures_getByKey(root_res, gZoneStringsTag, NULL, &status);
        if (U_SUCCESS(status)) {
            while(ures_hasNext(zoneArray)){
                UErrorCode tempStatus = U_ZERO_ERROR;
                zoneItem = ures_getNextResource(zoneArray, NULL, &status);
                UnicodeString key(ures_getKey(zoneItem), -1, US_INV);
                if ( key.indexOf(colon) == -1 ) {
                    ures_close(zoneItem);
                    continue;
                }
                key.findAndReplace(colon, solidus);

                // Don't step on anything that is already there
                UnicodeString* existingArray = (UnicodeString*)fZoneStringsHash->get(key);
                if(existingArray != NULL){
                    ures_close(zoneItem);
                    continue;
                }
                UnicodeString* strArray = newUnicodeStringArray(UTZ_MAX_DISPLAY_STRINGS_LENGTH);
                int32_t len = 0;

                const UChar *str = ures_getStringByKeyWithFallback(zoneItem,UTZ_EXEMPLAR_CITY, &len, &tempStatus);
                if(U_SUCCESS(tempStatus)){
                    strArray[TIMEZONE_EXEMPLAR_CITY].setTo(TRUE, str, len);
                }else{
                    tempStatus = U_ZERO_ERROR;
                }
                // store the strings in hash
                fZoneStringsHash->put(key, strArray, status);
                ures_close(zoneItem);
            }
            ures_close(zoneArray);
            ures_close(root_res);
        }

        int32_t length = fZoneStringsHash->count();
        TimeZoneKeysEnumeration* keysEnum = new TimeZoneKeysEnumeration(length, status);
        fZoneIDEnumeration = keysEnum;
        if(fZoneIDEnumeration==NULL){
            delete fZoneStringsHash;
            fZoneStringsHash = NULL;
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        int32_t pos=-1;
        const UnicodeString* key; 
        const UHashElement* elem = NULL;
        while((elem = fZoneStringsHash->nextElement(pos))!= NULL){  
            const UHashTok keyTok = elem->key;
            key = (const UnicodeString*)keyTok.pointer;
            keysEnum->put(*key, status);
        }
    }else{
        //last resort strings
        UnicodeString* array = newUnicodeStringArray(UTZ_MAX_DISPLAY_STRINGS_LENGTH);
        if(array==NULL){
            delete fZoneStringsHash;
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        int32_t length = ARRAY_LENGTH(gLastResortZoneStrings);
        UnicodeString key(gLastResortZoneStrings[0]);
        TimeZoneKeysEnumeration* keysEnum = new TimeZoneKeysEnumeration(length, status);
        fZoneIDEnumeration = keysEnum;
        if(fZoneIDEnumeration==NULL){
            delete fZoneStringsHash;
            delete[] array;
            fZoneStringsHash = NULL;
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        keysEnum->put(key, status);
        int32_t j=1;
        for(i=0; i< length; ){
            array[i++].setTo(gLastResortZoneStrings[j++]);
        }
        fZoneStringsHash->put(key, array, status);
    }
}
void 
DateFormatSymbols::initZoneStrings(const UnicodeString** strings, int32_t rowCount, int32_t columnCount, UErrorCode& status){
    if(strings==NULL || rowCount<0 || columnCount<0){
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    TimeZoneKeysEnumeration* keysEnum = new TimeZoneKeysEnumeration(rowCount, status);
    fZoneIDEnumeration = keysEnum;
    if(U_FAILURE(status)){
        return;
    }
    if(fZoneIDEnumeration==NULL){
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    fZoneStringsHash = new Hashtable(uhash_compareUnicodeString, compareTZHashValues, status);
    if(U_FAILURE(status)){
        return;
    }
    if(fZoneStringsHash==NULL){
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    fZoneStringsHash->setValueDeleter(deleteUnicodeStringArray);
    for (int32_t row=0; row<rowCount; ++row){
        // the first string in the array is the key.
        UnicodeString key = strings[row][0];
        keysEnum->put(key, status);
        UnicodeString* array = newUnicodeStringArray(UTZ_MAX_DISPLAY_STRINGS_LENGTH);
        if(array==NULL){
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        for (int32_t col=1; col<columnCount; ++col) {
            // fastCopyFrom() - see assignArray comments
            switch (col){
                case 1:
                    array[TIMEZONE_LONG_STANDARD].setTo(strings[row][col]);
                    break;
                case 2:
                    array[TIMEZONE_SHORT_STANDARD].setTo(strings[row][col]);
                    break;
                case 3:
                    array[TIMEZONE_LONG_DAYLIGHT].setTo(strings[row][col]);
                    break;
                case 4:
                     array[TIMEZONE_LONG_DAYLIGHT].setTo(strings[row][col]);
                     break;
                case 5:
                     array[TIMEZONE_EXEMPLAR_CITY].setTo(strings[row][col]);
                     break;
                case 6:
                     array[TIMEZONE_LONG_GENERIC].setTo(strings[row][col]);
                     break; 
                case 7:
                     array[TIMEZONE_SHORT_GENERIC].setTo(strings[row][col]);
                     break;
                default:
                    status = U_ILLEGAL_ARGUMENT_ERROR;
            }
            // populate the hash table
            fZoneStringsHash->put(strings[row][0], array, status);
        }
    }

}

UnicodeString&
DateFormatSymbols::getZoneString(const UnicodeString &zid, const TimeZoneTranslationType type, 
                                 UnicodeString &result, UErrorCode &status){

    if(fZoneStringsHash == NULL){
        //lazy initialization
        initZoneStrings(status);
    }
    if(U_FAILURE(status)){
        return result;
    }

    UnicodeString* stringsArray = (UnicodeString*)fZoneStringsHash->get(zid);
    if(stringsArray != NULL){
        result.setTo(stringsArray[type],0);
    }
    return result;
}

UnicodeString&
DateFormatSymbols::getMetazoneString(const UnicodeString &zid, const TimeZoneTranslationType type, Calendar &cal,
                                 UnicodeString &result, UErrorCode &status)
{
    UErrorCode tempStatus = U_ZERO_ERROR;
    int32_t len;

    // Get the appropriate metazone mapping from the resource bundles

    char usesMetazoneKey[ZID_KEY_MAX];
    char zidkey[ZID_KEY_MAX];

    uprv_strcpy(usesMetazoneKey,gZoneStringsTag);
    uprv_strcat(usesMetazoneKey,"/");

    len = zid.length();
    len = (len >= (ZID_KEY_MAX-1) ? ZID_KEY_MAX-1 : len);
    u_UCharsToChars(zid.getBuffer(), zidkey, len);
    zidkey[len] = 0; // NULL terminate

    // Replace / with : for zid
    len = (int32_t)uprv_strlen(zidkey);
    for (int i = 0; i < len; i++) {
        if (zidkey[i] == '/') {
            zidkey[i] = ':';
        }
    }

    uprv_strcat(usesMetazoneKey,zidkey);
    uprv_strcat(usesMetazoneKey,"/");
    uprv_strcat(usesMetazoneKey,UTZ_USES_METAZONE);

    UResourceBundle *um = ures_getByKeyWithFallback(fResourceBundle, usesMetazoneKey, NULL, &tempStatus);
    if (U_FAILURE(tempStatus)) {
        return result;
    }

    UnicodeString* stringsArray = (UnicodeString*)fZoneStringsHash->get(zid);

    if(stringsArray != NULL){
        SimpleDateFormat df(UNICODE_STRING_SIMPLE("yyyy-MM-dd HH:mm"), Locale(""),tempStatus);
        TimeZone *tz = TimeZone::createTimeZone(zid);
        df.setTimeZone(*tz);
        delete tz;
        UnicodeString theTime;
        df.format(cal.getTime(tempStatus),theTime);

        while (ures_hasNext(um)) {
            UResourceBundle *mz = ures_getNextResource(um,NULL,&status);
            const UChar *mz_name = ures_getStringByIndex(mz,0,&len,&status);
            const UChar *mz_from = ures_getStringByIndex(mz,1,&len,&status);
            const UChar *mz_to   = ures_getStringByIndex(mz,2,&len,&status);
            ures_close(mz);
            if(U_FAILURE(status)){
                break;
            }

            if (mz_name[0] != 0 &&
                UnicodeString(TRUE, mz_from, -1) <= theTime &&
                UnicodeString(TRUE, mz_to, -1) > theTime )
            {
                UnicodeString mzid(UNICODE_STRING_SIMPLE("meta/"));
                mzid += mz_name;
                getZoneString(mzid,type,result,status);
                break;
            }
        }
    } 
    ures_close(um);
    return result;
}
StringEnumeration* 
DateFormatSymbols::createZoneStringIDs(UErrorCode &status){
    if(U_FAILURE(status)){
        return NULL;
    }
    if(fZoneStringsHash == NULL){
        //lazy initialization
        initZoneStrings(status);
    }
    return fZoneIDEnumeration->clone();
}

/**
 * Sets timezone strings.
 * @draft ICU 3.6
 */
void 
DateFormatSymbols::setZoneString(const UnicodeString &zid, const TimeZoneTranslationType type,
                                 const UnicodeString &value, UErrorCode &status){
    if(fZoneStringsHash == NULL){
        //lazy initialization
        initZoneStrings(status);
    }
    if(U_FAILURE(status)){
        return;
    }
    UnicodeString* stringsArray = (UnicodeString*)fZoneStringsHash->get(zid);
    if(stringsArray != NULL){
        stringsArray[type].setTo(value);
    }else{
        stringsArray = newUnicodeStringArray(UTZ_MAX_DISPLAY_STRINGS_LENGTH); 
        if(stringsArray==NULL){
            status = U_MEMORY_ALLOCATION_ERROR;
            return;
        }
        stringsArray[type].setTo(value);
        fZoneStringsHash->put(zid, stringsArray, status);
        TimeZoneKeysEnumeration* keys = (TimeZoneKeysEnumeration*) fZoneIDEnumeration;
        keys->put(zid, status);
    }
}

Hashtable* 
DateFormatSymbols::createZoneStringsHash(const Hashtable* otherHash){
    UErrorCode status = U_ZERO_ERROR;
    Hashtable* hash = new Hashtable(uhash_compareUnicodeString, compareTZHashValues, status);
    if(hash==NULL){
        return NULL;
    }
    if(U_FAILURE(status)){
        return NULL;
    }
    hash->setValueDeleter(deleteUnicodeStringArray);
    int32_t pos = -1;
    const UHashElement* elem = NULL;
    // walk through the hash table and create a deep clone 
    while((elem = otherHash->nextElement(pos))!= NULL){
        const UHashTok otherKeyTok = elem->key;
        const UHashTok otherValueTok = elem->value;
        UnicodeString* otherKey = (UnicodeString*)otherKeyTok.pointer;
        UnicodeString* otherArray = (UnicodeString*)otherValueTok.pointer;
        UnicodeString* array = newUnicodeStringArray(UTZ_MAX_DISPLAY_STRINGS_LENGTH);
        if(array==NULL){
            return NULL;
        }
        UnicodeString key(*otherKey);
        for(int32_t i=0; i<UTZ_MAX_DISPLAY_STRINGS_LENGTH; i++){
            array[i].setTo(otherArray[i]);
        }
        hash->put(key, array, status);
        if(U_FAILURE(status)){
            delete[] array;
            return NULL;
        }
    } 
    return hash;
}


UnicodeString&
DateFormatSymbols::getZoneID(const UnicodeString& zid, UnicodeString& result, UErrorCode& status){
    if(fZoneStringsHash == NULL){
        initZoneStrings(status); 
    }
    if(U_FAILURE(status)){
        return result;
    }
    UnicodeString* strings = (UnicodeString*)fZoneStringsHash->get(zid);
    if (strings != NULL) {
        return result.setTo(zid,0);
    }

    // Do a search through the equivalency group for the given ID
    int32_t n = TimeZone::countEquivalentIDs(zid);
    if (n > 1) {
        int32_t i;
        for (i=0; i<n; ++i) {
            UnicodeString equivID = TimeZone::getEquivalentID(zid, i);
            if (equivID != zid) {
                strings = (UnicodeString*)fZoneStringsHash->get(equivID);
                if (strings != NULL) {
                    return result.setTo(equivID,0);
                }
            }
        }
    }else{
        result.setTo(zid);
    }
    return result;
}

void
DateFormatSymbols::getZoneType(const UnicodeString& zid, const UnicodeString& text, int32_t start, 
                               TimeZoneTranslationType& type, UnicodeString& value, UErrorCode& status){
    if(fZoneStringsHash == NULL){
        initZoneStrings(status);
    }
    if(U_FAILURE(status)){
        return;
    }
    type = TIMEZONE_COUNT;
    UnicodeString* strings = (UnicodeString*)fZoneStringsHash->get(zid);
    if(strings != NULL){
        for(int32_t j=0; j<UTZ_MAX_DISPLAY_STRINGS_LENGTH; j++){
            if(strings[j].length() >0 && text.caseCompare(start, strings[j].length(), strings[j], 0)==0){
                type = (TimeZoneTranslationType)j;
                value.setTo(strings[j]);
                return;
            }
        }
    }
}
void
DateFormatSymbols::findZoneIDTypeValue( UnicodeString& zid, const UnicodeString& text, int32_t start, 
                                        TimeZoneTranslationType& type, UnicodeString& value,
                                        UErrorCode& status){
    if(fZoneStringsHash == NULL){
        initZoneStrings(status);
    }
    if(U_FAILURE(status)){
        return;
    }
    const UnicodeString* myKey = NULL;
    int32_t pos = 0;
    TimeZoneKeysEnumeration *keys = (TimeZoneKeysEnumeration*)fZoneIDEnumeration;
    while( (myKey=keys->snext(pos, status))!= NULL){
        UnicodeString* strings = (UnicodeString*)fZoneStringsHash->get(*myKey);
        if(strings != NULL){
            for(int32_t j=0; j<UTZ_MAX_DISPLAY_STRINGS_LENGTH; j++){
                if(strings[j].length()>0 && text.caseCompare(start, strings[j].length(), strings[j], 0)==0){
                    type = (TimeZoneTranslationType)j;
                    value.setTo(strings[j]);
                    if (myKey->startsWith(UNICODE_STRING_SIMPLE("meta"))) {
                       zid.setTo(resolveParsedMetazone(*myKey));
                    }
                    else
                       zid.setTo(*myKey);
                    return;
                }
            }
        }
    }
}

UnicodeString
DateFormatSymbols::resolveParsedMetazone( const UnicodeString& zid ) {
    if ( zid == UNICODE_STRING_SIMPLE("meta/America_Pacific")) return UNICODE_STRING_SIMPLE("America/Los_Angeles");
    if ( zid == UNICODE_STRING_SIMPLE("meta/America_Mountain")) return UNICODE_STRING_SIMPLE("America/Denver");
    if ( zid == UNICODE_STRING_SIMPLE("meta/America_Central")) return UNICODE_STRING_SIMPLE("America/Chicago");
    if ( zid == UNICODE_STRING_SIMPLE("meta/America_Eastern")) return UNICODE_STRING_SIMPLE("America/New_York");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Acre")) return UNICODE_STRING_SIMPLE("America/Rio_Branco");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Africa_Central")) return UNICODE_STRING_SIMPLE("Africa/Maputo");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Africa_Eastern")) return UNICODE_STRING_SIMPLE("Africa/Nairobi");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Africa_Southern")) return UNICODE_STRING_SIMPLE("Africa/Johannesburg");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Africa_Western")) return UNICODE_STRING_SIMPLE("Africa/Lagos");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Alaska")) return UNICODE_STRING_SIMPLE("America/Anchorage");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Alaska_Hawaii")) return UNICODE_STRING_SIMPLE("America/Anchorage");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Amazon")) return UNICODE_STRING_SIMPLE("America/Manaus");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Aqtau")) return UNICODE_STRING_SIMPLE("Asia/Aqtau");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Aqtobe")) return UNICODE_STRING_SIMPLE("Asia/Aqtobe");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Arabian")) return UNICODE_STRING_SIMPLE("Asia/Riyadh");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Argentina")) return UNICODE_STRING_SIMPLE("America/Buenos_Aires");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Argentina_Western")) return UNICODE_STRING_SIMPLE("America/Catamarca");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Armenia")) return UNICODE_STRING_SIMPLE("Asia/Yerevan");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Ashkhabad")) return UNICODE_STRING_SIMPLE("Asia/Ashgabat");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Atlantic")) return UNICODE_STRING_SIMPLE("America/Halifax");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Australia_Central")) return UNICODE_STRING_SIMPLE("Australia/Adelaide");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Australia_Eastern")) return UNICODE_STRING_SIMPLE("Australia/Sydney");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Australia_Western")) return UNICODE_STRING_SIMPLE("Australia/Perth");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Azores")) return UNICODE_STRING_SIMPLE("Atlantic/Azores");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Baku")) return UNICODE_STRING_SIMPLE("Asia/Baku");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Bangladesh")) return UNICODE_STRING_SIMPLE("Asia/Dhaka");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Bering")) return UNICODE_STRING_SIMPLE("America/Adak");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Bhutan")) return UNICODE_STRING_SIMPLE("Asia/Thimphu");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Borneo")) return UNICODE_STRING_SIMPLE("Asia/Kuching");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Brasilia")) return UNICODE_STRING_SIMPLE("America/Sao_Paulo");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Chamorro")) return UNICODE_STRING_SIMPLE("Pacific/Saipan");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Changbai")) return UNICODE_STRING_SIMPLE("Asia/Harbin");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Chile")) return UNICODE_STRING_SIMPLE("America/Santiago");
    if ( zid == UNICODE_STRING_SIMPLE("meta/China")) return UNICODE_STRING_SIMPLE("Asia/Shanghai");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Choibalsan")) return UNICODE_STRING_SIMPLE("Asia/Choibalsan");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Dacca")) return UNICODE_STRING_SIMPLE("Asia/Dhaka");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Dushanbe")) return UNICODE_STRING_SIMPLE("Asia/Dushanbe");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Dutch_Guiana")) return UNICODE_STRING_SIMPLE("America/Paramaribo");
    if ( zid == UNICODE_STRING_SIMPLE("meta/East_Timor")) return UNICODE_STRING_SIMPLE("Asia/Dili");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Ecuador")) return UNICODE_STRING_SIMPLE("America/Guayaquil");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Europe_Central")) return UNICODE_STRING_SIMPLE("Europe/Paris");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Europe_Eastern")) return UNICODE_STRING_SIMPLE("Europe/Bucharest");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Europe_Western")) return UNICODE_STRING_SIMPLE("Europe/Lisbon");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Frunze")) return UNICODE_STRING_SIMPLE("Asia/Bishkek");
    if ( zid == UNICODE_STRING_SIMPLE("meta/GMT")) return UNICODE_STRING_SIMPLE("Europe/London");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Galapagos")) return UNICODE_STRING_SIMPLE("Pacific/Galapagos");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Georgia")) return UNICODE_STRING_SIMPLE("Asia/Tbilisi");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Greenland_Central")) return UNICODE_STRING_SIMPLE("America/Scoresbysund");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Greenland_Eastern")) return UNICODE_STRING_SIMPLE("America/Scoresbysund");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Greenland_Western")) return UNICODE_STRING_SIMPLE("America/Godthab");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Guam")) return UNICODE_STRING_SIMPLE("Pacific/Guam");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Gulf")) return UNICODE_STRING_SIMPLE("Asia/Dubai");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Hawaii")) return UNICODE_STRING_SIMPLE("Pacific/Honolulu");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Hawaii_Aleutian")) return UNICODE_STRING_SIMPLE("America/Adak");
    if ( zid == UNICODE_STRING_SIMPLE("meta/India")) return UNICODE_STRING_SIMPLE("Asia/Calcutta");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Indonesia_Central")) return UNICODE_STRING_SIMPLE("Asia/Makassar");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Indonesia_Eastern")) return UNICODE_STRING_SIMPLE("Asia/Jayapura");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Indonesia_Western")) return UNICODE_STRING_SIMPLE("Asia/Jakarta");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Israel")) return UNICODE_STRING_SIMPLE("Asia/Jerusalem");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Karachi")) return UNICODE_STRING_SIMPLE("Asia/Karachi");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Kashgar")) return UNICODE_STRING_SIMPLE("Asia/Kashgar");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Kazakhstan_Eastern")) return UNICODE_STRING_SIMPLE("Asia/Almaty");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Kazakhstan_Western")) return UNICODE_STRING_SIMPLE("Asia/Aqtau");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Kizilorda")) return UNICODE_STRING_SIMPLE("Asia/Qyzylorda");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Korea")) return UNICODE_STRING_SIMPLE("Asia/Seoul");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Kuybyshev")) return UNICODE_STRING_SIMPLE("Europe/Samara");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Kwajalein")) return UNICODE_STRING_SIMPLE("Pacific/Kwajalein");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Kyrgystan")) return UNICODE_STRING_SIMPLE("Asia/Bishkek");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Lanka")) return UNICODE_STRING_SIMPLE("Asia/Colombo");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Long_Shu")) return UNICODE_STRING_SIMPLE("Asia/Chongqing");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Lord_Howe")) return UNICODE_STRING_SIMPLE("Australia/Lord_Howe");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Macau")) return UNICODE_STRING_SIMPLE("Asia/Macau");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Malaya")) return UNICODE_STRING_SIMPLE("Asia/Kuala_Lumpur");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Malaysia")) return UNICODE_STRING_SIMPLE("Asia/Kuala_Lumpur");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Marshall_Islands")) return UNICODE_STRING_SIMPLE("Pacific/Majuro");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Mongolia")) return UNICODE_STRING_SIMPLE("Asia/Ulaanbaatar");
    if ( zid == UNICODE_STRING_SIMPLE("meta/New_Zealand")) return UNICODE_STRING_SIMPLE("Pacific/Auckland");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Newfoundland")) return UNICODE_STRING_SIMPLE("America/St_Johns");
    if ( zid == UNICODE_STRING_SIMPLE("meta/North_Mariana")) return UNICODE_STRING_SIMPLE("Pacific/Saipan");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Pakistan")) return UNICODE_STRING_SIMPLE("Asia/Karachi");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Pierre_Miquelon")) return UNICODE_STRING_SIMPLE("America/Miquelon");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Qyzylorda")) return UNICODE_STRING_SIMPLE("Asia/Qyzylorda");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Samara")) return UNICODE_STRING_SIMPLE("Europe/Samara");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Samarkand")) return UNICODE_STRING_SIMPLE("Asia/Samarkand");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Samoa")) return UNICODE_STRING_SIMPLE("Pacific/Apia");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Shevchenko")) return UNICODE_STRING_SIMPLE("Asia/Aqtau");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Suriname")) return UNICODE_STRING_SIMPLE("America/Paramaribo");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Sverdlovsk")) return UNICODE_STRING_SIMPLE("Asia/Yekaterinburg");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Tajikistan")) return UNICODE_STRING_SIMPLE("Asia/Dushanbe");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Tashkent")) return UNICODE_STRING_SIMPLE("Asia/Tashkent");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Tbilisi")) return UNICODE_STRING_SIMPLE("Asia/Tbilisi");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Turkey")) return UNICODE_STRING_SIMPLE("Europe/Istanbul");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Turkmenistan")) return UNICODE_STRING_SIMPLE("Asia/Ashgabat");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Uralsk")) return UNICODE_STRING_SIMPLE("Asia/Oral");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Urumqi")) return UNICODE_STRING_SIMPLE("Asia/Urumqi");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Uzbekistan")) return UNICODE_STRING_SIMPLE("Asia/Tashkent");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Yekaterinburg")) return UNICODE_STRING_SIMPLE("Asia/Yekaterinburg");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Yerevan")) return UNICODE_STRING_SIMPLE("Asia/Yerevan");
    if ( zid == UNICODE_STRING_SIMPLE("meta/Yukon")) return UNICODE_STRING_SIMPLE("America/Dawson");
    return UnicodeString();
}
U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

//eof
