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

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#if defined(STARBOARD)
#include "starboard/client_porting/poem/assert_poem.h"
#include "starboard/client_porting/poem/string_poem.h"
#endif  // defined(STARBOARD)
#include "unicode/calendar.h"
#include "unicode/tzfmt.h"
#include "unicode/numsys.h"
#include "unicode/strenum.h"
#include "unicode/uchar.h"
#include "unicode/udat.h"
#include "unicode/ustring.h"
#include "unicode/utf16.h"
#include "bytesinkutil.h"
#include "charstr.h"
#include "tzgnames.h"
#include "cmemory.h"
#include "cstring.h"
#include "putilimp.h"
#include "uassert.h"
#include "ucln_in.h"
#include "ulocimp.h"
#include "umutex.h"
#include "uresimp.h"
#include "ureslocs.h"
#include "uvector.h"
#include "zonemeta.h"
#include "tznames_impl.h"   // TextTrieMap
#include "patternprops.h"

U_NAMESPACE_BEGIN

// Bit flags used by the parse method.
// The order must match UTimeZoneFormatStyle enum.
#define ISO_Z_STYLE_FLAG 0x0080
#define ISO_LOCAL_STYLE_FLAG 0x0100
static const int16_t STYLE_PARSE_FLAGS[] = {
    0x0001, // UTZFMT_STYLE_GENERIC_LOCATION,
    0x0002, // UTZFMT_STYLE_GENERIC_LONG,
    0x0004, // UTZFMT_STYLE_GENERIC_SHORT,
    0x0008, // UTZFMT_STYLE_SPECIFIC_LONG,
    0x0010, // UTZFMT_STYLE_SPECIFIC_SHORT,
    0x0020, // UTZFMT_STYLE_LOCALIZED_GMT,
    0x0040, // UTZFMT_STYLE_LOCALIZED_GMT_SHORT,
    ISO_Z_STYLE_FLAG,       // UTZFMT_STYLE_ISO_BASIC_SHORT,
    ISO_LOCAL_STYLE_FLAG,   // UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT,
    ISO_Z_STYLE_FLAG,       // UTZFMT_STYLE_ISO_BASIC_FIXED,
    ISO_LOCAL_STYLE_FLAG,   // UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED,
    ISO_Z_STYLE_FLAG,       // UTZFMT_STYLE_ISO_BASIC_FULL,
    ISO_LOCAL_STYLE_FLAG,   // UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL,
    ISO_Z_STYLE_FLAG,       // UTZFMT_STYLE_ISO_EXTENDED_FIXED,
    ISO_LOCAL_STYLE_FLAG,   // UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED,
    ISO_Z_STYLE_FLAG,       // UTZFMT_STYLE_ISO_EXTENDED_FULL,
    ISO_LOCAL_STYLE_FLAG,   // UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL,
    0x0200, // UTZFMT_STYLE_ZONE_ID,
    0x0400, // UTZFMT_STYLE_ZONE_ID_SHORT,
    0x0800  // UTZFMT_STYLE_EXEMPLAR_LOCATION
};

static const char gZoneStringsTag[] = "zoneStrings";
static const char gGmtFormatTag[]= "gmtFormat";
static const char gGmtZeroFormatTag[] = "gmtZeroFormat";
static const char gHourFormatTag[]= "hourFormat";

static const UChar TZID_GMT[] = {0x0045, 0x0074, 0x0063, 0x002F, 0x0047, 0x004D, 0x0054, 0};    // Etc/GMT
static const UChar UNKNOWN_ZONE_ID[] = {
    0x0045, 0x0074, 0x0063, 0x002F, 0x0055, 0x006E, 0x006B, 0x006E, 0x006F, 0x0077, 0x006E, 0}; // Etc/Unknown
static const UChar UNKNOWN_SHORT_ZONE_ID[] = {0x0075, 0x006E, 0x006B, 0};   // unk
static const UChar UNKNOWN_LOCATION[] = {0x0055, 0x006E, 0x006B, 0x006E, 0x006F, 0x0077, 0x006E, 0};    // Unknown

static const UChar DEFAULT_GMT_PATTERN[] = {0x0047, 0x004D, 0x0054, 0x007B, 0x0030, 0x007D, 0}; // GMT{0}
//static const UChar DEFAULT_GMT_ZERO[] = {0x0047, 0x004D, 0x0054, 0}; // GMT
static const UChar DEFAULT_GMT_POSITIVE_HM[] = {0x002B, 0x0048, 0x003A, 0x006D, 0x006D, 0}; // +H:mm
static const UChar DEFAULT_GMT_POSITIVE_HMS[] = {0x002B, 0x0048, 0x003A, 0x006D, 0x006D, 0x003A, 0x0073, 0x0073, 0}; // +H:mm:ss
static const UChar DEFAULT_GMT_NEGATIVE_HM[] = {0x002D, 0x0048, 0x003A, 0x006D, 0x006D, 0}; // -H:mm
static const UChar DEFAULT_GMT_NEGATIVE_HMS[] = {0x002D, 0x0048, 0x003A, 0x006D, 0x006D, 0x003A, 0x0073, 0x0073, 0}; // -H:mm:ss
static const UChar DEFAULT_GMT_POSITIVE_H[] = {0x002B, 0x0048, 0}; // +H
static const UChar DEFAULT_GMT_NEGATIVE_H[] = {0x002D, 0x0048, 0}; // -H

static const UChar32 DEFAULT_GMT_DIGITS[] = {
    0x0030, 0x0031, 0x0032, 0x0033, 0x0034,
    0x0035, 0x0036, 0x0037, 0x0038, 0x0039
};

static const UChar DEFAULT_GMT_OFFSET_SEP = 0x003A; // ':'

static const UChar ARG0[] = {0x007B, 0x0030, 0x007D};   // "{0}"
static const int32_t ARG0_LEN = 3;

static const UChar DEFAULT_GMT_OFFSET_MINUTE_PATTERN[] = {0x006D, 0x006D, 0};   // "mm"
static const UChar DEFAULT_GMT_OFFSET_SECOND_PATTERN[] = {0x0073, 0x0073, 0};   // "ss"

static const UChar ALT_GMT_STRINGS[][4] = {
    {0x0047, 0x004D, 0x0054, 0},    // GMT
    {0x0055, 0x0054, 0x0043, 0},    // UTC
    {0x0055, 0x0054, 0, 0},         // UT
    {0, 0, 0, 0}
};

// Order of GMT offset pattern parsing, *_HMS must be evaluated first
// because *_HM is most likely a substring of *_HMS 
static const int32_t PARSE_GMT_OFFSET_TYPES[] = {
    UTZFMT_PAT_POSITIVE_HMS,
    UTZFMT_PAT_NEGATIVE_HMS,
    UTZFMT_PAT_POSITIVE_HM,
    UTZFMT_PAT_NEGATIVE_HM,
    UTZFMT_PAT_POSITIVE_H,
    UTZFMT_PAT_NEGATIVE_H,
    -1
};

static const UChar SINGLEQUOTE  = 0x0027;
static const UChar PLUS         = 0x002B;
static const UChar MINUS        = 0x002D;
static const UChar ISO8601_UTC  = 0x005A;   // 'Z'
static const UChar ISO8601_SEP  = 0x003A;   // ':'

static const int32_t MILLIS_PER_HOUR = 60 * 60 * 1000;
static const int32_t MILLIS_PER_MINUTE = 60 * 1000;
static const int32_t MILLIS_PER_SECOND = 1000;

// Maximum offset (exclusive) in millisecond supported by offset formats
static int32_t MAX_OFFSET = 24 * MILLIS_PER_HOUR;

// Maximum values for GMT offset fields
static const int32_t MAX_OFFSET_HOUR = 23;
static const int32_t MAX_OFFSET_MINUTE = 59;
static const int32_t MAX_OFFSET_SECOND = 59;

static const int32_t UNKNOWN_OFFSET = 0x7FFFFFFF;

static const int32_t ALL_SIMPLE_NAME_TYPES = UTZNM_LONG_STANDARD | UTZNM_LONG_DAYLIGHT | UTZNM_SHORT_STANDARD | UTZNM_SHORT_DAYLIGHT | UTZNM_EXEMPLAR_LOCATION;
static const int32_t ALL_GENERIC_NAME_TYPES = UTZGNM_LOCATION | UTZGNM_LONG | UTZGNM_SHORT;

#define DIGIT_VAL(c) (0x0030 <= (c) && (c) <= 0x0039 ? (c) - 0x0030 : -1)
#define MAX_OFFSET_DIGITS 6

// Time Zone ID/Short ID trie
static TextTrieMap *gZoneIdTrie = NULL;
static icu::UInitOnce gZoneIdTrieInitOnce = U_INITONCE_INITIALIZER;

static TextTrieMap *gShortZoneIdTrie = NULL;
static icu::UInitOnce gShortZoneIdTrieInitOnce = U_INITONCE_INITIALIZER;

static UMutex gLock;

U_CDECL_BEGIN
/**
 * Cleanup callback func
 */
static UBool U_CALLCONV tzfmt_cleanup(void)
{
    if (gZoneIdTrie != NULL) {
        delete gZoneIdTrie;
    }
    gZoneIdTrie = NULL;
    gZoneIdTrieInitOnce.reset();

    if (gShortZoneIdTrie != NULL) {
        delete gShortZoneIdTrie;
    }
    gShortZoneIdTrie = NULL;
    gShortZoneIdTrieInitOnce.reset();

    return TRUE;
}
U_CDECL_END

// ------------------------------------------------------------------
// GMTOffsetField
//
// This class represents a localized GMT offset pattern
// item and used by TimeZoneFormat
// ------------------------------------------------------------------
class GMTOffsetField : public UMemory {
public:
    enum FieldType {
        TEXT = 0,
        HOUR = 1,
        MINUTE = 2,
        SECOND = 4
    };

    virtual ~GMTOffsetField();

    static GMTOffsetField* createText(const UnicodeString& text, UErrorCode& status);
    static GMTOffsetField* createTimeField(FieldType type, uint8_t width, UErrorCode& status);
    static UBool isValid(FieldType type, int32_t width);
    static FieldType getTypeByLetter(UChar ch);

    FieldType getType() const;
    uint8_t getWidth() const;
    const UChar* getPatternText(void) const;

private:
    UChar* fText;
    FieldType fType;
    uint8_t fWidth;

    GMTOffsetField();
};

GMTOffsetField::GMTOffsetField()
: fText(NULL), fType(TEXT), fWidth(0) {
}

GMTOffsetField::~GMTOffsetField() {
    if (fText) {
        uprv_free(fText);
    }
}

GMTOffsetField*
GMTOffsetField::createText(const UnicodeString& text, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    GMTOffsetField* result = new GMTOffsetField();
    if (result == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    int32_t len = text.length();
    result->fText = (UChar*)uprv_malloc((len + 1) * sizeof(UChar));
    if (result->fText == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        delete result;
        return NULL;
    }
    u_strncpy(result->fText, text.getBuffer(), len);
    result->fText[len] = 0;
    result->fType = TEXT;

    return result;
}

GMTOffsetField*
GMTOffsetField::createTimeField(FieldType type, uint8_t width, UErrorCode& status) {
    U_ASSERT(type != TEXT);
    if (U_FAILURE(status)) {
        return NULL;
    }
    GMTOffsetField* result = new GMTOffsetField();
    if (result == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    result->fType = type;
    result->fWidth = width;

    return result;
}

UBool
GMTOffsetField::isValid(FieldType type, int32_t width) {
    switch (type) {
    case HOUR:
        return (width == 1 || width == 2);
    case MINUTE:
    case SECOND:
        return (width == 2);
    default:
        UPRV_UNREACHABLE;
    }
    return (width > 0);
}

GMTOffsetField::FieldType
GMTOffsetField::getTypeByLetter(UChar ch) {
    if (ch == 0x0048 /* H */) {
        return HOUR;
    } else if (ch == 0x006D /* m */) {
        return MINUTE;
    } else if (ch == 0x0073 /* s */) {
        return SECOND;
    }
    return TEXT;
}

inline GMTOffsetField::FieldType
GMTOffsetField::getType() const {
     return fType;
 }

inline uint8_t
GMTOffsetField::getWidth() const {
    return fWidth;
}
 
inline const UChar*
GMTOffsetField::getPatternText(void) const {
    return fText;
}


U_CDECL_BEGIN
static void U_CALLCONV
deleteGMTOffsetField(void *obj) {
    delete static_cast<GMTOffsetField *>(obj);
}
U_CDECL_END


// ------------------------------------------------------------------
// TimeZoneFormat
// ------------------------------------------------------------------
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeZoneFormat)

TimeZoneFormat::TimeZoneFormat(const Locale& locale, UErrorCode& status) 
: fLocale(locale), fTimeZoneNames(NULL), fTimeZoneGenericNames(NULL),
  fDefParseOptionFlags(0), fTZDBTimeZoneNames(NULL) {

    for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) {
        fGMTOffsetPatternItems[i] = NULL;
    }

    const char* region = fLocale.getCountry();
    int32_t regionLen = static_cast<int32_t>(uprv_strlen(region));
    if (regionLen == 0) {
        CharString loc;
        {
            CharStringByteSink sink(&loc);
            ulocimp_addLikelySubtags(fLocale.getName(), sink, &status);
        }

        regionLen = uloc_getCountry(loc.data(), fTargetRegion, sizeof(fTargetRegion), &status);
        if (U_SUCCESS(status)) {
            fTargetRegion[regionLen] = 0;
        } else {
            return;
        }
    } else if (regionLen < (int32_t)sizeof(fTargetRegion)) {
        uprv_strcpy(fTargetRegion, region);
    } else {
        fTargetRegion[0] = 0;
    }

    fTimeZoneNames = TimeZoneNames::createInstance(locale, status);
    // fTimeZoneGenericNames is lazily instantiated
    if (U_FAILURE(status)) {
        return;
    }

    const UChar* gmtPattern = NULL;
    const UChar* hourFormats = NULL;

    UResourceBundle *zoneBundle = ures_open(U_ICUDATA_ZONE, locale.getName(), &status);
    UResourceBundle *zoneStringsArray = ures_getByKeyWithFallback(zoneBundle, gZoneStringsTag, NULL, &status);
    if (U_SUCCESS(status)) {
        const UChar* resStr;
        int32_t len;
        resStr = ures_getStringByKeyWithFallback(zoneStringsArray, gGmtFormatTag, &len, &status);
        if (len > 0) {
            gmtPattern = resStr;
        }
        resStr = ures_getStringByKeyWithFallback(zoneStringsArray, gGmtZeroFormatTag, &len, &status);
        if (len > 0) {
            fGMTZeroFormat.setTo(TRUE, resStr, len);
        }
        resStr = ures_getStringByKeyWithFallback(zoneStringsArray, gHourFormatTag, &len, &status);
        if (len > 0) {
            hourFormats = resStr;
        }
        ures_close(zoneStringsArray);
        ures_close(zoneBundle);
    }

    if (gmtPattern == NULL) {
        gmtPattern = DEFAULT_GMT_PATTERN;
    }
    initGMTPattern(UnicodeString(TRUE, gmtPattern, -1), status);

    UBool useDefaultOffsetPatterns = TRUE;
    if (hourFormats) {
        UChar *sep = u_strchr(hourFormats, (UChar)0x003B /* ';' */);
        if (sep != NULL) {
            UErrorCode tmpStatus = U_ZERO_ERROR;
            fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_HM].setTo(FALSE, hourFormats, (int32_t)(sep - hourFormats));
            fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_HM].setTo(TRUE, sep + 1, -1);
            expandOffsetPattern(fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_HM], fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_HMS], tmpStatus);
            expandOffsetPattern(fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_HM], fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_HMS], tmpStatus);
            truncateOffsetPattern(fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_HM], fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_H], tmpStatus);
            truncateOffsetPattern(fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_HM], fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_H], tmpStatus);
            if (U_SUCCESS(tmpStatus)) {
                useDefaultOffsetPatterns = FALSE;
            }
        }
    }
    if (useDefaultOffsetPatterns) {
        fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_H].setTo(TRUE, DEFAULT_GMT_POSITIVE_H, -1);
        fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_HM].setTo(TRUE, DEFAULT_GMT_POSITIVE_HM, -1);
        fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_HMS].setTo(TRUE, DEFAULT_GMT_POSITIVE_HMS, -1);
        fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_H].setTo(TRUE, DEFAULT_GMT_NEGATIVE_H, -1);
        fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_HM].setTo(TRUE, DEFAULT_GMT_NEGATIVE_HM, -1);
        fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_HMS].setTo(TRUE, DEFAULT_GMT_NEGATIVE_HMS, -1);
    }
    initGMTOffsetPatterns(status);

    NumberingSystem* ns = NumberingSystem::createInstance(locale, status);
    UBool useDefDigits = TRUE;
    if (ns && !ns->isAlgorithmic()) {
        UnicodeString digits = ns->getDescription();
        useDefDigits = !toCodePoints(digits, fGMTOffsetDigits, 10);
    }
    if (useDefDigits) {
        uprv_memcpy(fGMTOffsetDigits, DEFAULT_GMT_DIGITS, sizeof(UChar32) * 10);
    }
    delete ns;
}

TimeZoneFormat::TimeZoneFormat(const TimeZoneFormat& other)
: Format(other), fTimeZoneNames(NULL), fTimeZoneGenericNames(NULL),
  fTZDBTimeZoneNames(NULL) {

    for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) {
        fGMTOffsetPatternItems[i] = NULL;
    }
    *this = other;
}


TimeZoneFormat::~TimeZoneFormat() {
    delete fTimeZoneNames;
    delete fTimeZoneGenericNames;
    delete fTZDBTimeZoneNames;
    for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) {
        delete fGMTOffsetPatternItems[i];
    }
}

TimeZoneFormat&
TimeZoneFormat::operator=(const TimeZoneFormat& other) {
    if (this == &other) {
        return *this;
    }

    delete fTimeZoneNames;
    delete fTimeZoneGenericNames;
    fTimeZoneGenericNames = NULL;
    delete fTZDBTimeZoneNames;
    fTZDBTimeZoneNames = NULL;

    fLocale = other.fLocale;
    uprv_memcpy(fTargetRegion, other.fTargetRegion, sizeof(fTargetRegion));

    fTimeZoneNames = other.fTimeZoneNames->clone();
    if (other.fTimeZoneGenericNames) {
        // TODO: this test has dubious thread safety.
        fTimeZoneGenericNames = other.fTimeZoneGenericNames->clone();
    }

    fGMTPattern = other.fGMTPattern;
    fGMTPatternPrefix = other.fGMTPatternPrefix;
    fGMTPatternSuffix = other.fGMTPatternSuffix;

    UErrorCode status = U_ZERO_ERROR;
    for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) {
        fGMTOffsetPatterns[i] = other.fGMTOffsetPatterns[i];
        delete fGMTOffsetPatternItems[i];
        fGMTOffsetPatternItems[i] = NULL;
    }
    initGMTOffsetPatterns(status);
    U_ASSERT(U_SUCCESS(status));

    fGMTZeroFormat = other.fGMTZeroFormat;

    uprv_memcpy(fGMTOffsetDigits, other.fGMTOffsetDigits, sizeof(fGMTOffsetDigits));

    fDefParseOptionFlags = other.fDefParseOptionFlags;

    return *this;
}


UBool
TimeZoneFormat::operator==(const Format& other) const {
    TimeZoneFormat* tzfmt = (TimeZoneFormat*)&other;

    UBool isEqual =
            fLocale == tzfmt->fLocale
            && fGMTPattern == tzfmt->fGMTPattern
            && fGMTZeroFormat == tzfmt->fGMTZeroFormat
            && *fTimeZoneNames == *tzfmt->fTimeZoneNames;

    for (int32_t i = 0; i < UTZFMT_PAT_COUNT && isEqual; i++) {
        isEqual = fGMTOffsetPatterns[i] == tzfmt->fGMTOffsetPatterns[i];
    }
    for (int32_t i = 0; i < 10 && isEqual; i++) {
        isEqual = fGMTOffsetDigits[i] == tzfmt->fGMTOffsetDigits[i];
    }
    // TODO
    // Check fTimeZoneGenericNames. For now,
    // if fTimeZoneNames is same, fTimeZoneGenericNames should
    // be also equivalent.
    return isEqual;
}

TimeZoneFormat*
TimeZoneFormat::clone() const {
    return new TimeZoneFormat(*this);
}

TimeZoneFormat* U_EXPORT2
TimeZoneFormat::createInstance(const Locale& locale, UErrorCode& status) {
    TimeZoneFormat* tzfmt = new TimeZoneFormat(locale, status);
    if (U_SUCCESS(status)) {
        return tzfmt;
    }
    delete tzfmt;
    return NULL;
}

// ------------------------------------------------------------------
// Setter and Getter

const TimeZoneNames*
TimeZoneFormat::getTimeZoneNames() const {
    return (const TimeZoneNames*)fTimeZoneNames;
}

void
TimeZoneFormat::adoptTimeZoneNames(TimeZoneNames *tznames) {
    delete fTimeZoneNames;
    fTimeZoneNames = tznames;

    // TODO - We should also update fTimeZoneGenericNames
}

void
TimeZoneFormat::setTimeZoneNames(const TimeZoneNames &tznames) {
    delete fTimeZoneNames;
    fTimeZoneNames = tznames.clone();

    // TODO - We should also update fTimeZoneGenericNames
}

void
TimeZoneFormat::setDefaultParseOptions(uint32_t flags) {
    fDefParseOptionFlags = flags;
}

uint32_t
TimeZoneFormat::getDefaultParseOptions(void) const {
    return fDefParseOptionFlags;
}


UnicodeString& 
TimeZoneFormat::getGMTPattern(UnicodeString& pattern) const {
    return pattern.setTo(fGMTPattern);
}

void
TimeZoneFormat::setGMTPattern(const UnicodeString& pattern, UErrorCode& status) {
    initGMTPattern(pattern, status);
}

UnicodeString&
TimeZoneFormat::getGMTOffsetPattern(UTimeZoneFormatGMTOffsetPatternType type, UnicodeString& pattern) const {
    return pattern.setTo(fGMTOffsetPatterns[type]);
}

void
TimeZoneFormat::setGMTOffsetPattern(UTimeZoneFormatGMTOffsetPatternType type, const UnicodeString& pattern, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return;
    }
    if (pattern == fGMTOffsetPatterns[type]) {
        // No need to reset
        return;
    }

    OffsetFields required = FIELDS_HM;
    switch (type) {
    case UTZFMT_PAT_POSITIVE_H:
    case UTZFMT_PAT_NEGATIVE_H:
        required = FIELDS_H;
        break;
    case UTZFMT_PAT_POSITIVE_HM:
    case UTZFMT_PAT_NEGATIVE_HM:
        required = FIELDS_HM;
        break;
    case UTZFMT_PAT_POSITIVE_HMS:
    case UTZFMT_PAT_NEGATIVE_HMS:
        required = FIELDS_HMS;
        break;
    default:
        UPRV_UNREACHABLE;
    }

    UVector* patternItems = parseOffsetPattern(pattern, required, status);
    if (patternItems == NULL) {
        return;
    }

    fGMTOffsetPatterns[type].setTo(pattern);
    delete fGMTOffsetPatternItems[type];
    fGMTOffsetPatternItems[type] = patternItems;
    checkAbuttingHoursAndMinutes();
}

UnicodeString&
TimeZoneFormat::getGMTOffsetDigits(UnicodeString& digits) const {
    digits.remove();
    for (int32_t i = 0; i < 10; i++) {
        digits.append(fGMTOffsetDigits[i]);
    }
    return digits;
}

void
TimeZoneFormat::setGMTOffsetDigits(const UnicodeString& digits, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return;
    }
    UChar32 digitArray[10];
    if (!toCodePoints(digits, digitArray, 10)) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    uprv_memcpy(fGMTOffsetDigits, digitArray, sizeof(UChar32)*10);
}

UnicodeString&
TimeZoneFormat::getGMTZeroFormat(UnicodeString& gmtZeroFormat) const {
    return gmtZeroFormat.setTo(fGMTZeroFormat);
}

void
TimeZoneFormat::setGMTZeroFormat(const UnicodeString& gmtZeroFormat, UErrorCode& status) {
    if (U_SUCCESS(status)) {
        if (gmtZeroFormat.isEmpty()) {
            status = U_ILLEGAL_ARGUMENT_ERROR;
        } else if (gmtZeroFormat != fGMTZeroFormat) {
            fGMTZeroFormat.setTo(gmtZeroFormat);
        }
    }
}

// ------------------------------------------------------------------
// Format and Parse

UnicodeString&
TimeZoneFormat::format(UTimeZoneFormatStyle style, const TimeZone& tz, UDate date,
        UnicodeString& name, UTimeZoneFormatTimeType* timeType /* = NULL */) const {
    if (timeType) {
        *timeType = UTZFMT_TIME_TYPE_UNKNOWN;
    }

    UBool noOffsetFormatFallback = FALSE;

    switch (style) {
    case UTZFMT_STYLE_GENERIC_LOCATION:
        formatGeneric(tz, UTZGNM_LOCATION, date, name);
        break;
    case UTZFMT_STYLE_GENERIC_LONG:
        formatGeneric(tz, UTZGNM_LONG, date, name);
        break;
    case UTZFMT_STYLE_GENERIC_SHORT:
        formatGeneric(tz, UTZGNM_SHORT, date, name);
        break;
    case UTZFMT_STYLE_SPECIFIC_LONG:
        formatSpecific(tz, UTZNM_LONG_STANDARD, UTZNM_LONG_DAYLIGHT, date, name, timeType);
        break;
    case UTZFMT_STYLE_SPECIFIC_SHORT:
        formatSpecific(tz, UTZNM_SHORT_STANDARD, UTZNM_SHORT_DAYLIGHT, date, name, timeType);
        break;

    case UTZFMT_STYLE_ZONE_ID:
        tz.getID(name);
        noOffsetFormatFallback = TRUE;
        break;
    case UTZFMT_STYLE_ZONE_ID_SHORT:
        {
            const UChar* shortID = ZoneMeta::getShortID(tz);
            if (shortID == NULL) {
                shortID = UNKNOWN_SHORT_ZONE_ID;
            }
            name.setTo(shortID, -1);
        }
        noOffsetFormatFallback = TRUE;
        break;

    case UTZFMT_STYLE_EXEMPLAR_LOCATION:
        formatExemplarLocation(tz, name);
        noOffsetFormatFallback = TRUE;
        break;

    default:
        // will be handled below
        break;
    }

    if (name.isEmpty() && !noOffsetFormatFallback) {
        UErrorCode status = U_ZERO_ERROR;
        int32_t rawOffset, dstOffset;
        tz.getOffset(date, FALSE, rawOffset, dstOffset, status);
        int32_t offset = rawOffset + dstOffset;
        if (U_SUCCESS(status)) {
            switch (style) {
            case UTZFMT_STYLE_GENERIC_LOCATION:
            case UTZFMT_STYLE_GENERIC_LONG:
            case UTZFMT_STYLE_SPECIFIC_LONG:
            case UTZFMT_STYLE_LOCALIZED_GMT:
                formatOffsetLocalizedGMT(offset, name, status);
                break;

            case UTZFMT_STYLE_GENERIC_SHORT:
            case UTZFMT_STYLE_SPECIFIC_SHORT:
            case UTZFMT_STYLE_LOCALIZED_GMT_SHORT:
                formatOffsetShortLocalizedGMT(offset, name, status);
                break;

            case UTZFMT_STYLE_ISO_BASIC_SHORT:
                formatOffsetISO8601Basic(offset, TRUE, TRUE, TRUE, name, status);
                break;

            case UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT:
                formatOffsetISO8601Basic(offset, FALSE, TRUE, TRUE, name, status);
                break;

            case UTZFMT_STYLE_ISO_BASIC_FIXED:
                formatOffsetISO8601Basic(offset, TRUE, FALSE, TRUE, name, status);
                break;

            case UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED:
                formatOffsetISO8601Basic(offset, FALSE, FALSE, TRUE, name, status);
                break;

            case UTZFMT_STYLE_ISO_EXTENDED_FIXED:
                formatOffsetISO8601Extended(offset, TRUE, FALSE, TRUE, name, status);
                break;

            case UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED:
                formatOffsetISO8601Extended(offset, FALSE, FALSE, TRUE, name, status);
                break;

            case UTZFMT_STYLE_ISO_BASIC_FULL:
                formatOffsetISO8601Basic(offset, TRUE, FALSE, FALSE, name, status);
                break;

            case UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL:
                formatOffsetISO8601Basic(offset, FALSE, FALSE, FALSE, name, status);
                break;

            case UTZFMT_STYLE_ISO_EXTENDED_FULL:
                formatOffsetISO8601Extended(offset, TRUE, FALSE, FALSE, name, status);
                break;

            case UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL:
                formatOffsetISO8601Extended(offset, FALSE, FALSE, FALSE, name, status);
                break;

            default:
              // UTZFMT_STYLE_ZONE_ID, UTZFMT_STYLE_ZONE_ID_SHORT, UTZFMT_STYLE_EXEMPLAR_LOCATION
              break;
            }

            if (timeType) {
                *timeType = (dstOffset != 0) ? UTZFMT_TIME_TYPE_DAYLIGHT : UTZFMT_TIME_TYPE_STANDARD;
            }
        }
    }

    return name;
}

UnicodeString&
TimeZoneFormat::format(const Formattable& obj, UnicodeString& appendTo,
        FieldPosition& pos, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return appendTo;
    }
    UDate date = Calendar::getNow();
    if (obj.getType() == Formattable::kObject) {
        const UObject* formatObj = obj.getObject();
        const TimeZone* tz = dynamic_cast<const TimeZone*>(formatObj);
        if (tz == NULL) {
            const Calendar* cal = dynamic_cast<const Calendar*>(formatObj);
            if (cal != NULL) {
                tz = &cal->getTimeZone();
                date = cal->getTime(status);
            }
        }
        if (tz != NULL) {
            int32_t rawOffset, dstOffset;
            tz->getOffset(date, FALSE, rawOffset, dstOffset, status);
            UChar buf[ZONE_NAME_U16_MAX];
            UnicodeString result(buf, 0, UPRV_LENGTHOF(buf));
            formatOffsetLocalizedGMT(rawOffset + dstOffset, result, status);
            if (U_SUCCESS(status)) {
                appendTo.append(result);
                if (pos.getField() == UDAT_TIMEZONE_FIELD) {
                    pos.setBeginIndex(0);
                    pos.setEndIndex(result.length());
                }
            }
        }
    }
    return appendTo;
}

TimeZone*
TimeZoneFormat::parse(UTimeZoneFormatStyle style, const UnicodeString& text, ParsePosition& pos,
        UTimeZoneFormatTimeType* timeType /*= NULL*/) const {
    return parse(style, text, pos, getDefaultParseOptions(), timeType);
}

TimeZone*
TimeZoneFormat::parse(UTimeZoneFormatStyle style, const UnicodeString& text, ParsePosition& pos,
        int32_t parseOptions, UTimeZoneFormatTimeType* timeType /* = NULL */) const {
    if (timeType) {
        *timeType = UTZFMT_TIME_TYPE_UNKNOWN;
    }

    int32_t startIdx = pos.getIndex();
    int32_t maxPos = text.length();
    int32_t offset;

    // Styles using localized GMT format as fallback
    UBool fallbackLocalizedGMT = 
        (style == UTZFMT_STYLE_SPECIFIC_LONG || style == UTZFMT_STYLE_GENERIC_LONG || style == UTZFMT_STYLE_GENERIC_LOCATION);
    UBool fallbackShortLocalizedGMT =
        (style == UTZFMT_STYLE_SPECIFIC_SHORT || style == UTZFMT_STYLE_GENERIC_SHORT);

    int32_t evaluated = 0;  // bit flags representing already evaluated styles
    ParsePosition tmpPos(startIdx);

    int32_t parsedOffset = UNKNOWN_OFFSET;  // stores successfully parsed offset for later use
    int32_t parsedPos = -1;                 // stores successfully parsed offset position for later use

    // Try localized GMT format first if necessary
    if (fallbackLocalizedGMT || fallbackShortLocalizedGMT) {
        UBool hasDigitOffset = FALSE;
        offset = parseOffsetLocalizedGMT(text, tmpPos, fallbackShortLocalizedGMT, &hasDigitOffset);
        if (tmpPos.getErrorIndex() == -1) {
            // Even when the input text was successfully parsed as a localized GMT format text,
            // we may still need to evaluate the specified style if -
            //   1) GMT zero format was used, and
            //   2) The input text was not completely processed
            if (tmpPos.getIndex() == maxPos || hasDigitOffset) {
                pos.setIndex(tmpPos.getIndex());
                return createTimeZoneForOffset(offset);
            }
            parsedOffset = offset;
            parsedPos = tmpPos.getIndex();
        }
        // Note: For now, no distinction between long/short localized GMT format in the parser.
        // This might be changed in future.
        // evaluated |= (fallbackLocalizedGMT ? STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT] : STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT_SHORT]);
        evaluated |= STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT] | STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT_SHORT];
    }

    UErrorCode status = U_ZERO_ERROR;
    UChar tzIDBuf[32];
    UnicodeString tzID(tzIDBuf, 0, UPRV_LENGTHOF(tzIDBuf));

    UBool parseTZDBAbbrev = ((parseOptions & UTZFMT_PARSE_OPTION_TZ_DATABASE_ABBREVIATIONS) != 0);

    // Try the specified style
    switch (style) {
    case UTZFMT_STYLE_LOCALIZED_GMT:
        {
            tmpPos.setIndex(startIdx);
            tmpPos.setErrorIndex(-1);

            offset = parseOffsetLocalizedGMT(text, tmpPos);
            if (tmpPos.getErrorIndex() == -1) {
                pos.setIndex(tmpPos.getIndex());
                return createTimeZoneForOffset(offset);
            }

            // Note: For now, no distinction between long/short localized GMT format in the parser.
            // This might be changed in future.
            evaluated |= STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT_SHORT];

            break;
        }
    case UTZFMT_STYLE_LOCALIZED_GMT_SHORT:
        {
            tmpPos.setIndex(startIdx);
            tmpPos.setErrorIndex(-1);

            offset = parseOffsetShortLocalizedGMT(text, tmpPos);
            if (tmpPos.getErrorIndex() == -1) {
                pos.setIndex(tmpPos.getIndex());
                return createTimeZoneForOffset(offset);
            }

            // Note: For now, no distinction between long/short localized GMT format in the parser.
            // This might be changed in future.
            evaluated |= STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT];

            break;
        }
    case UTZFMT_STYLE_ISO_BASIC_SHORT:
    case UTZFMT_STYLE_ISO_BASIC_FIXED:
    case UTZFMT_STYLE_ISO_BASIC_FULL:
    case UTZFMT_STYLE_ISO_EXTENDED_FIXED:
    case UTZFMT_STYLE_ISO_EXTENDED_FULL:
        {
            tmpPos.setIndex(startIdx);
            tmpPos.setErrorIndex(-1);

            offset = parseOffsetISO8601(text, tmpPos);
            if (tmpPos.getErrorIndex() == -1) {
                pos.setIndex(tmpPos.getIndex());
                return createTimeZoneForOffset(offset);
            }

            break;
        }

    case UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT:
    case UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED:
    case UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL:
    case UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED:
    case UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL:
        {
            tmpPos.setIndex(startIdx);
            tmpPos.setErrorIndex(-1);

            // Exclude the case of UTC Indicator "Z" here
            UBool hasDigitOffset = FALSE;
            offset = parseOffsetISO8601(text, tmpPos, FALSE, &hasDigitOffset);
            if (tmpPos.getErrorIndex() == -1 && hasDigitOffset) {
                pos.setIndex(tmpPos.getIndex());
                return createTimeZoneForOffset(offset);
            }

            break;
        }

    case UTZFMT_STYLE_SPECIFIC_LONG:
    case UTZFMT_STYLE_SPECIFIC_SHORT:
        {
            // Specific styles
            int32_t nameTypes = 0;
            if (style == UTZFMT_STYLE_SPECIFIC_LONG) {
                nameTypes = (UTZNM_LONG_STANDARD | UTZNM_LONG_DAYLIGHT);
            } else {
                U_ASSERT(style == UTZFMT_STYLE_SPECIFIC_SHORT);
                nameTypes = (UTZNM_SHORT_STANDARD | UTZNM_SHORT_DAYLIGHT);
            }
            LocalPointer<TimeZoneNames::MatchInfoCollection> specificMatches(fTimeZoneNames->find(text, startIdx, nameTypes, status));
            if (U_FAILURE(status)) {
                pos.setErrorIndex(startIdx);
                return NULL;
            }
            if (!specificMatches.isNull()) {
                int32_t matchIdx = -1;
                int32_t matchPos = -1;
                for (int32_t i = 0; i < specificMatches->size(); i++) {
                    matchPos  = startIdx + specificMatches->getMatchLengthAt(i);
                    if (matchPos > parsedPos) {
                        matchIdx = i;
                        parsedPos = matchPos;
                    }
                }
                if (matchIdx >= 0) {
                    if (timeType) {
                        *timeType = getTimeType(specificMatches->getNameTypeAt(matchIdx));
                    }
                    pos.setIndex(matchPos);
                    getTimeZoneID(specificMatches.getAlias(), matchIdx, tzID);
                    U_ASSERT(!tzID.isEmpty());
                    return TimeZone::createTimeZone(tzID);
                }
            }

            if (parseTZDBAbbrev && style == UTZFMT_STYLE_SPECIFIC_SHORT) {
                U_ASSERT((nameTypes & UTZNM_SHORT_STANDARD) != 0);
                U_ASSERT((nameTypes & UTZNM_SHORT_DAYLIGHT) != 0);

                const TZDBTimeZoneNames *tzdbTimeZoneNames = getTZDBTimeZoneNames(status);
                if (U_SUCCESS(status)) {
                    LocalPointer<TimeZoneNames::MatchInfoCollection> tzdbNameMatches(
                        tzdbTimeZoneNames->find(text, startIdx, nameTypes, status));
                    if (U_FAILURE(status)) {
                        pos.setErrorIndex(startIdx);
                        return NULL;
                    }
                    if (!tzdbNameMatches.isNull()) {
                        int32_t matchIdx = -1;
                        int32_t matchPos = -1;
                        for (int32_t i = 0; i < tzdbNameMatches->size(); i++) {
                            matchPos = startIdx + tzdbNameMatches->getMatchLengthAt(i);
                            if (matchPos > parsedPos) {
                                matchIdx = i;
                                parsedPos = matchPos;
                            }
                        }
                        if (matchIdx >= 0) {
                            if (timeType) {
                                *timeType = getTimeType(tzdbNameMatches->getNameTypeAt(matchIdx));
                            }
                            pos.setIndex(matchPos);
                            getTimeZoneID(tzdbNameMatches.getAlias(), matchIdx, tzID);
                            U_ASSERT(!tzID.isEmpty());
                            return TimeZone::createTimeZone(tzID);
                        }
                    }
                }
            }
            break;
        }
    case UTZFMT_STYLE_GENERIC_LONG:
    case UTZFMT_STYLE_GENERIC_SHORT:
    case UTZFMT_STYLE_GENERIC_LOCATION:
        {
            int32_t genericNameTypes = 0;
            switch (style) {
            case UTZFMT_STYLE_GENERIC_LOCATION:
                genericNameTypes = UTZGNM_LOCATION;
                break;

            case UTZFMT_STYLE_GENERIC_LONG:
                genericNameTypes = UTZGNM_LONG | UTZGNM_LOCATION;
                break;

            case UTZFMT_STYLE_GENERIC_SHORT:
                genericNameTypes = UTZGNM_SHORT | UTZGNM_LOCATION;
                break;

            default:
                UPRV_UNREACHABLE;
            }

            int32_t len = 0;
            UTimeZoneFormatTimeType tt = UTZFMT_TIME_TYPE_UNKNOWN;
            const TimeZoneGenericNames *gnames = getTimeZoneGenericNames(status);
            if (U_SUCCESS(status)) {
                len = gnames->findBestMatch(text, startIdx, genericNameTypes, tzID, tt, status);
            }
            if (U_FAILURE(status)) {
                pos.setErrorIndex(startIdx);
                return NULL;
            }
            if (len > 0) {
                // Found a match
                if (timeType) {
                    *timeType = tt;
                }
                pos.setIndex(startIdx + len);
                U_ASSERT(!tzID.isEmpty());
                return TimeZone::createTimeZone(tzID);
            }

            break;
        }
    case UTZFMT_STYLE_ZONE_ID:
        {
            tmpPos.setIndex(startIdx);
            tmpPos.setErrorIndex(-1);

            parseZoneID(text, tmpPos, tzID);
            if (tmpPos.getErrorIndex() == -1) {
                pos.setIndex(tmpPos.getIndex());
                return TimeZone::createTimeZone(tzID);
            }
            break;
        }
    case UTZFMT_STYLE_ZONE_ID_SHORT:
        {
            tmpPos.setIndex(startIdx);
            tmpPos.setErrorIndex(-1);

            parseShortZoneID(text, tmpPos, tzID);
            if (tmpPos.getErrorIndex() == -1) {
                pos.setIndex(tmpPos.getIndex());
                return TimeZone::createTimeZone(tzID);
            }
            break;
        }
    case UTZFMT_STYLE_EXEMPLAR_LOCATION:
        {
            tmpPos.setIndex(startIdx);
            tmpPos.setErrorIndex(-1);

            parseExemplarLocation(text, tmpPos, tzID);
            if (tmpPos.getErrorIndex() == -1) {
                pos.setIndex(tmpPos.getIndex());
                return TimeZone::createTimeZone(tzID);
            }
            break;
        }
    }
    evaluated |= STYLE_PARSE_FLAGS[style];


    if (parsedPos > startIdx) {
        // When the specified style is one of SPECIFIC_XXX or GENERIC_XXX, we tried to parse the input
        // as localized GMT format earlier. If parsedOffset is positive, it means it was successfully
        // parsed as localized GMT format, but offset digits were not detected (more specifically, GMT
        // zero format). Then, it tried to find a match within the set of display names, but could not
        // find a match. At this point, we can safely assume the input text contains the localized
        // GMT format.
        U_ASSERT(parsedOffset != UNKNOWN_OFFSET);
        pos.setIndex(parsedPos);
        return createTimeZoneForOffset(parsedOffset);
    }

    // Failed to parse the input text as the time zone format in the specified style.
    // Check the longest match among other styles below.
    UChar parsedIDBuf[32];
    UnicodeString parsedID(parsedIDBuf, 0, UPRV_LENGTHOF(parsedIDBuf));
    UTimeZoneFormatTimeType parsedTimeType = UTZFMT_TIME_TYPE_UNKNOWN;

    U_ASSERT(parsedPos < 0);
    U_ASSERT(parsedOffset == UNKNOWN_OFFSET);

    // ISO 8601
    if (parsedPos < maxPos &&
        ((evaluated & ISO_Z_STYLE_FLAG) == 0 || (evaluated & ISO_LOCAL_STYLE_FLAG) == 0)) {
        tmpPos.setIndex(startIdx);
        tmpPos.setErrorIndex(-1);

        UBool hasDigitOffset = FALSE;
        offset = parseOffsetISO8601(text, tmpPos, FALSE, &hasDigitOffset);
        if (tmpPos.getErrorIndex() == -1) {
            if (tmpPos.getIndex() == maxPos || hasDigitOffset) {
                pos.setIndex(tmpPos.getIndex());
                return createTimeZoneForOffset(offset);
            }
            // Note: When ISO 8601 format contains offset digits, it should not
            // collide with other formats. However, ISO 8601 UTC format "Z" (single letter)
            // may collide with other names. In this case, we need to evaluate other names.
            if (parsedPos < tmpPos.getIndex()) {
                parsedOffset = offset;
                parsedID.setToBogus();
                parsedTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
                parsedPos = tmpPos.getIndex();
                U_ASSERT(parsedPos == startIdx + 1);    // only when "Z" is used
            }
        }
    }

    // Localized GMT format
    if (parsedPos < maxPos &&
        (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT]) == 0) {
        tmpPos.setIndex(startIdx);
        tmpPos.setErrorIndex(-1);

        UBool hasDigitOffset = FALSE;
        offset = parseOffsetLocalizedGMT(text, tmpPos, FALSE, &hasDigitOffset);
        if (tmpPos.getErrorIndex() == -1) {
            if (tmpPos.getIndex() == maxPos || hasDigitOffset) {
                pos.setIndex(tmpPos.getIndex());
                return createTimeZoneForOffset(offset);
            }
            // Evaluate other names - see the comment earlier in this method.
            if (parsedPos < tmpPos.getIndex()) {
                parsedOffset = offset;
                parsedID.setToBogus();
                parsedTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
                parsedPos = tmpPos.getIndex();
            }
        }
    }

    if (parsedPos < maxPos &&
        (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT_SHORT]) == 0) {
        tmpPos.setIndex(startIdx);
        tmpPos.setErrorIndex(-1);

        UBool hasDigitOffset = FALSE;
        offset = parseOffsetLocalizedGMT(text, tmpPos, TRUE, &hasDigitOffset);
        if (tmpPos.getErrorIndex() == -1) {
            if (tmpPos.getIndex() == maxPos || hasDigitOffset) {
                pos.setIndex(tmpPos.getIndex());
                return createTimeZoneForOffset(offset);
            }
            // Evaluate other names - see the comment earlier in this method.
            if (parsedPos < tmpPos.getIndex()) {
                parsedOffset = offset;
                parsedID.setToBogus();
                parsedTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
                parsedPos = tmpPos.getIndex();
            }
        }
    }

    // When ParseOption.ALL_STYLES is available, we also try to look all possible display names and IDs.
    // For example, when style is GENERIC_LONG, "EST" (SPECIFIC_SHORT) is never
    // used for America/New_York. With parseAllStyles true, this code parses "EST"
    // as America/New_York.

    // Note: Adding all possible names into the trie used by the implementation is quite heavy operation,
    // which we want to avoid normally (note that we cache the trie, so this is applicable to the
    // first time only as long as the cache does not expire).

    if (parseOptions & UTZFMT_PARSE_OPTION_ALL_STYLES) {
        // Try all specific names and exemplar location names
        if (parsedPos < maxPos) {
            LocalPointer<TimeZoneNames::MatchInfoCollection> specificMatches(fTimeZoneNames->find(text, startIdx, ALL_SIMPLE_NAME_TYPES, status));
            if (U_FAILURE(status)) {
                pos.setErrorIndex(startIdx);
                return NULL;
            }
            int32_t specificMatchIdx = -1;
            int32_t matchPos = -1;
            if (!specificMatches.isNull()) {
                for (int32_t i = 0; i < specificMatches->size(); i++) {
                    if (startIdx + specificMatches->getMatchLengthAt(i) > matchPos) {
                        specificMatchIdx = i;
                        matchPos = startIdx + specificMatches->getMatchLengthAt(i);
                    }
                }
            }
            if (parsedPos < matchPos) {
                U_ASSERT(specificMatchIdx >= 0);
                parsedPos = matchPos;
                getTimeZoneID(specificMatches.getAlias(), specificMatchIdx, parsedID);
                parsedTimeType = getTimeType(specificMatches->getNameTypeAt(specificMatchIdx));
                parsedOffset = UNKNOWN_OFFSET;
            }
        }
        if (parseTZDBAbbrev && parsedPos < maxPos && (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_SPECIFIC_SHORT]) == 0) {
            const TZDBTimeZoneNames *tzdbTimeZoneNames = getTZDBTimeZoneNames(status);
            if (U_SUCCESS(status)) {
                LocalPointer<TimeZoneNames::MatchInfoCollection> tzdbNameMatches(
                    tzdbTimeZoneNames->find(text, startIdx, ALL_SIMPLE_NAME_TYPES, status));
                if (U_FAILURE(status)) {
                    pos.setErrorIndex(startIdx);
                    return NULL;
                }
                int32_t tzdbNameMatchIdx = -1;
                int32_t matchPos = -1;
                if (!tzdbNameMatches.isNull()) {
                    for (int32_t i = 0; i < tzdbNameMatches->size(); i++) {
                        if (startIdx + tzdbNameMatches->getMatchLengthAt(i) > matchPos) {
                            tzdbNameMatchIdx = i;
                            matchPos = startIdx + tzdbNameMatches->getMatchLengthAt(i);
                        }
                    }
                }
                if (parsedPos < matchPos) {
                    U_ASSERT(tzdbNameMatchIdx >= 0);
                    parsedPos = matchPos;
                    getTimeZoneID(tzdbNameMatches.getAlias(), tzdbNameMatchIdx, parsedID);
                    parsedTimeType = getTimeType(tzdbNameMatches->getNameTypeAt(tzdbNameMatchIdx));
                    parsedOffset = UNKNOWN_OFFSET;
                }
            }
        }
        // Try generic names
        if (parsedPos < maxPos) {
            int32_t genMatchLen = -1;
            UTimeZoneFormatTimeType tt = UTZFMT_TIME_TYPE_UNKNOWN;

            const TimeZoneGenericNames *gnames = getTimeZoneGenericNames(status);
            if (U_SUCCESS(status)) {
                genMatchLen = gnames->findBestMatch(text, startIdx, ALL_GENERIC_NAME_TYPES, tzID, tt, status);
            }
            if (U_FAILURE(status)) {
                pos.setErrorIndex(startIdx);
                return NULL;
            }

            if (genMatchLen > 0 && parsedPos < startIdx + genMatchLen) {
                parsedPos = startIdx + genMatchLen;
                parsedID.setTo(tzID);
                parsedTimeType = tt;
                parsedOffset = UNKNOWN_OFFSET;
            }
        }

        // Try time zone ID
        if (parsedPos < maxPos && (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_ZONE_ID]) == 0) {
            tmpPos.setIndex(startIdx);
            tmpPos.setErrorIndex(-1);

            parseZoneID(text, tmpPos, tzID);
            if (tmpPos.getErrorIndex() == -1 && parsedPos < tmpPos.getIndex()) {
                parsedPos = tmpPos.getIndex();
                parsedID.setTo(tzID);
                parsedTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
                parsedOffset = UNKNOWN_OFFSET;
            }
        }
        // Try short time zone ID
        if (parsedPos < maxPos && (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_ZONE_ID]) == 0) {
            tmpPos.setIndex(startIdx);
            tmpPos.setErrorIndex(-1);

            parseShortZoneID(text, tmpPos, tzID);
            if (tmpPos.getErrorIndex() == -1 && parsedPos < tmpPos.getIndex()) {
                parsedPos = tmpPos.getIndex();
                parsedID.setTo(tzID);
                parsedTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
                parsedOffset = UNKNOWN_OFFSET;
            }
        }
    }

    if (parsedPos > startIdx) {
        // Parsed successfully
        TimeZone* parsedTZ;
        if (parsedID.length() > 0) {
            parsedTZ = TimeZone::createTimeZone(parsedID);
        } else {
            U_ASSERT(parsedOffset != UNKNOWN_OFFSET);
            parsedTZ = createTimeZoneForOffset(parsedOffset);
        }
        if (timeType) {
            *timeType = parsedTimeType;
        }
        pos.setIndex(parsedPos);
        return parsedTZ;
    }

    pos.setErrorIndex(startIdx);
    return NULL;
}

void
TimeZoneFormat::parseObject(const UnicodeString& source, Formattable& result,
        ParsePosition& parse_pos) const {
    result.adoptObject(parse(UTZFMT_STYLE_GENERIC_LOCATION, source, parse_pos, UTZFMT_PARSE_OPTION_ALL_STYLES));
}


// ------------------------------------------------------------------
// Private zone name format/parse implementation

UnicodeString&
TimeZoneFormat::formatGeneric(const TimeZone& tz, int32_t genType, UDate date, UnicodeString& name) const {
    UErrorCode status = U_ZERO_ERROR;
    const TimeZoneGenericNames* gnames = getTimeZoneGenericNames(status);
    if (U_FAILURE(status)) {
        name.setToBogus();
        return name;
    }

    if (genType == UTZGNM_LOCATION) {
        const UChar* canonicalID = ZoneMeta::getCanonicalCLDRID(tz);
        if (canonicalID == NULL) {
            name.setToBogus();
            return name;
        }
        return gnames->getGenericLocationName(UnicodeString(TRUE, canonicalID, -1), name);
    }
    return gnames->getDisplayName(tz, (UTimeZoneGenericNameType)genType, date, name);
}

UnicodeString&
TimeZoneFormat::formatSpecific(const TimeZone& tz, UTimeZoneNameType stdType, UTimeZoneNameType dstType,
        UDate date, UnicodeString& name, UTimeZoneFormatTimeType *timeType) const {
    if (fTimeZoneNames == NULL) {
        name.setToBogus();
        return name;
    }

    UErrorCode status = U_ZERO_ERROR;
    UBool isDaylight = tz.inDaylightTime(date, status);
    const UChar* canonicalID = ZoneMeta::getCanonicalCLDRID(tz);

    if (U_FAILURE(status) || canonicalID == NULL) {
        name.setToBogus();
        return name;
    }

    if (isDaylight) {
        fTimeZoneNames->getDisplayName(UnicodeString(TRUE, canonicalID, -1), dstType, date, name);
    } else {
        fTimeZoneNames->getDisplayName(UnicodeString(TRUE, canonicalID, -1), stdType, date, name);
    }

    if (timeType && !name.isEmpty()) {
        *timeType = isDaylight ? UTZFMT_TIME_TYPE_DAYLIGHT : UTZFMT_TIME_TYPE_STANDARD;
    }
    return name;
}

const TimeZoneGenericNames*
TimeZoneFormat::getTimeZoneGenericNames(UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return NULL;
    }

    umtx_lock(&gLock);
    if (fTimeZoneGenericNames == NULL) {
        TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this);
        nonConstThis->fTimeZoneGenericNames = TimeZoneGenericNames::createInstance(fLocale, status);
    }
    umtx_unlock(&gLock);

    return fTimeZoneGenericNames;
}

const TZDBTimeZoneNames*
TimeZoneFormat::getTZDBTimeZoneNames(UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return NULL;
    }

    umtx_lock(&gLock);
    if (fTZDBTimeZoneNames == NULL) {
        TZDBTimeZoneNames *tzdbNames = new TZDBTimeZoneNames(fLocale);
        if (tzdbNames == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
        } else {
            TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this);
            nonConstThis->fTZDBTimeZoneNames = tzdbNames;
        }
    }
    umtx_unlock(&gLock);

    return fTZDBTimeZoneNames;
}

UnicodeString&
TimeZoneFormat::formatExemplarLocation(const TimeZone& tz, UnicodeString& name) const {
    UChar locationBuf[ZONE_NAME_U16_MAX];
    UnicodeString location(locationBuf, 0, UPRV_LENGTHOF(locationBuf));
    const UChar* canonicalID = ZoneMeta::getCanonicalCLDRID(tz);

    if (canonicalID) {
        fTimeZoneNames->getExemplarLocationName(UnicodeString(TRUE, canonicalID, -1), location);
    }
    if (location.length() > 0) {
        name.setTo(location);
    } else {
        // Use "unknown" location
        fTimeZoneNames->getExemplarLocationName(UnicodeString(TRUE, UNKNOWN_ZONE_ID, -1), location);
        if (location.length() > 0) {
            name.setTo(location);
        } else {
            // last resort
            name.setTo(UNKNOWN_LOCATION, -1);
        }
    }
    return name;
}


// ------------------------------------------------------------------
// Zone offset format and parse

UnicodeString&
TimeZoneFormat::formatOffsetISO8601Basic(int32_t offset, UBool useUtcIndicator, UBool isShort, UBool ignoreSeconds,
        UnicodeString& result, UErrorCode& status) const {
    return formatOffsetISO8601(offset, TRUE, useUtcIndicator, isShort, ignoreSeconds, result, status);
}

UnicodeString&
TimeZoneFormat::formatOffsetISO8601Extended(int32_t offset, UBool useUtcIndicator, UBool isShort, UBool ignoreSeconds,
        UnicodeString& result, UErrorCode& status) const {
    return formatOffsetISO8601(offset, FALSE, useUtcIndicator, isShort, ignoreSeconds, result, status);
}

UnicodeString&
TimeZoneFormat::formatOffsetLocalizedGMT(int32_t offset, UnicodeString& result, UErrorCode& status) const {
    return formatOffsetLocalizedGMT(offset, FALSE, result, status);
}

UnicodeString&
TimeZoneFormat::formatOffsetShortLocalizedGMT(int32_t offset, UnicodeString& result, UErrorCode& status) const {
    return formatOffsetLocalizedGMT(offset, TRUE, result, status);
}

int32_t
TimeZoneFormat::parseOffsetISO8601(const UnicodeString& text, ParsePosition& pos) const {
    return parseOffsetISO8601(text, pos, FALSE);
}

int32_t
TimeZoneFormat::parseOffsetLocalizedGMT(const UnicodeString& text, ParsePosition& pos) const {
    return parseOffsetLocalizedGMT(text, pos, FALSE, NULL);
}

int32_t
TimeZoneFormat::parseOffsetShortLocalizedGMT(const UnicodeString& text, ParsePosition& pos) const {
    return parseOffsetLocalizedGMT(text, pos, TRUE, NULL);
}

// ------------------------------------------------------------------
// Private zone offset format/parse implementation

UnicodeString&
TimeZoneFormat::formatOffsetISO8601(int32_t offset, UBool isBasic, UBool useUtcIndicator,
        UBool isShort, UBool ignoreSeconds, UnicodeString& result, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        result.setToBogus();
        return result;
    }
    int32_t absOffset = offset < 0 ? -offset : offset;
    if (useUtcIndicator && (absOffset < MILLIS_PER_SECOND || (ignoreSeconds && absOffset < MILLIS_PER_MINUTE))) {
        result.setTo(ISO8601_UTC);
        return result;
    }

    OffsetFields minFields = isShort ? FIELDS_H : FIELDS_HM;
    OffsetFields maxFields = ignoreSeconds ? FIELDS_HM : FIELDS_HMS;
    UChar sep = isBasic ? 0 : ISO8601_SEP;

    // Note: FIELDS_HMS as maxFields is a CLDR/ICU extension. ISO 8601 specification does
    // not support seconds field.

    if (absOffset >= MAX_OFFSET) {
        result.setToBogus();
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return result;
    }

    int fields[3];
    fields[0] = absOffset / MILLIS_PER_HOUR;
    absOffset = absOffset % MILLIS_PER_HOUR;
    fields[1] = absOffset / MILLIS_PER_MINUTE;
    absOffset = absOffset % MILLIS_PER_MINUTE;
    fields[2] = absOffset / MILLIS_PER_SECOND;

    U_ASSERT(fields[0] >= 0 && fields[0] <= MAX_OFFSET_HOUR);
    U_ASSERT(fields[1] >= 0 && fields[1] <= MAX_OFFSET_MINUTE);
    U_ASSERT(fields[2] >= 0 && fields[2] <= MAX_OFFSET_SECOND);

    int32_t lastIdx = maxFields;
    while (lastIdx > minFields) {
        if (fields[lastIdx] != 0) {
            break;
        }
        lastIdx--;
    }

    UChar sign = PLUS;
    if (offset < 0) {
        // if all output fields are 0s, do not use negative sign
        for (int32_t idx = 0; idx <= lastIdx; idx++) {
            if (fields[idx] != 0) {
                sign = MINUS;
                break;
            }
        }
    }
    result.setTo(sign);

    for (int32_t idx = 0; idx <= lastIdx; idx++) {
        if (sep && idx != 0) {
            result.append(sep);
        }
        result.append((UChar)(0x0030 + fields[idx]/10));
        result.append((UChar)(0x0030 + fields[idx]%10));
    }

    return result;
}

UnicodeString&
TimeZoneFormat::formatOffsetLocalizedGMT(int32_t offset, UBool isShort, UnicodeString& result, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        result.setToBogus();
        return result;
    }
    if (offset <= -MAX_OFFSET || offset >= MAX_OFFSET) {
        result.setToBogus();
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return result;
    }

    if (offset == 0) {
        result.setTo(fGMTZeroFormat);
        return result;
    }

    UBool positive = TRUE;
    if (offset < 0) {
        offset = -offset;
        positive = FALSE;
    }

    int32_t offsetH = offset / MILLIS_PER_HOUR;
    offset = offset % MILLIS_PER_HOUR;
    int32_t offsetM = offset / MILLIS_PER_MINUTE;
    offset = offset % MILLIS_PER_MINUTE;
    int32_t offsetS = offset / MILLIS_PER_SECOND;

    U_ASSERT(offsetH <= MAX_OFFSET_HOUR && offsetM <= MAX_OFFSET_MINUTE && offsetS <= MAX_OFFSET_SECOND);

    const UVector* offsetPatternItems = NULL;
    if (positive) {
        if (offsetS != 0) {
            offsetPatternItems = fGMTOffsetPatternItems[UTZFMT_PAT_POSITIVE_HMS];
        } else if (offsetM != 0 || !isShort) {
            offsetPatternItems = fGMTOffsetPatternItems[UTZFMT_PAT_POSITIVE_HM];
        } else {
            offsetPatternItems = fGMTOffsetPatternItems[UTZFMT_PAT_POSITIVE_H];
        }
    } else {
        if (offsetS != 0) {
            offsetPatternItems = fGMTOffsetPatternItems[UTZFMT_PAT_NEGATIVE_HMS];
        } else if (offsetM != 0 || !isShort) {
            offsetPatternItems = fGMTOffsetPatternItems[UTZFMT_PAT_NEGATIVE_HM];
        } else {
            offsetPatternItems = fGMTOffsetPatternItems[UTZFMT_PAT_NEGATIVE_H];
        }
    }

    U_ASSERT(offsetPatternItems != NULL);

    // Building the GMT format string
    result.setTo(fGMTPatternPrefix);

    for (int32_t i = 0; i < offsetPatternItems->size(); i++) {
        const GMTOffsetField* item = (GMTOffsetField*)offsetPatternItems->elementAt(i);
        GMTOffsetField::FieldType type = item->getType();

        switch (type) {
        case GMTOffsetField::TEXT:
            result.append(item->getPatternText(), -1);
            break;

        case GMTOffsetField::HOUR:
            appendOffsetDigits(result, offsetH, (isShort ? 1 : 2));
            break;

        case GMTOffsetField::MINUTE:
            appendOffsetDigits(result, offsetM, 2);
            break;

        case GMTOffsetField::SECOND:
            appendOffsetDigits(result, offsetS, 2);
            break;
        }
    }

    result.append(fGMTPatternSuffix);
    return result;
}

int32_t
TimeZoneFormat::parseOffsetISO8601(const UnicodeString& text, ParsePosition& pos, UBool extendedOnly, UBool* hasDigitOffset /* = NULL */) const {
    if (hasDigitOffset) {
        *hasDigitOffset = FALSE;
    }
    int32_t start = pos.getIndex();
    if (start >= text.length()) {
        pos.setErrorIndex(start);
        return 0;
    }

    UChar firstChar = text.charAt(start);
    if (firstChar == ISO8601_UTC || firstChar == (UChar)(ISO8601_UTC + 0x20)) {
        // "Z" (or "z") - indicates UTC
        pos.setIndex(start + 1);
        return 0;
    }

    int32_t sign = 1;
    if (firstChar == PLUS) {
        sign = 1;
    } else if (firstChar == MINUS) {
        sign = -1;
    } else {
        // Not an ISO 8601 offset string
        pos.setErrorIndex(start);
        return 0;
    }
    ParsePosition posOffset(start + 1);
    int32_t offset = parseAsciiOffsetFields(text, posOffset, ISO8601_SEP, FIELDS_H, FIELDS_HMS);
    if (posOffset.getErrorIndex() == -1 && !extendedOnly && (posOffset.getIndex() - start <= 3)) {
        // If the text is successfully parsed as extended format with the options above, it can be also parsed
        // as basic format. For example, "0230" can be parsed as offset 2:00 (only first digits are valid for
        // extended format), but it can be parsed as offset 2:30 with basic format. We use longer result.
        ParsePosition posBasic(start + 1);
        int32_t tmpOffset = parseAbuttingAsciiOffsetFields(text, posBasic, FIELDS_H, FIELDS_HMS, FALSE);
        if (posBasic.getErrorIndex() == -1 && posBasic.getIndex() > posOffset.getIndex()) {
            offset = tmpOffset;
            posOffset.setIndex(posBasic.getIndex());
        }
    }

    if (posOffset.getErrorIndex() != -1) {
        pos.setErrorIndex(start);
        return 0;
    }

    pos.setIndex(posOffset.getIndex());
    if (hasDigitOffset) {
        *hasDigitOffset = TRUE;
    }
    return sign * offset;
}

int32_t
TimeZoneFormat::parseOffsetLocalizedGMT(const UnicodeString& text, ParsePosition& pos, UBool isShort, UBool* hasDigitOffset) const {
    int32_t start = pos.getIndex();
    int32_t offset = 0;
    int32_t parsedLength = 0;

    if (hasDigitOffset) {
        *hasDigitOffset = FALSE;
    }

    offset = parseOffsetLocalizedGMTPattern(text, start, isShort, parsedLength);

    // For now, parseOffsetLocalizedGMTPattern handles both long and short
    // formats, no matter isShort is true or false. This might be changed in future
    // when strict parsing is necessary, or different set of patterns are used for
    // short/long formats.
#if 0
    if (parsedLength == 0) {
        offset = parseOffsetLocalizedGMTPattern(text, start, !isShort, parsedLength);
    }
#endif

    if (parsedLength > 0) {
        if (hasDigitOffset) {
            *hasDigitOffset = TRUE;
        }
        pos.setIndex(start + parsedLength);
        return offset;
    }

    // Try the default patterns
    offset = parseOffsetDefaultLocalizedGMT(text, start, parsedLength);
    if (parsedLength > 0) {
        if (hasDigitOffset) {
            *hasDigitOffset = TRUE;
        }
        pos.setIndex(start + parsedLength);
        return offset;
    }

    // Check if this is a GMT zero format
    if (text.caseCompare(start, fGMTZeroFormat.length(), fGMTZeroFormat, 0) == 0) {
        pos.setIndex(start + fGMTZeroFormat.length());
        return 0;
    }

    // Check if this is a default GMT zero format
    for (int32_t i = 0; ALT_GMT_STRINGS[i][0] != 0; i++) {
        const UChar* defGMTZero = ALT_GMT_STRINGS[i];
        int32_t defGMTZeroLen = u_strlen(defGMTZero);
        if (text.caseCompare(start, defGMTZeroLen, defGMTZero, 0) == 0) {
            pos.setIndex(start + defGMTZeroLen);
            return 0;
        }
    }

    // Nothing matched
    pos.setErrorIndex(start);
    return 0;
}

int32_t
TimeZoneFormat::parseOffsetLocalizedGMTPattern(const UnicodeString& text, int32_t start, UBool /*isShort*/, int32_t& parsedLen) const {
    int32_t idx = start;
    int32_t offset = 0;
    UBool parsed = FALSE;

    do {
        // Prefix part
        int32_t len = fGMTPatternPrefix.length();
        if (len > 0 && text.caseCompare(idx, len, fGMTPatternPrefix, 0) != 0) {
            // prefix match failed
            break;
        }
        idx += len;

        // Offset part
        offset = parseOffsetFields(text, idx, FALSE, len);
        if (len == 0) {
            // offset field match failed
            break;
        }
        idx += len;

        len = fGMTPatternSuffix.length();
        if (len > 0 && text.caseCompare(idx, len, fGMTPatternSuffix, 0) != 0) {
            // no suffix match
            break;
        }
        idx += len;
        parsed = TRUE;
    } while (FALSE);

    parsedLen = parsed ? idx - start : 0;
    return offset;
}

int32_t
TimeZoneFormat::parseOffsetFields(const UnicodeString& text, int32_t start, UBool /*isShort*/, int32_t& parsedLen) const {
    int32_t outLen = 0;
    int32_t offset = 0;
    int32_t sign = 1;

    parsedLen = 0;

    int32_t offsetH, offsetM, offsetS;
    offsetH = offsetM = offsetS = 0;

    for (int32_t patidx = 0; PARSE_GMT_OFFSET_TYPES[patidx] >= 0; patidx++) {
        int32_t gmtPatType = PARSE_GMT_OFFSET_TYPES[patidx];
        UVector* items = fGMTOffsetPatternItems[gmtPatType];
        U_ASSERT(items != NULL);

        outLen = parseOffsetFieldsWithPattern(text, start, items, FALSE, offsetH, offsetM, offsetS);
        if (outLen > 0) {
            sign = (gmtPatType == UTZFMT_PAT_POSITIVE_H || gmtPatType == UTZFMT_PAT_POSITIVE_HM || gmtPatType == UTZFMT_PAT_POSITIVE_HMS) ?
                1 : -1;
            break;
        }
    }

    if (outLen > 0 && fAbuttingOffsetHoursAndMinutes) {
        // When hours field is sabutting minutes field,
        // the parse result above may not be appropriate.
        // For example, "01020" is parsed as 01:02: above,
        // but it should be parsed as 00:10:20.
        int32_t tmpLen = 0;
        int32_t tmpSign = 1;
        int32_t tmpH = 0;
        int32_t tmpM = 0;
        int32_t tmpS = 0;

        for (int32_t patidx = 0; PARSE_GMT_OFFSET_TYPES[patidx] >= 0; patidx++) {
            int32_t gmtPatType = PARSE_GMT_OFFSET_TYPES[patidx];
            UVector* items = fGMTOffsetPatternItems[gmtPatType];
            U_ASSERT(items != NULL);

            // forcing parse to use single hour digit
            tmpLen = parseOffsetFieldsWithPattern(text, start, items, TRUE, tmpH, tmpM, tmpS);
            if (tmpLen > 0) {
                tmpSign = (gmtPatType == UTZFMT_PAT_POSITIVE_H || gmtPatType == UTZFMT_PAT_POSITIVE_HM || gmtPatType == UTZFMT_PAT_POSITIVE_HMS) ?
                    1 : -1;
                break;
            }
        }
        if (tmpLen > outLen) {
            // Better parse result with single hour digit
            outLen = tmpLen;
            sign = tmpSign;
            offsetH = tmpH;
            offsetM = tmpM;
            offsetS = tmpS;
        }
    }

    if (outLen > 0) {
        offset = ((((offsetH * 60) + offsetM) * 60) + offsetS) * 1000 * sign;
        parsedLen = outLen;
    }

    return offset;
}

int32_t
TimeZoneFormat::parseOffsetFieldsWithPattern(const UnicodeString& text, int32_t start,
        UVector* patternItems, UBool forceSingleHourDigit, int32_t& hour, int32_t& min, int32_t& sec) const {
    UBool failed = FALSE;
    int32_t offsetH, offsetM, offsetS;
    offsetH = offsetM = offsetS = 0;
    int32_t idx = start;

    for (int32_t i = 0; i < patternItems->size(); i++) {
        int32_t len = 0;
        const GMTOffsetField* field = (const GMTOffsetField*)patternItems->elementAt(i);
        GMTOffsetField::FieldType fieldType = field->getType();
        if (fieldType == GMTOffsetField::TEXT) {
            const UChar* patStr = field->getPatternText();
            len = u_strlen(patStr);
            if (i == 0) {
                // When TimeZoneFormat parse() is called from SimpleDateFormat,
                // leading space characters might be truncated. If the first pattern text
                // starts with such character (e.g. Bidi control), then we need to
                // skip the leading space charcters.
                if (idx < text.length() && !PatternProps::isWhiteSpace(text.char32At(idx))) {
                    while (len > 0) {
                        UChar32 ch;
                        int32_t chLen;
                        U16_GET(patStr, 0, 0, len, ch);
                        if (PatternProps::isWhiteSpace(ch)) {
                            chLen = U16_LENGTH(ch);
                            len -= chLen;
                            patStr += chLen;
                        }
                        else {
                            break;
                        }
                    }
                }
            }
            if (text.caseCompare(idx, len, patStr, 0) != 0) {
                failed = TRUE;
                break;
            }
            idx += len;
        } else {
            if (fieldType == GMTOffsetField::HOUR) {
                uint8_t maxDigits = forceSingleHourDigit ? 1 : 2;
                offsetH = parseOffsetFieldWithLocalizedDigits(text, idx, 1, maxDigits, 0, MAX_OFFSET_HOUR, len);
            } else if (fieldType == GMTOffsetField::MINUTE) {
                offsetM = parseOffsetFieldWithLocalizedDigits(text, idx, 2, 2, 0, MAX_OFFSET_MINUTE, len);
            } else if (fieldType == GMTOffsetField::SECOND) {
                offsetS = parseOffsetFieldWithLocalizedDigits(text, idx, 2, 2, 0, MAX_OFFSET_SECOND, len);
            }

            if (len == 0) {
                failed = TRUE;
                break;
            }
            idx += len;
        }
    }

    if (failed) {
        hour = min = sec = 0;
        return 0;
    }

    hour = offsetH;
    min = offsetM;
    sec = offsetS;

    return idx - start;
}

int32_t
TimeZoneFormat::parseAbuttingOffsetFields(const UnicodeString& text, int32_t start, int32_t& parsedLen) const {
    int32_t digits[MAX_OFFSET_DIGITS];
    int32_t parsed[MAX_OFFSET_DIGITS];  // accumulative offsets

    // Parse digits into int[]
    int32_t idx = start;
    int32_t len = 0;
    int32_t numDigits = 0;
    for (int32_t i = 0; i < MAX_OFFSET_DIGITS; i++) {
        digits[i] = parseSingleLocalizedDigit(text, idx, len);
        if (digits[i] < 0) {
            break;
        }
        idx += len;
        parsed[i] = idx - start;
        numDigits++;
    }

    if (numDigits == 0) {
        parsedLen = 0;
        return 0;
    }

    int32_t offset = 0;
    while (numDigits > 0) {
        int32_t hour = 0;
        int32_t min = 0;
        int32_t sec = 0;

        U_ASSERT(numDigits > 0 && numDigits <= MAX_OFFSET_DIGITS);
        switch (numDigits) {
        case 1: // H
            hour = digits[0];
            break;
        case 2: // HH
            hour = digits[0] * 10 + digits[1];
            break;
        case 3: // Hmm
            hour = digits[0];
            min = digits[1] * 10 + digits[2];
            break;
        case 4: // HHmm
            hour = digits[0] * 10 + digits[1];
            min = digits[2] * 10 + digits[3];
            break;
        case 5: // Hmmss
            hour = digits[0];
            min = digits[1] * 10 + digits[2];
            sec = digits[3] * 10 + digits[4];
            break;
        case 6: // HHmmss
            hour = digits[0] * 10 + digits[1];
            min = digits[2] * 10 + digits[3];
            sec = digits[4] * 10 + digits[5];
            break;
        }
        if (hour <= MAX_OFFSET_HOUR && min <= MAX_OFFSET_MINUTE && sec <= MAX_OFFSET_SECOND) {
            // found a valid combination
            offset = hour * MILLIS_PER_HOUR + min * MILLIS_PER_MINUTE + sec * MILLIS_PER_SECOND;
            parsedLen = parsed[numDigits - 1];
            break;
        }
        numDigits--;
    }
    return offset;
}

int32_t
TimeZoneFormat::parseOffsetDefaultLocalizedGMT(const UnicodeString& text, int start, int32_t& parsedLen) const {
    int32_t idx = start;
    int32_t offset = 0;
    int32_t parsed = 0;

    do {
        // check global default GMT alternatives
        int32_t gmtLen = 0;

        for (int32_t i = 0; ALT_GMT_STRINGS[i][0] != 0; i++) {
            const UChar* gmt = ALT_GMT_STRINGS[i];
            int32_t len = u_strlen(gmt);
            if (text.caseCompare(start, len, gmt, 0) == 0) {
                gmtLen = len;
                break;
            }
        }
        if (gmtLen == 0) {
            break;
        }
        idx += gmtLen;

        // offset needs a sign char and a digit at minimum
        if (idx + 1 >= text.length()) {
            break;
        }

        // parse sign
        int32_t sign = 1;
        UChar c = text.charAt(idx);
        if (c == PLUS) {
            sign = 1;
        } else if (c == MINUS) {
            sign = -1;
        } else {
            break;
        }
        idx++;

        // offset part
        // try the default pattern with the separator first
        int32_t lenWithSep = 0;
        int32_t offsetWithSep = parseDefaultOffsetFields(text, idx, DEFAULT_GMT_OFFSET_SEP, lenWithSep);
        if (lenWithSep == text.length() - idx) {
            // maximum match
            offset = offsetWithSep * sign;
            idx += lenWithSep;
        } else {
            // try abutting field pattern
            int32_t lenAbut = 0;
            int32_t offsetAbut = parseAbuttingOffsetFields(text, idx, lenAbut);

            if (lenWithSep > lenAbut) {
                offset = offsetWithSep * sign;
                idx += lenWithSep;
            } else {
                offset = offsetAbut * sign;
                idx += lenAbut;
            }
        }
        parsed = idx - start;
    } while (false);

    parsedLen = parsed;
    return offset;
}

int32_t
TimeZoneFormat::parseDefaultOffsetFields(const UnicodeString& text, int32_t start, UChar separator, int32_t& parsedLen) const {
    int32_t max = text.length();
    int32_t idx = start;
    int32_t len = 0;
    int32_t hour = 0, min = 0, sec = 0;

    parsedLen = 0;

    do {
        hour = parseOffsetFieldWithLocalizedDigits(text, idx, 1, 2, 0, MAX_OFFSET_HOUR, len);
        if (len == 0) {
            break;
        }
        idx += len;

        if (idx + 1 < max && text.charAt(idx) == separator) {
            min = parseOffsetFieldWithLocalizedDigits(text, idx + 1, 2, 2, 0, MAX_OFFSET_MINUTE, len);
            if (len == 0) {
                break;
            }
            idx += (1 + len);

            if (idx + 1 < max && text.charAt(idx) == separator) {
                sec = parseOffsetFieldWithLocalizedDigits(text, idx + 1, 2, 2, 0, MAX_OFFSET_SECOND, len);
                if (len == 0) {
                    break;
                }
                idx += (1 + len);
            }
        }
    } while (FALSE);

    if (idx == start) {
        return 0;
    }

    parsedLen = idx - start;
    return hour * MILLIS_PER_HOUR + min * MILLIS_PER_MINUTE + sec * MILLIS_PER_SECOND;
}

int32_t
TimeZoneFormat::parseOffsetFieldWithLocalizedDigits(const UnicodeString& text, int32_t start, uint8_t minDigits, uint8_t maxDigits, uint16_t minVal, uint16_t maxVal, int32_t& parsedLen) const {
    parsedLen = 0;

    int32_t decVal = 0;
    int32_t numDigits = 0;
    int32_t idx = start;
    int32_t digitLen = 0;

    while (idx < text.length() && numDigits < maxDigits) {
        int32_t digit = parseSingleLocalizedDigit(text, idx, digitLen);
        if (digit < 0) {
            break;
        }
        int32_t tmpVal = decVal * 10 + digit;
        if (tmpVal > maxVal) {
            break;
        }
        decVal = tmpVal;
        numDigits++;
        idx += digitLen;
    }

    // Note: maxVal is checked in the while loop
    if (numDigits < minDigits || decVal < minVal) {
        decVal = -1;
        numDigits = 0;
    } else {
        parsedLen = idx - start;
    }

    return decVal;
}

int32_t
TimeZoneFormat::parseSingleLocalizedDigit(const UnicodeString& text, int32_t start, int32_t& len) const {
    int32_t digit = -1;
    len = 0;
    if (start < text.length()) {
        UChar32 cp = text.char32At(start);

        // First, try digits configured for this instance
        for (int32_t i = 0; i < 10; i++) {
            if (cp == fGMTOffsetDigits[i]) {
                digit = i;
                break;
            }
        }
        // If failed, check if this is a Unicode digit
        if (digit < 0) {
            int32_t tmp = u_charDigitValue(cp);
            digit = (tmp >= 0 && tmp <= 9) ? tmp : -1;
        }

        if (digit >= 0) {
            int32_t next = text.moveIndex32(start, 1);
            len = next - start;
        }
    }
    return digit;
}

UnicodeString&
TimeZoneFormat::formatOffsetWithAsciiDigits(int32_t offset, UChar sep, OffsetFields minFields, OffsetFields maxFields, UnicodeString& result) {
    U_ASSERT(maxFields >= minFields);
    U_ASSERT(offset > -MAX_OFFSET && offset < MAX_OFFSET);

    UChar sign = PLUS;
    if (offset < 0) {
        sign = MINUS;
        offset = -offset;
    }
    result.setTo(sign);

    int fields[3];
    fields[0] = offset / MILLIS_PER_HOUR;
    offset = offset % MILLIS_PER_HOUR;
    fields[1] = offset / MILLIS_PER_MINUTE;
    offset = offset % MILLIS_PER_MINUTE;
    fields[2] = offset / MILLIS_PER_SECOND;

    U_ASSERT(fields[0] >= 0 && fields[0] <= MAX_OFFSET_HOUR);
    U_ASSERT(fields[1] >= 0 && fields[1] <= MAX_OFFSET_MINUTE);
    U_ASSERT(fields[2] >= 0 && fields[2] <= MAX_OFFSET_SECOND);

    int32_t lastIdx = maxFields;
    while (lastIdx > minFields) {
        if (fields[lastIdx] != 0) {
            break;
        }
        lastIdx--;
    }

    for (int32_t idx = 0; idx <= lastIdx; idx++) {
        if (sep && idx != 0) {
            result.append(sep);
        }
        result.append((UChar)(0x0030 + fields[idx]/10));
        result.append((UChar)(0x0030 + fields[idx]%10));
    }

    return result;
}

int32_t
TimeZoneFormat::parseAbuttingAsciiOffsetFields(const UnicodeString& text, ParsePosition& pos, OffsetFields minFields, OffsetFields maxFields, UBool fixedHourWidth) {
    int32_t start = pos.getIndex();

    int32_t minDigits = 2 * (minFields + 1) - (fixedHourWidth ? 0 : 1);
    int32_t maxDigits = 2 * (maxFields + 1);

    U_ASSERT(maxDigits <= MAX_OFFSET_DIGITS);

    int32_t digits[MAX_OFFSET_DIGITS] = {};
    int32_t numDigits = 0;
    int32_t idx = start;
    while (numDigits < maxDigits && idx < text.length()) {
        UChar uch = text.charAt(idx);
        int32_t digit = DIGIT_VAL(uch);
        if (digit < 0) {
            break;
        }
        digits[numDigits] = digit;
        numDigits++;
        idx++;
    }

    if (fixedHourWidth && (numDigits & 1)) {
        // Fixed digits, so the number of digits must be even number. Truncating.
        numDigits--;
    }

    if (numDigits < minDigits) {
        pos.setErrorIndex(start);
        return 0;
    }

    int32_t hour = 0, min = 0, sec = 0;
    UBool bParsed = FALSE;
    while (numDigits >= minDigits) {
        switch (numDigits) {
        case 1: //H
            hour = digits[0];
            break;
        case 2: //HH
            hour = digits[0] * 10 + digits[1];
            break;
        case 3: //Hmm
            hour = digits[0];
            min = digits[1] * 10 + digits[2];
            break;
        case 4: //HHmm
            hour = digits[0] * 10 + digits[1];
            min = digits[2] * 10 + digits[3];
            break;
        case 5: //Hmmss
            hour = digits[0];
            min = digits[1] * 10 + digits[2];
            sec = digits[3] * 10 + digits[4];
            break;
        case 6: //HHmmss
            hour = digits[0] * 10 + digits[1];
            min = digits[2] * 10 + digits[3];
            sec = digits[4] * 10 + digits[5];
            break;
        }

        if (hour <= MAX_OFFSET_HOUR && min <= MAX_OFFSET_MINUTE && sec <= MAX_OFFSET_SECOND) {
            // Successfully parsed
            bParsed = true;
            break;
        }

        // Truncating
        numDigits -= (fixedHourWidth ? 2 : 1);
        hour = min = sec = 0;
    }

    if (!bParsed) {
        pos.setErrorIndex(start);
        return 0;
    }
    pos.setIndex(start + numDigits);
    return ((((hour * 60) + min) * 60) + sec) * 1000;
}

int32_t
TimeZoneFormat::parseAsciiOffsetFields(const UnicodeString& text, ParsePosition& pos, UChar sep, OffsetFields minFields, OffsetFields maxFields) {
    int32_t start = pos.getIndex();
    int32_t fieldVal[] = {0, 0, 0};
    int32_t fieldLen[] = {0, -1, -1};
    for (int32_t idx = start, fieldIdx = 0; idx < text.length() && fieldIdx <= maxFields; idx++) {
        UChar c = text.charAt(idx);
        if (c == sep) {
            if (fieldIdx == 0) {
                if (fieldLen[0] == 0) {
                    // no hours field
                    break;
                }
                // 1 digit hour, move to next field
            } else {
                if (fieldLen[fieldIdx] != -1) {
                    // premature minute or seconds field
                    break;
                }
                fieldLen[fieldIdx] = 0;
            }
            continue;
        } else if (fieldLen[fieldIdx] == -1) {
            // no separator after 2 digit field
            break;
        }
        int32_t digit = DIGIT_VAL(c);
        if (digit < 0) {
            // not a digit
            break;
        }
        fieldVal[fieldIdx] = fieldVal[fieldIdx] * 10 + digit;
        fieldLen[fieldIdx]++;
        if (fieldLen[fieldIdx] >= 2) {
            // parsed 2 digits, move to next field
            fieldIdx++;
        }
    }

    int32_t offset = 0;
    int32_t parsedLen = 0;
    int32_t parsedFields = -1;
    do {
        // hour
        if (fieldLen[0] == 0) {
            break;
        }
        if (fieldVal[0] > MAX_OFFSET_HOUR) {
            offset = (fieldVal[0] / 10) * MILLIS_PER_HOUR;
            parsedFields = FIELDS_H;
            parsedLen = 1;
            break;
        }
        offset = fieldVal[0] * MILLIS_PER_HOUR;
        parsedLen = fieldLen[0];
        parsedFields = FIELDS_H;

        // minute
        if (fieldLen[1] != 2 || fieldVal[1] > MAX_OFFSET_MINUTE) {
            break;
        }
        offset += fieldVal[1] * MILLIS_PER_MINUTE;
        parsedLen += (1 + fieldLen[1]);
        parsedFields = FIELDS_HM;

        // second
        if (fieldLen[2] != 2 || fieldVal[2] > MAX_OFFSET_SECOND) {
            break;
        }
        offset += fieldVal[2] * MILLIS_PER_SECOND;
        parsedLen += (1 + fieldLen[2]);
        parsedFields = FIELDS_HMS;
    } while (false);

    if (parsedFields < minFields) {
        pos.setErrorIndex(start);
        return 0;
    }

    pos.setIndex(start + parsedLen);
    return offset;
}

void
TimeZoneFormat::appendOffsetDigits(UnicodeString& buf, int32_t n, uint8_t minDigits) const {
    U_ASSERT(n >= 0 && n < 60);
    int32_t numDigits = n >= 10 ? 2 : 1;
    for (int32_t i = 0; i < minDigits - numDigits; i++) {
        buf.append(fGMTOffsetDigits[0]);
    }
    if (numDigits == 2) {
        buf.append(fGMTOffsetDigits[n / 10]);
    }
    buf.append(fGMTOffsetDigits[n % 10]);
}

// ------------------------------------------------------------------
// Private misc
void
TimeZoneFormat::initGMTPattern(const UnicodeString& gmtPattern, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return;
    }
    // This implementation not perfect, but sufficient practically.
    int32_t idx = gmtPattern.indexOf(ARG0, ARG0_LEN, 0);
    if (idx < 0) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    fGMTPattern.setTo(gmtPattern);
    unquote(gmtPattern.tempSubString(0, idx), fGMTPatternPrefix);
    unquote(gmtPattern.tempSubString(idx + ARG0_LEN), fGMTPatternSuffix);
}

UnicodeString&
TimeZoneFormat::unquote(const UnicodeString& pattern, UnicodeString& result) {
    if (pattern.indexOf(SINGLEQUOTE) < 0) {
        result.setTo(pattern);
        return result;
    }
    result.remove();
    UBool isPrevQuote = FALSE;
    UBool inQuote = FALSE;
    for (int32_t i = 0; i < pattern.length(); i++) {
        UChar c = pattern.charAt(i);
        if (c == SINGLEQUOTE) {
            if (isPrevQuote) {
                result.append(c);
                isPrevQuote = FALSE;
            } else {
                isPrevQuote = TRUE;
            }
            inQuote = !inQuote;
        } else {
            isPrevQuote = FALSE;
            result.append(c);
        }
    }
    return result;
}

UVector*
TimeZoneFormat::parseOffsetPattern(const UnicodeString& pattern, OffsetFields required, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    UVector* result = new UVector(deleteGMTOffsetField, NULL, status);
    if (result == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }

    int32_t checkBits = 0;
    UBool isPrevQuote = FALSE;
    UBool inQuote = FALSE;
    UChar textBuf[32];
    UnicodeString text(textBuf, 0, UPRV_LENGTHOF(textBuf));
    GMTOffsetField::FieldType itemType = GMTOffsetField::TEXT;
    int32_t itemLength = 1;

    for (int32_t i = 0; i < pattern.length(); i++) {
        UChar ch = pattern.charAt(i);
        if (ch == SINGLEQUOTE) {
            if (isPrevQuote) {
                text.append(SINGLEQUOTE);
                isPrevQuote = FALSE;
            } else {
                isPrevQuote = TRUE;
                if (itemType != GMTOffsetField::TEXT) {
                    if (GMTOffsetField::isValid(itemType, itemLength)) {
                        GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, static_cast<uint8_t>(itemLength), status);
                        result->addElement(fld, status);
                        if (U_FAILURE(status)) {
                            break;
                        }
                    } else {
                        status = U_ILLEGAL_ARGUMENT_ERROR;
                        break;
                    }
                    itemType = GMTOffsetField::TEXT;
                }
            }
            inQuote = !inQuote;
        } else {
            isPrevQuote = FALSE;
            if (inQuote) {
                text.append(ch);
            } else {
                GMTOffsetField::FieldType tmpType = GMTOffsetField::getTypeByLetter(ch);
                if (tmpType != GMTOffsetField::TEXT) {
                    // an offset time pattern character
                    if (tmpType == itemType) {
                        itemLength++;
                    } else {
                        if (itemType == GMTOffsetField::TEXT) {
                            if (text.length() > 0) {
                                GMTOffsetField* textfld = GMTOffsetField::createText(text, status);
                                result->addElement(textfld, status);
                                if (U_FAILURE(status)) {
                                    break;
                                }
                                text.remove();
                            }
                        } else {
                            if (GMTOffsetField::isValid(itemType, itemLength)) {
                                GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, static_cast<uint8_t>(itemLength), status);
                                result->addElement(fld, status);
                                if (U_FAILURE(status)) {
                                    break;
                                }
                            } else {
                                status = U_ILLEGAL_ARGUMENT_ERROR;
                                break;
                            }
                        }
                        itemType = tmpType;
                        itemLength = 1;
                        checkBits |= tmpType;
                    }
                } else {
                    // a string literal
                    if (itemType != GMTOffsetField::TEXT) {
                        if (GMTOffsetField::isValid(itemType, itemLength)) {
                            GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, static_cast<uint8_t>(itemLength), status);
                            result->addElement(fld, status);
                            if (U_FAILURE(status)) {
                                break;
                            }
                        } else {
                            status = U_ILLEGAL_ARGUMENT_ERROR;
                            break;
                        }
                        itemType = GMTOffsetField::TEXT;
                    }
                    text.append(ch);
                }
            }
        }
    }
    // handle last item
    if (U_SUCCESS(status)) {
        if (itemType == GMTOffsetField::TEXT) {
            if (text.length() > 0) {
                GMTOffsetField* tfld = GMTOffsetField::createText(text, status);
                result->addElement(tfld, status);
            }
        } else {
            if (GMTOffsetField::isValid(itemType, itemLength)) {
                GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, static_cast<uint8_t>(itemLength), status);
                result->addElement(fld, status);
            } else {
                status = U_ILLEGAL_ARGUMENT_ERROR;
            }
        }

        // Check all required fields are set
        if (U_SUCCESS(status)) {
            int32_t reqBits = 0;
            switch (required) {
            case FIELDS_H:
                reqBits = GMTOffsetField::HOUR;
                break;
            case FIELDS_HM:
                reqBits = GMTOffsetField::HOUR | GMTOffsetField::MINUTE;
                break;
            case FIELDS_HMS:
                reqBits = GMTOffsetField::HOUR | GMTOffsetField::MINUTE | GMTOffsetField::SECOND;
                break;
            }
            if (checkBits == reqBits) {
                // all required fields are set, no extra fields
                return result;
            }
        }
    }

    // error
    delete result;
    return NULL;
}

UnicodeString&
TimeZoneFormat::expandOffsetPattern(const UnicodeString& offsetHM, UnicodeString& result, UErrorCode& status) {
    result.setToBogus();
    if (U_FAILURE(status)) {
        return result;
    }
    U_ASSERT(u_strlen(DEFAULT_GMT_OFFSET_MINUTE_PATTERN) == 2);

    int32_t idx_mm = offsetHM.indexOf(DEFAULT_GMT_OFFSET_MINUTE_PATTERN, 2, 0);
    if (idx_mm < 0) {
        // Bad time zone hour pattern data
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return result;
    }

    UnicodeString sep;
    int32_t idx_H = offsetHM.tempSubString(0, idx_mm).lastIndexOf((UChar)0x0048 /* H */);
    if (idx_H >= 0) {
        sep = offsetHM.tempSubString(idx_H + 1, idx_mm - (idx_H + 1));
    }
    result.setTo(offsetHM.tempSubString(0, idx_mm + 2));
    result.append(sep);
    result.append(DEFAULT_GMT_OFFSET_SECOND_PATTERN, -1);
    result.append(offsetHM.tempSubString(idx_mm + 2));
    return result;
}

UnicodeString&
TimeZoneFormat::truncateOffsetPattern(const UnicodeString& offsetHM, UnicodeString& result, UErrorCode& status) {
    result.setToBogus();
    if (U_FAILURE(status)) {
        return result;
    }
    U_ASSERT(u_strlen(DEFAULT_GMT_OFFSET_MINUTE_PATTERN) == 2);

    int32_t idx_mm = offsetHM.indexOf(DEFAULT_GMT_OFFSET_MINUTE_PATTERN, 2, 0);
    if (idx_mm < 0) {
        // Bad time zone hour pattern data
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return result;
    }
    UChar HH[] = {0x0048, 0x0048};
    int32_t idx_HH = offsetHM.tempSubString(0, idx_mm).lastIndexOf(HH, 2, 0);
    if (idx_HH >= 0) {
        return result.setTo(offsetHM.tempSubString(0, idx_HH + 2));
    }
    int32_t idx_H = offsetHM.tempSubString(0, idx_mm).lastIndexOf((UChar)0x0048, 0);
    if (idx_H >= 0) {
        return result.setTo(offsetHM.tempSubString(0, idx_H + 1));
    }
    // Bad time zone hour pattern data
    status = U_ILLEGAL_ARGUMENT_ERROR;
    return result;
}

void
TimeZoneFormat::initGMTOffsetPatterns(UErrorCode& status) {
    for (int32_t type = 0; type < UTZFMT_PAT_COUNT; type++) {
        switch (type) {
        case UTZFMT_PAT_POSITIVE_H:
        case UTZFMT_PAT_NEGATIVE_H:
            fGMTOffsetPatternItems[type] = parseOffsetPattern(fGMTOffsetPatterns[type], FIELDS_H, status);
            break;
        case UTZFMT_PAT_POSITIVE_HM:
        case UTZFMT_PAT_NEGATIVE_HM:
            fGMTOffsetPatternItems[type] = parseOffsetPattern(fGMTOffsetPatterns[type], FIELDS_HM, status);
            break;
        case UTZFMT_PAT_POSITIVE_HMS:
        case UTZFMT_PAT_NEGATIVE_HMS:
            fGMTOffsetPatternItems[type] = parseOffsetPattern(fGMTOffsetPatterns[type], FIELDS_HMS, status);
            break;
        }
    }
    checkAbuttingHoursAndMinutes();
}

void
TimeZoneFormat::checkAbuttingHoursAndMinutes() {
    fAbuttingOffsetHoursAndMinutes= FALSE;
    for (int32_t type = 0; type < UTZFMT_PAT_COUNT; type++) {
        UBool afterH = FALSE;
        UVector *items = fGMTOffsetPatternItems[type];
        for (int32_t i = 0; i < items->size(); i++) {
            const GMTOffsetField* item = (GMTOffsetField*)items->elementAt(i);
            GMTOffsetField::FieldType fieldType = item->getType();
            if (fieldType != GMTOffsetField::TEXT) {
                if (afterH) {
                    fAbuttingOffsetHoursAndMinutes = TRUE;
                    break;
                } else if (fieldType == GMTOffsetField::HOUR) {
                    afterH = TRUE;
                }
            } else if (afterH) {
                break;
            }
        }
        if (fAbuttingOffsetHoursAndMinutes) {
            break;
        }
    }
}

UBool
TimeZoneFormat::toCodePoints(const UnicodeString& str, UChar32* codeArray, int32_t size) {
    int32_t count = str.countChar32();
    if (count != size) {
        return FALSE;
    }

    for (int32_t idx = 0, start = 0; idx < size; idx++) {
        codeArray[idx] = str.char32At(start);
        start = str.moveIndex32(start, 1);
    }

    return TRUE;
}

TimeZone*
TimeZoneFormat::createTimeZoneForOffset(int32_t offset) const {
    if (offset == 0) {
        // when offset is 0, we should use "Etc/GMT"
        return TimeZone::createTimeZone(UnicodeString(TRUE, TZID_GMT, -1));
    }
    return ZoneMeta::createCustomTimeZone(offset);
}

UTimeZoneFormatTimeType
TimeZoneFormat::getTimeType(UTimeZoneNameType nameType) {
    switch (nameType) {
    case UTZNM_LONG_STANDARD:
    case UTZNM_SHORT_STANDARD:
        return UTZFMT_TIME_TYPE_STANDARD;

    case UTZNM_LONG_DAYLIGHT:
    case UTZNM_SHORT_DAYLIGHT:
        return UTZFMT_TIME_TYPE_DAYLIGHT;

    default:
        return UTZFMT_TIME_TYPE_UNKNOWN;
    }
}

UnicodeString&
TimeZoneFormat::getTimeZoneID(const TimeZoneNames::MatchInfoCollection* matches, int32_t idx, UnicodeString& tzID) const {
    if (!matches->getTimeZoneIDAt(idx, tzID)) {
        UChar mzIDBuf[32];
        UnicodeString mzID(mzIDBuf, 0, UPRV_LENGTHOF(mzIDBuf));
        if (matches->getMetaZoneIDAt(idx, mzID)) {
            fTimeZoneNames->getReferenceZoneID(mzID, fTargetRegion, tzID);
        }
    }
    return tzID;
}


class ZoneIdMatchHandler : public TextTrieMapSearchResultHandler {
public:
    ZoneIdMatchHandler();
    virtual ~ZoneIdMatchHandler();

    UBool handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status);
    const UChar* getID();
    int32_t getMatchLen();
private:
    int32_t fLen;
    const UChar* fID;
};

ZoneIdMatchHandler::ZoneIdMatchHandler() 
: fLen(0), fID(NULL) {
}

ZoneIdMatchHandler::~ZoneIdMatchHandler() {
}

UBool
ZoneIdMatchHandler::handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return FALSE;
    }
    if (node->hasValues()) {
        const UChar* id = (const UChar*)node->getValue(0);
        if (id != NULL) {
            if (fLen < matchLength) {
                fID = id;
                fLen = matchLength;
            }
        }
    }
    return TRUE;
}

const UChar*
ZoneIdMatchHandler::getID() {
    return fID;
}

int32_t
ZoneIdMatchHandler::getMatchLen() {
    return fLen;
}


static void U_CALLCONV initZoneIdTrie(UErrorCode &status) {
    U_ASSERT(gZoneIdTrie == NULL);
    ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONEFORMAT, tzfmt_cleanup);
    gZoneIdTrie = new TextTrieMap(TRUE, NULL);    // No deleter, because values are pooled by ZoneMeta
    if (gZoneIdTrie == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    StringEnumeration *tzenum = TimeZone::createEnumeration();
    const UnicodeString *id;
    while ((id = tzenum->snext(status)) != NULL) {
        const UChar* uid = ZoneMeta::findTimeZoneID(*id);
        if (uid) {
            gZoneIdTrie->put(uid, const_cast<UChar *>(uid), status);
        }
    }
    delete tzenum;
}


UnicodeString&
TimeZoneFormat::parseZoneID(const UnicodeString& text, ParsePosition& pos, UnicodeString& tzID) const {
    UErrorCode status = U_ZERO_ERROR;
    umtx_initOnce(gZoneIdTrieInitOnce, &initZoneIdTrie, status);

    int32_t start = pos.getIndex();
    int32_t len = 0;
    tzID.setToBogus();

    if (U_SUCCESS(status)) {
        LocalPointer<ZoneIdMatchHandler> handler(new ZoneIdMatchHandler());
        gZoneIdTrie->search(text, start, handler.getAlias(), status); 
        len = handler->getMatchLen();
        if (len > 0) {
            tzID.setTo(handler->getID(), -1);
        }
    }

    if (len > 0) {
        pos.setIndex(start + len);
    } else {
        pos.setErrorIndex(start);
    }

    return tzID;
}

static void U_CALLCONV initShortZoneIdTrie(UErrorCode &status) {
    U_ASSERT(gShortZoneIdTrie == NULL);
    ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONEFORMAT, tzfmt_cleanup);
    StringEnumeration *tzenum = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status);
    if (U_SUCCESS(status)) {
        gShortZoneIdTrie = new TextTrieMap(TRUE, NULL);    // No deleter, because values are pooled by ZoneMeta
        if (gShortZoneIdTrie == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
        } else {
            const UnicodeString *id;
            while ((id = tzenum->snext(status)) != NULL) {
                const UChar* uID = ZoneMeta::findTimeZoneID(*id);
                const UChar* shortID = ZoneMeta::getShortID(*id);
                if (shortID && uID) {
                    gShortZoneIdTrie->put(shortID, const_cast<UChar *>(uID), status);
                }
            }
        }
    }
    delete tzenum;
}


UnicodeString&
TimeZoneFormat::parseShortZoneID(const UnicodeString& text, ParsePosition& pos, UnicodeString& tzID) const {
    UErrorCode status = U_ZERO_ERROR;
    umtx_initOnce(gShortZoneIdTrieInitOnce, &initShortZoneIdTrie, status);

    int32_t start = pos.getIndex();
    int32_t len = 0;
    tzID.setToBogus();

    if (U_SUCCESS(status)) {
        LocalPointer<ZoneIdMatchHandler> handler(new ZoneIdMatchHandler());
        gShortZoneIdTrie->search(text, start, handler.getAlias(), status); 
        len = handler->getMatchLen();
        if (len > 0) {
            tzID.setTo(handler->getID(), -1);
        }
    }

    if (len > 0) {
        pos.setIndex(start + len);
    } else {
        pos.setErrorIndex(start);
    }

    return tzID;
}


UnicodeString&
TimeZoneFormat::parseExemplarLocation(const UnicodeString& text, ParsePosition& pos, UnicodeString& tzID) const {
    int32_t startIdx = pos.getIndex();
    int32_t parsedPos = -1;
    tzID.setToBogus();

    UErrorCode status = U_ZERO_ERROR;
    LocalPointer<TimeZoneNames::MatchInfoCollection> exemplarMatches(fTimeZoneNames->find(text, startIdx, UTZNM_EXEMPLAR_LOCATION, status));
    if (U_FAILURE(status)) {
        pos.setErrorIndex(startIdx);
        return tzID;
    }
    int32_t matchIdx = -1;
    if (!exemplarMatches.isNull()) {
        for (int32_t i = 0; i < exemplarMatches->size(); i++) {
            if (startIdx + exemplarMatches->getMatchLengthAt(i) > parsedPos) {
                matchIdx = i;
                parsedPos = startIdx + exemplarMatches->getMatchLengthAt(i);
            }
        }
        if (parsedPos > 0) {
            pos.setIndex(parsedPos);
            getTimeZoneID(exemplarMatches.getAlias(), matchIdx, tzID);
        }
    }

    if (tzID.length() == 0) {
        pos.setErrorIndex(startIdx);
    }

    return tzID;
}

U_NAMESPACE_END

#endif
