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

#include "utypeinfo.h"  // for 'typeid' to work

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/vtzone.h"
#include "unicode/rbtz.h"
#include "unicode/ucal.h"
#include "unicode/ures.h"
#include "cmemory.h"
#include "uvector.h"
#include "gregoimp.h"

U_NAMESPACE_BEGIN

// This is the deleter that will be use to remove TimeZoneRule
U_CDECL_BEGIN
static void U_CALLCONV
deleteTimeZoneRule(void* obj) {
    delete (TimeZoneRule*) obj;
}
U_CDECL_END

// Smybol characters used by RFC2445 VTIMEZONE
static const UChar COLON = 0x3A; /* : */
static const UChar SEMICOLON = 0x3B; /* ; */
static const UChar EQUALS_SIGN = 0x3D; /* = */
static const UChar COMMA = 0x2C; /* , */
static const UChar PLUS = 0x2B; /* + */
static const UChar MINUS = 0x2D; /* - */

// RFC2445 VTIMEZONE tokens
static const UChar ICAL_BEGIN_VTIMEZONE[] = {0x42, 0x45, 0x47, 0x49, 0x4E, 0x3A, 0x56, 0x54, 0x49, 0x4D, 0x45, 0x5A, 0x4F, 0x4E, 0x45, 0}; /* "BEGIN:VTIMEZONE" */
static const UChar ICAL_END_VTIMEZONE[] = {0x45, 0x4E, 0x44, 0x3A, 0x56, 0x54, 0x49, 0x4D, 0x45, 0x5A, 0x4F, 0x4E, 0x45, 0}; /* "END:VTIMEZONE" */
static const UChar ICAL_BEGIN[] = {0x42, 0x45, 0x47, 0x49, 0x4E, 0}; /* "BEGIN" */
static const UChar ICAL_END[] = {0x45, 0x4E, 0x44, 0}; /* "END" */
static const UChar ICAL_VTIMEZONE[] = {0x56, 0x54, 0x49, 0x4D, 0x45, 0x5A, 0x4F, 0x4E, 0x45, 0}; /* "VTIMEZONE" */
static const UChar ICAL_TZID[] = {0x54, 0x5A, 0x49, 0x44, 0}; /* "TZID" */
static const UChar ICAL_STANDARD[] = {0x53, 0x54, 0x41, 0x4E, 0x44, 0x41, 0x52, 0x44, 0}; /* "STANDARD" */
static const UChar ICAL_DAYLIGHT[] = {0x44, 0x41, 0x59, 0x4C, 0x49, 0x47, 0x48, 0x54, 0}; /* "DAYLIGHT" */
static const UChar ICAL_DTSTART[] = {0x44, 0x54, 0x53, 0x54, 0x41, 0x52, 0x54, 0}; /* "DTSTART" */
static const UChar ICAL_TZOFFSETFROM[] = {0x54, 0x5A, 0x4F, 0x46, 0x46, 0x53, 0x45, 0x54, 0x46, 0x52, 0x4F, 0x4D, 0}; /* "TZOFFSETFROM" */
static const UChar ICAL_TZOFFSETTO[] = {0x54, 0x5A, 0x4F, 0x46, 0x46, 0x53, 0x45, 0x54, 0x54, 0x4F, 0}; /* "TZOFFSETTO" */
static const UChar ICAL_RDATE[] = {0x52, 0x44, 0x41, 0x54, 0x45, 0}; /* "RDATE" */
static const UChar ICAL_RRULE[] = {0x52, 0x52, 0x55, 0x4C, 0x45, 0}; /* "RRULE" */
static const UChar ICAL_TZNAME[] = {0x54, 0x5A, 0x4E, 0x41, 0x4D, 0x45, 0}; /* "TZNAME" */
static const UChar ICAL_TZURL[] = {0x54, 0x5A, 0x55, 0x52, 0x4C, 0}; /* "TZURL" */
static const UChar ICAL_LASTMOD[] = {0x4C, 0x41, 0x53, 0x54, 0x2D, 0x4D, 0x4F, 0x44, 0x49, 0x46, 0x49, 0x45, 0x44, 0}; /* "LAST-MODIFIED" */

static const UChar ICAL_FREQ[] = {0x46, 0x52, 0x45, 0x51, 0}; /* "FREQ" */
static const UChar ICAL_UNTIL[] = {0x55, 0x4E, 0x54, 0x49, 0x4C, 0}; /* "UNTIL" */
static const UChar ICAL_YEARLY[] = {0x59, 0x45, 0x41, 0x52, 0x4C, 0x59, 0}; /* "YEARLY" */
static const UChar ICAL_BYMONTH[] = {0x42, 0x59, 0x4D, 0x4F, 0x4E, 0x54, 0x48, 0}; /* "BYMONTH" */
static const UChar ICAL_BYDAY[] = {0x42, 0x59, 0x44, 0x41, 0x59, 0}; /* "BYDAY" */
static const UChar ICAL_BYMONTHDAY[] = {0x42, 0x59, 0x4D, 0x4F, 0x4E, 0x54, 0x48, 0x44, 0x41, 0x59, 0}; /* "BYMONTHDAY" */

static const UChar ICAL_NEWLINE[] = {0x0D, 0x0A, 0}; /* CRLF */

static const UChar ICAL_DOW_NAMES[7][3] = {
    {0x53, 0x55, 0}, /* "SU" */
    {0x4D, 0x4F, 0}, /* "MO" */
    {0x54, 0x55, 0}, /* "TU" */
    {0x57, 0x45, 0}, /* "WE" */
    {0x54, 0x48, 0}, /* "TH" */
    {0x46, 0x52, 0}, /* "FR" */
    {0x53, 0x41, 0}  /* "SA" */};

// Month length for non-leap year
static const int32_t MONTHLENGTH[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

// ICU custom property
static const UChar ICU_TZINFO_PROP[] = {0x58, 0x2D, 0x54, 0x5A, 0x49, 0x4E, 0x46, 0x4F, 0x3A, 0}; /* "X-TZINFO:" */
static const UChar ICU_TZINFO_PARTIAL[] = {0x2F, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6C, 0x40, 0}; /* "/Partial@" */
static const UChar ICU_TZINFO_SIMPLE[] = {0x2F, 0x53, 0x69, 0x6D, 0x70, 0x6C, 0x65, 0x40, 0}; /* "/Simple@" */


/*
 * Simple fixed digit ASCII number to integer converter
 */
static int32_t parseAsciiDigits(const UnicodeString& str, int32_t start, int32_t length, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return 0;
    }
    if (length <= 0 || str.length() < start || (start + length) > str.length()) {
        status = U_INVALID_FORMAT_ERROR;
        return 0;
    }
    int32_t sign = 1;
    if (str.charAt(start) == PLUS) {
        start++;
        length--;
    } else if (str.charAt(start) == MINUS) {
        sign = -1;
        start++;
        length--;
    }
    int32_t num = 0;
    for (int32_t i = 0; i < length; i++) {
        int32_t digit = str.charAt(start + i) - 0x0030;
        if (digit < 0 || digit > 9) {
            status = U_INVALID_FORMAT_ERROR;
            return 0;
        }
        num = 10 * num + digit;
    }
    return sign * num;    
}

static UnicodeString& appendAsciiDigits(int32_t number, uint8_t length, UnicodeString& str) {
    UBool negative = FALSE;
    int32_t digits[10]; // max int32_t is 10 decimal digits
    int32_t i;

    if (number < 0) {
        negative = TRUE;
        number *= -1;
    }

    length = length > 10 ? 10 : length;
    if (length == 0) {
        // variable length
        i = 0;
        do {
            digits[i++] = number % 10;
            number /= 10;
        } while (number != 0);
        length = i;
    } else {
        // fixed digits
        for (i = 0; i < length; i++) {
           digits[i] = number % 10;
           number /= 10;
        }
    }
    if (negative) {
        str.append(MINUS);
    }
    for (i = length - 1; i >= 0; i--) {
        str.append((UChar)(digits[i] + 0x0030));
    }
    return str;
}

static UnicodeString& appendMillis(UDate date, UnicodeString& str) {
    UBool negative = FALSE;
    int32_t digits[20]; // max int64_t is 20 decimal digits
    int32_t i;
    int64_t number;

    if (date < MIN_MILLIS) {
        number = (int64_t)MIN_MILLIS;
    } else if (date > MAX_MILLIS) {
        number = (int64_t)MAX_MILLIS;
    } else {
        number = (int64_t)date;
    }
    if (number < 0) {
        negative = TRUE;
        number *= -1;
    }
    i = 0;
    do {
        digits[i++] = (int32_t)(number % 10);
        number /= 10;
    } while (number != 0);

    if (negative) {
        str.append(MINUS);
    }
    i--;
    while (i >= 0) {
        str.append((UChar)(digits[i--] + 0x0030));
    }
    return str;
}

/*
 * Convert date/time to RFC2445 Date-Time form #1 DATE WITH LOCAL TIME
 */
static UnicodeString& getDateTimeString(UDate time, UnicodeString& str) {
    int32_t year, month, dom, dow, doy, mid;
    Grego::timeToFields(time, year, month, dom, dow, doy, mid);

    str.remove();
    appendAsciiDigits(year, 4, str);
    appendAsciiDigits(month + 1, 2, str);
    appendAsciiDigits(dom, 2, str);
    str.append((UChar)0x0054 /*'T'*/);

    int32_t t = mid;
    int32_t hour = t / U_MILLIS_PER_HOUR;
    t %= U_MILLIS_PER_HOUR;
    int32_t min = t / U_MILLIS_PER_MINUTE;
    t %= U_MILLIS_PER_MINUTE;
    int32_t sec = t / U_MILLIS_PER_SECOND;

    appendAsciiDigits(hour, 2, str);
    appendAsciiDigits(min, 2, str);
    appendAsciiDigits(sec, 2, str);
    return str;
}

/*
 * Convert date/time to RFC2445 Date-Time form #2 DATE WITH UTC TIME
 */
static UnicodeString& getUTCDateTimeString(UDate time, UnicodeString& str) {
    getDateTimeString(time, str);
    str.append((UChar)0x005A /*'Z'*/);
    return str;
}

/*
 * Parse RFC2445 Date-Time form #1 DATE WITH LOCAL TIME and
 * #2 DATE WITH UTC TIME
 */
static UDate parseDateTimeString(const UnicodeString& str, int32_t offset, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return 0.0;
    }

    int32_t year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0;
    UBool isUTC = FALSE;
    UBool isValid = FALSE;
    do {
        int length = str.length();
        if (length != 15 && length != 16) {
            // FORM#1 15 characters, such as "20060317T142115"
            // FORM#2 16 characters, such as "20060317T142115Z"
            break;
        }
        if (str.charAt(8) != 0x0054) {
            // charcter "T" must be used for separating date and time
            break;
        }
        if (length == 16) {
            if (str.charAt(15) != 0x005A) {
                // invalid format
                break;
            }
            isUTC = TRUE;
        }

        year = parseAsciiDigits(str, 0, 4, status);
        month = parseAsciiDigits(str, 4, 2, status) - 1;  // 0-based
        day = parseAsciiDigits(str, 6, 2, status);
        hour = parseAsciiDigits(str, 9, 2, status);
        min = parseAsciiDigits(str, 11, 2, status);
        sec = parseAsciiDigits(str, 13, 2, status);

        if (U_FAILURE(status)) {
            break;
        }

        // check valid range
        int32_t maxDayOfMonth = Grego::monthLength(year, month);
        if (year < 0 || month < 0 || month > 11 || day < 1 || day > maxDayOfMonth ||
                hour < 0 || hour >= 24 || min < 0 || min >= 60 || sec < 0 || sec >= 60) {
            break;
        }

        isValid = TRUE;
    } while(false);

    if (!isValid) {
        status = U_INVALID_FORMAT_ERROR;
        return 0.0;
    }
    // Calculate the time
    UDate time = Grego::fieldsToDay(year, month, day) * U_MILLIS_PER_DAY;
    time += (hour * U_MILLIS_PER_HOUR + min * U_MILLIS_PER_MINUTE + sec * U_MILLIS_PER_SECOND);
    if (!isUTC) {
        time -= offset;
    }
    return time;
}

/*
 * Convert RFC2445 utc-offset string to milliseconds
 */
static int32_t offsetStrToMillis(const UnicodeString& str, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return 0;
    }

    UBool isValid = FALSE;
    int32_t sign = 0, hour = 0, min = 0, sec = 0;

    do {
        int length = str.length();
        if (length != 5 && length != 7) {
            // utf-offset must be 5 or 7 characters
            break;
        }
        // sign
        UChar s = str.charAt(0);
        if (s == PLUS) {
            sign = 1;
        } else if (s == MINUS) {
            sign = -1;
        } else {
            // utf-offset must start with "+" or "-"
            break;
        }
        hour = parseAsciiDigits(str, 1, 2, status);
        min = parseAsciiDigits(str, 3, 2, status);
        if (length == 7) {
            sec = parseAsciiDigits(str, 5, 2, status);
        }
        if (U_FAILURE(status)) {
            break;
        }
        isValid = true;
    } while(false);

    if (!isValid) {
        status = U_INVALID_FORMAT_ERROR;
        return 0;
    }
    int32_t millis = sign * ((hour * 60 + min) * 60 + sec) * 1000;
    return millis;
}

/*
 * Convert milliseconds to RFC2445 utc-offset string
 */
static void millisToOffset(int32_t millis, UnicodeString& str) {
    str.remove();
    if (millis >= 0) {
        str.append(PLUS);
    } else {
        str.append(MINUS);
        millis = -millis;
    }
    int32_t hour, min, sec;
    int32_t t = millis / 1000;

    sec = t % 60;
    t = (t - sec) / 60;
    min = t % 60;
    hour = t / 60;

    appendAsciiDigits(hour, 2, str);
    appendAsciiDigits(min, 2, str);
    appendAsciiDigits(sec, 2, str);
}

/*
 * Create a default TZNAME from TZID
 */
static void getDefaultTZName(const UnicodeString tzid, UBool isDST, UnicodeString& zonename) {
    zonename = tzid;
    if (isDST) {
        zonename += UNICODE_STRING_SIMPLE("(DST)");
    } else {
        zonename += UNICODE_STRING_SIMPLE("(STD)");
    }
}

/*
 * Parse individual RRULE
 * 
 * On return -
 * 
 * month    calculated by BYMONTH-1, or -1 when not found
 * dow      day of week in BYDAY, or 0 when not found
 * wim      day of week ordinal number in BYDAY, or 0 when not found
 * dom      an array of day of month
 * domCount number of availble days in dom (domCount is specifying the size of dom on input)
 * until    time defined by UNTIL attribute or MIN_MILLIS if not available
 */
static void parseRRULE(const UnicodeString& rrule, int32_t& month, int32_t& dow, int32_t& wim,
                       int32_t* dom, int32_t& domCount, UDate& until, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return;
    }
    int32_t numDom = 0;

    month = -1;
    dow = 0;
    wim = 0;
    until = MIN_MILLIS;

    UBool yearly = FALSE;
    //UBool parseError = FALSE;

    int32_t prop_start = 0;
    int32_t prop_end;
    UnicodeString prop, attr, value;
    UBool nextProp = TRUE;

    while (nextProp) {
        prop_end = rrule.indexOf(SEMICOLON, prop_start);
        if (prop_end == -1) {
            prop.setTo(rrule, prop_start);
            nextProp = FALSE;
        } else {
            prop.setTo(rrule, prop_start, prop_end - prop_start);
            prop_start = prop_end + 1;
        }
        int32_t eql = prop.indexOf(EQUALS_SIGN);
        if (eql != -1) {
            attr.setTo(prop, 0, eql);
            value.setTo(prop, eql + 1);
        } else {
            goto rruleParseError;
        }

        if (attr.compare(ICAL_FREQ, -1) == 0) {
            // only support YEARLY frequency type
            if (value.compare(ICAL_YEARLY, -1) == 0) {
                yearly = TRUE;
            } else {
                goto rruleParseError;
            }
        } else if (attr.compare(ICAL_UNTIL, -1) == 0) {
            // ISO8601 UTC format, for example, "20060315T020000Z"
            until = parseDateTimeString(value, 0, status);
            if (U_FAILURE(status)) {
                goto rruleParseError;
            }
        } else if (attr.compare(ICAL_BYMONTH, -1) == 0) {
            // Note: BYMONTH may contain multiple months, but only single month make sense for
            // VTIMEZONE property.
            if (value.length() > 2) {
                goto rruleParseError;
            }
            month = parseAsciiDigits(value, 0, value.length(), status) - 1;
            if (U_FAILURE(status) || month < 0 || month >= 12) {
                goto rruleParseError;
            }
        } else if (attr.compare(ICAL_BYDAY, -1) == 0) {
            // Note: BYDAY may contain multiple day of week separated by comma.  It is unlikely used for
            // VTIMEZONE property.  We do not support the case.

            // 2-letter format is used just for representing a day of week, for example, "SU" for Sunday
            // 3 or 4-letter format is used for represeinging Nth day of week, for example, "-1SA" for last Saturday
            int32_t length = value.length();
            if (length < 2 || length > 4) {
                goto rruleParseError;
            }
            if (length > 2) {
                // Nth day of week
                int32_t sign = 1;
                if (value.charAt(0) == PLUS) {
                    sign = 1;
                } else if (value.charAt(0) == MINUS) {
                    sign = -1;
                } else if (length == 4) {
                    goto rruleParseError;
                }
                int32_t n = parseAsciiDigits(value, length - 3, 1, status);
                if (U_FAILURE(status) || n == 0 || n > 4) {
                    goto rruleParseError;
                }
                wim = n * sign;
                value.remove(0, length - 2);
            }
            int32_t wday;
            for (wday = 0; wday < 7; wday++) {
                if (value.compare(ICAL_DOW_NAMES[wday], 2) == 0) {
                    break;
                }
            }
            if (wday < 7) {
                // Sunday(1) - Saturday(7)
                dow = wday + 1;
            } else {
                goto rruleParseError;
            }
        } else if (attr.compare(ICAL_BYMONTHDAY, -1) == 0) {
            // Note: BYMONTHDAY may contain multiple days delimitted by comma
            //
            // A value of BYMONTHDAY could be negative, for example, -1 means
            // the last day in a month
            int32_t dom_idx = 0;
            int32_t dom_start = 0;
            int32_t dom_end;
            UBool nextDOM = TRUE;
            while (nextDOM) {
                dom_end = value.indexOf(COMMA, dom_start);
                if (dom_end == -1) {
                    dom_end = value.length();
                    nextDOM = FALSE;
                }
                if (dom_idx < domCount) {
                    dom[dom_idx] = parseAsciiDigits(value, dom_start, dom_end - dom_start, status);
                    if (U_FAILURE(status)) {
                        goto rruleParseError;
                    }
                    dom_idx++;
                } else {
                    status = U_BUFFER_OVERFLOW_ERROR;
                    goto rruleParseError;
                }
                dom_start = dom_end + 1;
            }
            numDom = dom_idx;
        }
    }
    if (!yearly) {
        // FREQ=YEARLY must be set
        goto rruleParseError;
    }
    // Set actual number of parsed DOM (ICAL_BYMONTHDAY)
    domCount = numDom;
    return;

rruleParseError:
    if (U_SUCCESS(status)) {
        // Set error status
        status = U_INVALID_FORMAT_ERROR;
    }
}

static TimeZoneRule* createRuleByRRULE(const UnicodeString& zonename, int rawOffset, int dstSavings, UDate start,
                                       UVector* dates, int fromOffset, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    if (dates == NULL || dates->size() == 0) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return NULL;
    }

    int32_t i, j;
    DateTimeRule *adtr = NULL;

    // Parse the first rule
    UnicodeString rrule = *((UnicodeString*)dates->elementAt(0));
    int32_t month, dayOfWeek, nthDayOfWeek, dayOfMonth = 0;
    int32_t days[7];
    int32_t daysCount = sizeof(days)/sizeof(days[0]);
    UDate until;

    parseRRULE(rrule, month, dayOfWeek, nthDayOfWeek, days, daysCount, until, status);
    if (U_FAILURE(status)) {
        return NULL;
    }

    if (dates->size() == 1) {
        // No more rules
        if (daysCount > 1) {
            // Multiple BYMONTHDAY values
            if (daysCount != 7 || month == -1 || dayOfWeek == 0) {
                // Only support the rule using 7 continuous days
                // BYMONTH and BYDAY must be set at the same time
                goto unsupportedRRule;
            }
            int32_t firstDay = 31; // max possible number of dates in a month
            for (i = 0; i < 7; i++) {
                // Resolve negative day numbers.  A negative day number should
                // not be used in February, but if we see such case, we use 28
                // as the base.
                if (days[i] < 0) {
                    days[i] = MONTHLENGTH[month] + days[i] + 1;
                }
                if (days[i] < firstDay) {
                    firstDay = days[i];
                }
            }
            // Make sure days are continuous
            for (i = 1; i < 7; i++) {
                UBool found = FALSE;
                for (j = 0; j < 7; j++) {
                    if (days[j] == firstDay + i) {
                        found = TRUE;
                        break;
                    }
                }
                if (!found) {
                    // days are not continuous
                    goto unsupportedRRule;
                }
            }
            // Use DOW_GEQ_DOM rule with firstDay as the start date
            dayOfMonth = firstDay;
        }
    } else {
        // Check if BYMONTH + BYMONTHDAY + BYDAY rule with multiple RRULE lines.
        // Otherwise, not supported.
        if (month == -1 || dayOfWeek == 0 || daysCount == 0) {
            // This is not the case
            goto unsupportedRRule;
        }
        // Parse the rest of rules if number of rules is not exceeding 7.
        // We can only support 7 continuous days starting from a day of month.
        if (dates->size() > 7) {
            goto unsupportedRRule;
        }

        // Note: To check valid date range across multiple rule is a little
        // bit complicated.  For now, this code is not doing strict range
        // checking across month boundary

        int32_t earliestMonth = month;
        int32_t earliestDay = 31;
        for (i = 0; i < daysCount; i++) {
            int32_t dom = days[i];
            dom = dom > 0 ? dom : MONTHLENGTH[month] + dom + 1;
            earliestDay = dom < earliestDay ? dom : earliestDay;
        }

        int32_t anotherMonth = -1;
        for (i = 1; i < dates->size(); i++) {
            rrule = *((UnicodeString*)dates->elementAt(i));
            UDate tmp_until;
            int32_t tmp_month, tmp_dayOfWeek, tmp_nthDayOfWeek;
            int32_t tmp_days[7];
            int32_t tmp_daysCount = sizeof(tmp_days)/sizeof(tmp_days[0]);
            parseRRULE(rrule, tmp_month, tmp_dayOfWeek, tmp_nthDayOfWeek, tmp_days, tmp_daysCount, tmp_until, status);
            if (U_FAILURE(status)) {
                return NULL;
            }
            // If UNTIL is newer than previous one, use the one
            if (tmp_until > until) {
                until = tmp_until;
            }
            
            // Check if BYMONTH + BYMONTHDAY + BYDAY rule
            if (tmp_month == -1 || tmp_dayOfWeek == 0 || tmp_daysCount == 0) {
                goto unsupportedRRule;
            }
            // Count number of BYMONTHDAY
            if (daysCount + tmp_daysCount > 7) {
                // We cannot support BYMONTHDAY more than 7
                goto unsupportedRRule;
            }
            // Check if the same BYDAY is used.  Otherwise, we cannot
            // support the rule
            if (tmp_dayOfWeek != dayOfWeek) {
                goto unsupportedRRule;
            }
            // Check if the month is same or right next to the primary month
            if (tmp_month != month) {
                if (anotherMonth == -1) {
                    int32_t diff = tmp_month - month;
                    if (diff == -11 || diff == -1) {
                        // Previous month
                        anotherMonth = tmp_month;
                        earliestMonth = anotherMonth;
                        // Reset earliest day
                        earliestDay = 31;
                    } else if (diff == 11 || diff == 1) {
                        // Next month
                        anotherMonth = tmp_month;
                    } else {
                        // The day range cannot exceed more than 2 months
                        goto unsupportedRRule;
                    }
                } else if (tmp_month != month && tmp_month != anotherMonth) {
                    // The day range cannot exceed more than 2 months
                    goto unsupportedRRule;
                }
            }
            // If ealier month, go through days to find the earliest day
            if (tmp_month == earliestMonth) {
                for (j = 0; j < tmp_daysCount; j++) {
                    tmp_days[j] = tmp_days[j] > 0 ? tmp_days[j] : MONTHLENGTH[tmp_month] + tmp_days[j] + 1;
                    earliestDay = tmp_days[j] < earliestDay ? tmp_days[j] : earliestDay;
                }
            }
            daysCount += tmp_daysCount;
        }
        if (daysCount != 7) {
            // Number of BYMONTHDAY entries must be 7
            goto unsupportedRRule;
        }
        month = earliestMonth;
        dayOfMonth = earliestDay;
    }

    // Calculate start/end year and missing fields
    int32_t startYear, startMonth, startDOM, startDOW, startDOY, startMID;
    Grego::timeToFields(start + fromOffset, startYear, startMonth, startDOM,
        startDOW, startDOY, startMID);
    if (month == -1) {
        // If BYMONTH is not set, use the month of DTSTART
        month = startMonth;
    }
    if (dayOfWeek == 0 && nthDayOfWeek == 0 && dayOfMonth == 0) {
        // If only YEARLY is set, use the day of DTSTART as BYMONTHDAY
        dayOfMonth = startDOM;
    }

    int32_t endYear;
    if (until != MIN_MILLIS) {
        int32_t endMonth, endDOM, endDOW, endDOY, endMID;
        Grego::timeToFields(until, endYear, endMonth, endDOM, endDOW, endDOY, endMID);
    } else {
        endYear = AnnualTimeZoneRule::MAX_YEAR;
    }

    // Create the AnnualDateTimeRule
    if (dayOfWeek == 0 && nthDayOfWeek == 0 && dayOfMonth != 0) {
        // Day in month rule, for example, 15th day in the month
        adtr = new DateTimeRule(month, dayOfMonth, startMID, DateTimeRule::WALL_TIME);
    } else if (dayOfWeek != 0 && nthDayOfWeek != 0 && dayOfMonth == 0) {
        // Nth day of week rule, for example, last Sunday
        adtr = new DateTimeRule(month, nthDayOfWeek, dayOfWeek, startMID, DateTimeRule::WALL_TIME);
    } else if (dayOfWeek != 0 && nthDayOfWeek == 0 && dayOfMonth != 0) {
        // First day of week after day of month rule, for example,
        // first Sunday after 15th day in the month
        adtr = new DateTimeRule(month, dayOfMonth, dayOfWeek, TRUE, startMID, DateTimeRule::WALL_TIME);
    }
    if (adtr == NULL) {
        goto unsupportedRRule;
    }
    return new AnnualTimeZoneRule(zonename, rawOffset, dstSavings, adtr, startYear, endYear);

unsupportedRRule:
    status = U_INVALID_STATE_ERROR;
    return NULL;
}

/*
 * Create a TimeZoneRule by the RDATE definition
 */
static TimeZoneRule* createRuleByRDATE(const UnicodeString& zonename, int32_t rawOffset, int32_t dstSavings,
                                       UDate start, UVector* dates, int32_t fromOffset, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    TimeArrayTimeZoneRule *retVal = NULL;
    if (dates == NULL || dates->size() == 0) {
        // When no RDATE line is provided, use start (DTSTART)
        // as the transition time
        retVal = new TimeArrayTimeZoneRule(zonename, rawOffset, dstSavings,
            &start, 1, DateTimeRule::UTC_TIME);
    } else {
        // Create an array of transition times
        int32_t size = dates->size();
        UDate* times = (UDate*)uprv_malloc(sizeof(UDate) * size);
        if (times == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
            return NULL;
        }
        for (int32_t i = 0; i < size; i++) {
            UnicodeString *datestr = (UnicodeString*)dates->elementAt(i);
            times[i] = parseDateTimeString(*datestr, fromOffset, status);
            if (U_FAILURE(status)) {
                uprv_free(times);
                return NULL;
            }
        }
        retVal = new TimeArrayTimeZoneRule(zonename, rawOffset, dstSavings,
            times, size, DateTimeRule::UTC_TIME);
        uprv_free(times);
    }
    return retVal;
}

/*
 * Check if the DOW rule specified by month, weekInMonth and dayOfWeek is equivalent
 * to the DateTimerule.
 */
static UBool isEquivalentDateRule(int32_t month, int32_t weekInMonth, int32_t dayOfWeek, const DateTimeRule *dtrule) {
    if (month != dtrule->getRuleMonth() || dayOfWeek != dtrule->getRuleDayOfWeek()) {
        return FALSE;
    }
    if (dtrule->getTimeRuleType() != DateTimeRule::WALL_TIME) {
        // Do not try to do more intelligent comparison for now.
        return FALSE;
    }
    if (dtrule->getDateRuleType() == DateTimeRule::DOW
            && dtrule->getRuleWeekInMonth() == weekInMonth) {
        return TRUE;
    }
    int32_t ruleDOM = dtrule->getRuleDayOfMonth();
    if (dtrule->getDateRuleType() == DateTimeRule::DOW_GEQ_DOM) {
        if (ruleDOM%7 == 1 && (ruleDOM + 6)/7 == weekInMonth) {
            return TRUE;
        }
        if (month != UCAL_FEBRUARY && (MONTHLENGTH[month] - ruleDOM)%7 == 6
                && weekInMonth == -1*((MONTHLENGTH[month]-ruleDOM+1)/7)) {
            return TRUE;
        }
    }
    if (dtrule->getDateRuleType() == DateTimeRule::DOW_LEQ_DOM) {
        if (ruleDOM%7 == 0 && ruleDOM/7 == weekInMonth) {
            return TRUE;
        }
        if (month != UCAL_FEBRUARY && (MONTHLENGTH[month] - ruleDOM)%7 == 0
                && weekInMonth == -1*((MONTHLENGTH[month] - ruleDOM)/7 + 1)) {
            return TRUE;
        }
    }
    return FALSE;
}

/*
 * Convert the rule to its equivalent rule using WALL_TIME mode.
 * This function returns NULL when the specified DateTimeRule is already
 * using WALL_TIME mode.
 */
static DateTimeRule* toWallTimeRule(const DateTimeRule* rule, int32_t rawOffset, int32_t dstSavings) {
    if (rule->getTimeRuleType() == DateTimeRule::WALL_TIME) {
        return NULL;
    }
    int32_t wallt = rule->getRuleMillisInDay();
    if (rule->getTimeRuleType() == DateTimeRule::UTC_TIME) {
        wallt += (rawOffset + dstSavings);
    } else if (rule->getTimeRuleType() == DateTimeRule::STANDARD_TIME) {
        wallt += dstSavings;
    }

    int32_t month = -1, dom = 0, dow = 0;
    DateTimeRule::DateRuleType dtype;
    int32_t dshift = 0;
    if (wallt < 0) {
        dshift = -1;
        wallt += U_MILLIS_PER_DAY;
    } else if (wallt >= U_MILLIS_PER_DAY) {
        dshift = 1;
        wallt -= U_MILLIS_PER_DAY;
    }

    month = rule->getRuleMonth();
    dom = rule->getRuleDayOfMonth();
    dow = rule->getRuleDayOfWeek();
    dtype = rule->getDateRuleType();

    if (dshift != 0) {
        if (dtype == DateTimeRule::DOW) {
            // Convert to DOW_GEW_DOM or DOW_LEQ_DOM rule first
            int32_t wim = rule->getRuleWeekInMonth();
            if (wim > 0) {
                dtype = DateTimeRule::DOW_GEQ_DOM;
                dom = 7 * (wim - 1) + 1;
            } else {
                dtype = DateTimeRule::DOW_LEQ_DOM;
                dom = MONTHLENGTH[month] + 7 * (wim + 1);
            }
        }
        // Shift one day before or after
        dom += dshift;
        if (dom == 0) {
            month--;
            month = month < UCAL_JANUARY ? UCAL_DECEMBER : month;
            dom = MONTHLENGTH[month];
        } else if (dom > MONTHLENGTH[month]) {
            month++;
            month = month > UCAL_DECEMBER ? UCAL_JANUARY : month;
            dom = 1;
        }
        if (dtype != DateTimeRule::DOM) {
            // Adjust day of week
            dow += dshift;
            if (dow < UCAL_SUNDAY) {
                dow = UCAL_SATURDAY;
            } else if (dow > UCAL_SATURDAY) {
                dow = UCAL_SUNDAY;
            }
        }
    }
    // Create a new rule
    DateTimeRule *modifiedRule;
    if (dtype == DateTimeRule::DOM) {
        modifiedRule = new DateTimeRule(month, dom, wallt, DateTimeRule::WALL_TIME);
    } else {
        modifiedRule = new DateTimeRule(month, dom, dow,
            (dtype == DateTimeRule::DOW_GEQ_DOM), wallt, DateTimeRule::WALL_TIME);
    }
    return modifiedRule;
}

/*
 * Minumum implementations of stream writer/reader, writing/reading
 * UnicodeString.  For now, we do not want to introduce the dependency
 * on the ICU I/O stream in this module.  But we want to keep the code
 * equivalent to the ICU4J implementation, which utilizes java.io.Writer/
 * Reader.
 */
class VTZWriter {
public:
    VTZWriter(UnicodeString& out);
    ~VTZWriter();

    void write(const UnicodeString& str);
    void write(UChar ch);
    void write(const UChar* str);
    //void write(const UChar* str, int32_t length);
private:
    UnicodeString* out;
};

VTZWriter::VTZWriter(UnicodeString& output) {
    out = &output;
}

VTZWriter::~VTZWriter() {
}

void
VTZWriter::write(const UnicodeString& str) {
    out->append(str);
}

void
VTZWriter::write(UChar ch) {
    out->append(ch);
}

void
VTZWriter::write(const UChar* str) {
    out->append(str, -1);
}

/*
void
VTZWriter::write(const UChar* str, int32_t length) {
    out->append(str, length);
}
*/

class VTZReader {
public:
    VTZReader(const UnicodeString& input);
    ~VTZReader();

    UChar read(void);
private:
    const UnicodeString* in;
    int32_t index;
};

VTZReader::VTZReader(const UnicodeString& input) {
    in = &input;
    index = 0;
}

VTZReader::~VTZReader() {
}

UChar
VTZReader::read(void) {
    UChar ch = 0xFFFF;
    if (index < in->length()) {
        ch = in->charAt(index);
    }
    index++;
    return ch;
}


UOBJECT_DEFINE_RTTI_IMPLEMENTATION(VTimeZone)

VTimeZone::VTimeZone()
:   BasicTimeZone(), tz(NULL), vtzlines(NULL),
    lastmod(MAX_MILLIS) {
}

VTimeZone::VTimeZone(const VTimeZone& source)
:   BasicTimeZone(source), tz(NULL), vtzlines(NULL),
    tzurl(source.tzurl), lastmod(source.lastmod),
    olsonzid(source.olsonzid), icutzver(source.icutzver) {
    if (source.tz != NULL) {
        tz = (BasicTimeZone*)source.tz->clone();
    }
    if (source.vtzlines != NULL) {
        UErrorCode status = U_ZERO_ERROR;
        int32_t size = source.vtzlines->size();
        vtzlines = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, size, status);
        if (U_SUCCESS(status)) {
            for (int32_t i = 0; i < size; i++) {
                UnicodeString *line = (UnicodeString*)source.vtzlines->elementAt(i);
                vtzlines->addElement(line->clone(), status);
                if (U_FAILURE(status)) {
                    break;
                }
            }
        }
        if (U_FAILURE(status) && vtzlines != NULL) {
            delete vtzlines;
        }
    }
}

VTimeZone::~VTimeZone() {
    if (tz != NULL) {
        delete tz;
    }
    if (vtzlines != NULL) {
        delete vtzlines;
    }
}

VTimeZone&
VTimeZone::operator=(const VTimeZone& right) {
    if (this == &right) {
        return *this;
    }
    if (*this != right) {
        BasicTimeZone::operator=(right);
        if (tz != NULL) {
            delete tz;
            tz = NULL;
        }
        if (right.tz != NULL) {
            tz = (BasicTimeZone*)right.tz->clone();
        }
        if (vtzlines != NULL) {
            delete vtzlines;
        }
        if (right.vtzlines != NULL) {
            UErrorCode status = U_ZERO_ERROR;
            int32_t size = right.vtzlines->size();
            vtzlines = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, size, status);
            if (U_SUCCESS(status)) {
                for (int32_t i = 0; i < size; i++) {
                    UnicodeString *line = (UnicodeString*)right.vtzlines->elementAt(i);
                    vtzlines->addElement(line->clone(), status);
                    if (U_FAILURE(status)) {
                        break;
                    }
                }
            }
            if (U_FAILURE(status) && vtzlines != NULL) {
                delete vtzlines;
                vtzlines = NULL;
            }
        }
        tzurl = right.tzurl;
        lastmod = right.lastmod;
        olsonzid = right.olsonzid;
        icutzver = right.icutzver;
    }
    return *this;
}

UBool
VTimeZone::operator==(const TimeZone& that) const {
    if (this == &that) {
        return TRUE;
    }
    if (typeid(*this) != typeid(that) || !BasicTimeZone::operator==(that)) {
        return FALSE;
    }
    VTimeZone *vtz = (VTimeZone*)&that;
    if (*tz == *(vtz->tz)
        && tzurl == vtz->tzurl
        && lastmod == vtz->lastmod
        /* && olsonzid = that.olsonzid */
        /* && icutzver = that.icutzver */) {
        return TRUE;
    }
    return FALSE;
}

UBool
VTimeZone::operator!=(const TimeZone& that) const {
    return !operator==(that);
}

VTimeZone*
VTimeZone::createVTimeZoneByID(const UnicodeString& ID) {
    VTimeZone *vtz = new VTimeZone();
    vtz->tz = (BasicTimeZone*)TimeZone::createTimeZone(ID);
    vtz->tz->getID(vtz->olsonzid);

    // Set ICU tzdata version
    UErrorCode status = U_ZERO_ERROR;
    UResourceBundle *bundle = NULL;
    const UChar* versionStr = NULL;
    int32_t len = 0;
    bundle = ures_openDirect(NULL, "zoneinfo64", &status);
    versionStr = ures_getStringByKey(bundle, "TZVersion", &len, &status);
    if (U_SUCCESS(status)) {
        vtz->icutzver.setTo(versionStr, len);
    }
    ures_close(bundle);
    return vtz;
}

VTimeZone*
VTimeZone::createVTimeZoneFromBasicTimeZone(const BasicTimeZone& basic_time_zone, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    VTimeZone *vtz = new VTimeZone();
    if (vtz == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    vtz->tz = (BasicTimeZone *)basic_time_zone.clone();
    if (vtz->tz == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        delete vtz;
        return NULL;
    }
    vtz->tz->getID(vtz->olsonzid);

    // Set ICU tzdata version
    UResourceBundle *bundle = NULL;
    const UChar* versionStr = NULL;
    int32_t len = 0;
    bundle = ures_openDirect(NULL, "zoneinfo64", &status);
    versionStr = ures_getStringByKey(bundle, "TZVersion", &len, &status);
    if (U_SUCCESS(status)) {
        vtz->icutzver.setTo(versionStr, len);
    }
    ures_close(bundle);
    return vtz;
}

VTimeZone*
VTimeZone::createVTimeZone(const UnicodeString& vtzdata, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    VTZReader reader(vtzdata);
    VTimeZone *vtz = new VTimeZone();
    vtz->load(reader, status);
    if (U_FAILURE(status)) {
        delete vtz;
        return NULL;
    }
    return vtz;
}

UBool
VTimeZone::getTZURL(UnicodeString& url) const {
    if (tzurl.length() > 0) {
        url = tzurl;
        return TRUE;
    }
    return FALSE;
}

void
VTimeZone::setTZURL(const UnicodeString& url) {
    tzurl = url;
}

UBool
VTimeZone::getLastModified(UDate& lastModified) const {
    if (lastmod != MAX_MILLIS) {
        lastModified = lastmod;
        return TRUE;
    }
    return FALSE;
}

void
VTimeZone::setLastModified(UDate lastModified) {
    lastmod = lastModified;
}

void
VTimeZone::write(UnicodeString& result, UErrorCode& status) const {
    result.remove();
    VTZWriter writer(result);
    write(writer, status);
}

void
VTimeZone::write(UDate start, UnicodeString& result, UErrorCode& status) /*const*/ {
    result.remove();
    VTZWriter writer(result);
    write(start, writer, status);
}

void
VTimeZone::writeSimple(UDate time, UnicodeString& result, UErrorCode& status) /*const*/ {
    result.remove();
    VTZWriter writer(result);
    writeSimple(time, writer, status);
}

TimeZone*
VTimeZone::clone(void) const {
    return new VTimeZone(*this);
}

int32_t
VTimeZone::getOffset(uint8_t era, int32_t year, int32_t month, int32_t day,
                     uint8_t dayOfWeek, int32_t millis, UErrorCode& status) const {
    return tz->getOffset(era, year, month, day, dayOfWeek, millis, status);
}

int32_t
VTimeZone::getOffset(uint8_t era, int32_t year, int32_t month, int32_t day,
                     uint8_t dayOfWeek, int32_t millis,
                     int32_t monthLength, UErrorCode& status) const {
    return tz->getOffset(era, year, month, day, dayOfWeek, millis, monthLength, status);
}

void
VTimeZone::getOffset(UDate date, UBool local, int32_t& rawOffset,
                     int32_t& dstOffset, UErrorCode& status) const {
    return tz->getOffset(date, local, rawOffset, dstOffset, status);
}

void
VTimeZone::setRawOffset(int32_t offsetMillis) {
    tz->setRawOffset(offsetMillis);
}

int32_t
VTimeZone::getRawOffset(void) const {
    return tz->getRawOffset();
}

UBool
VTimeZone::useDaylightTime(void) const {
    return tz->useDaylightTime();
}

UBool
VTimeZone::inDaylightTime(UDate date, UErrorCode& status) const {
    return tz->inDaylightTime(date, status);
}

UBool
VTimeZone::hasSameRules(const TimeZone& other) const {
    return tz->hasSameRules(other);
}

UBool
VTimeZone::getNextTransition(UDate base, UBool inclusive, TimeZoneTransition& result) /*const*/ {
    return tz->getNextTransition(base, inclusive, result);
}

UBool
VTimeZone::getPreviousTransition(UDate base, UBool inclusive, TimeZoneTransition& result) /*const*/ {
    return tz->getPreviousTransition(base, inclusive, result);
}

int32_t
VTimeZone::countTransitionRules(UErrorCode& status) /*const*/ {
    return tz->countTransitionRules(status);
}

void
VTimeZone::getTimeZoneRules(const InitialTimeZoneRule*& initial,
                            const TimeZoneRule* trsrules[], int32_t& trscount,
                            UErrorCode& status) /*const*/ {
    tz->getTimeZoneRules(initial, trsrules, trscount, status);
}

void
VTimeZone::load(VTZReader& reader, UErrorCode& status) {
    vtzlines = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, DEFAULT_VTIMEZONE_LINES, status);
    if (U_FAILURE(status)) {
        return;
    }
    UBool eol = FALSE;
    UBool start = FALSE;
    UBool success = FALSE;
    UnicodeString line;

    while (TRUE) {
        UChar ch = reader.read();
        if (ch == 0xFFFF) {
            // end of file
            if (start && line.startsWith(ICAL_END_VTIMEZONE, -1)) {
                vtzlines->addElement(new UnicodeString(line), status);
                if (U_FAILURE(status)) {
                    goto cleanupVtzlines;
                }
                success = TRUE;
            }
            break;
        }
        if (ch == 0x000D) {
            // CR, must be followed by LF according to the definition in RFC2445
            continue;
        }
        if (eol) {
            if (ch != 0x0009 && ch != 0x0020) {
                // NOT followed by TAB/SP -> new line
                if (start) {
                    if (line.length() > 0) {
                        vtzlines->addElement(new UnicodeString(line), status);
                        if (U_FAILURE(status)) {
                            goto cleanupVtzlines;
                        }
                    }
                }
                line.remove();
                if (ch != 0x000A) {
                    line.append(ch);
                }
            }
            eol = FALSE;
        } else {
            if (ch == 0x000A) {
                // LF
                eol = TRUE;
                if (start) {
                    if (line.startsWith(ICAL_END_VTIMEZONE, -1)) {
                        vtzlines->addElement(new UnicodeString(line), status);
                        if (U_FAILURE(status)) {
                            goto cleanupVtzlines;
                        }
                        success = TRUE;
                        break;
                    }
                } else {
                    if (line.startsWith(ICAL_BEGIN_VTIMEZONE, -1)) {
                        vtzlines->addElement(new UnicodeString(line), status);
                        if (U_FAILURE(status)) {
                            goto cleanupVtzlines;
                        }
                        line.remove();
                        start = TRUE;
                        eol = FALSE;
                    }
                }
            } else {
                line.append(ch);
            }
        }
    }
    if (!success) {
        if (U_SUCCESS(status)) {
            status = U_INVALID_STATE_ERROR;
        }
        goto cleanupVtzlines;
    }
    parse(status);
    return;

cleanupVtzlines:
    delete vtzlines;
    vtzlines = NULL;
}

// parser state
#define INI 0   // Initial state
#define VTZ 1   // In VTIMEZONE
#define TZI 2   // In STANDARD or DAYLIGHT

#define DEF_DSTSAVINGS (60*60*1000)
#define DEF_TZSTARTTIME (0.0)

void
VTimeZone::parse(UErrorCode& status) {
    if (U_FAILURE(status)) {
        return;
    }
    if (vtzlines == NULL || vtzlines->size() == 0) {
        status = U_INVALID_STATE_ERROR;
        return;
    }
    InitialTimeZoneRule *initialRule = NULL;
    RuleBasedTimeZone *rbtz = NULL;

    // timezone ID
    UnicodeString tzid;

    int32_t state = INI;
    int32_t n = 0;
    UBool dst = FALSE;      // current zone type
    UnicodeString from;     // current zone from offset
    UnicodeString to;       // current zone offset
    UnicodeString zonename;   // current zone name
    UnicodeString dtstart;  // current zone starts
    UBool isRRULE = FALSE;  // true if the rule is described by RRULE
    int32_t initialRawOffset = 0;   // initial offset
    int32_t initialDSTSavings = 0;  // initial offset
    UDate firstStart = MAX_MILLIS;  // the earliest rule start time
    UnicodeString name;     // RFC2445 prop name
    UnicodeString value;    // RFC2445 prop value

    UVector *dates = NULL;  // list of RDATE or RRULE strings
    UVector *rules = NULL;  // list of TimeZoneRule instances

    int32_t finalRuleIdx = -1;
    int32_t finalRuleCount = 0;

    rules = new UVector(status);
    if (U_FAILURE(status)) {
        goto cleanupParse;
    }
     // Set the deleter to remove TimeZoneRule vectors to avoid memory leaks due to unowned TimeZoneRules.
    rules->setDeleter(deleteTimeZoneRule);
    
    dates = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status);
    if (U_FAILURE(status)) {
        goto cleanupParse;
    }
    if (rules == NULL || dates == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        goto cleanupParse;
    }

    for (n = 0; n < vtzlines->size(); n++) {
        UnicodeString *line = (UnicodeString*)vtzlines->elementAt(n);
        int32_t valueSep = line->indexOf(COLON);
        if (valueSep < 0) {
            continue;
        }
        name.setTo(*line, 0, valueSep);
        value.setTo(*line, valueSep + 1);

        switch (state) {
        case INI:
            if (name.compare(ICAL_BEGIN, -1) == 0
                && value.compare(ICAL_VTIMEZONE, -1) == 0) {
                state = VTZ;
            }
            break;

        case VTZ:
            if (name.compare(ICAL_TZID, -1) == 0) {
                tzid = value;
            } else if (name.compare(ICAL_TZURL, -1) == 0) {
                tzurl = value;
            } else if (name.compare(ICAL_LASTMOD, -1) == 0) {
                // Always in 'Z' format, so the offset argument for the parse method
                // can be any value.
                lastmod = parseDateTimeString(value, 0, status);
                if (U_FAILURE(status)) {
                    goto cleanupParse;
                }
            } else if (name.compare(ICAL_BEGIN, -1) == 0) {
                UBool isDST = (value.compare(ICAL_DAYLIGHT, -1) == 0);
                if (value.compare(ICAL_STANDARD, -1) == 0 || isDST) {
                    // tzid must be ready at this point
                    if (tzid.length() == 0) {
                        goto cleanupParse;
                    }
                    // initialize current zone properties
                    if (dates->size() != 0) {
                        dates->removeAllElements();
                    }
                    isRRULE = FALSE;
                    from.remove();
                    to.remove();
                    zonename.remove();
                    dst = isDST;
                    state = TZI;
                } else {
                    // BEGIN property other than STANDARD/DAYLIGHT
                    // must not be there.
                    goto cleanupParse;
                }
            } else if (name.compare(ICAL_END, -1) == 0) {
                break;
            }
            break;
        case TZI:
            if (name.compare(ICAL_DTSTART, -1) == 0) {
                dtstart = value;
            } else if (name.compare(ICAL_TZNAME, -1) == 0) {
                zonename = value;
            } else if (name.compare(ICAL_TZOFFSETFROM, -1) == 0) {
                from = value;
            } else if (name.compare(ICAL_TZOFFSETTO, -1) == 0) {
                to = value;
            } else if (name.compare(ICAL_RDATE, -1) == 0) {
                // RDATE mixed with RRULE is not supported
                if (isRRULE) {
                    goto cleanupParse;
                }
                // RDATE value may contain multiple date delimited
                // by comma
                UBool nextDate = TRUE;
                int32_t dstart = 0;
                UnicodeString *dstr;
                while (nextDate) {
                    int32_t dend = value.indexOf(COMMA, dstart);
                    if (dend == -1) {
                        dstr = new UnicodeString(value, dstart);
                        nextDate = FALSE;
                    } else {
                        dstr = new UnicodeString(value, dstart, dend - dstart);
                    }
                    dates->addElement(dstr, status);
                    if (U_FAILURE(status)) {
                        goto cleanupParse;
                    }
                    dstart = dend + 1;
                }
            } else if (name.compare(ICAL_RRULE, -1) == 0) {
                // RRULE mixed with RDATE is not supported
                if (!isRRULE && dates->size() != 0) {
                    goto cleanupParse;
                }
                isRRULE = true;
                dates->addElement(new UnicodeString(value), status);
                if (U_FAILURE(status)) {
                    goto cleanupParse;
                }
            } else if (name.compare(ICAL_END, -1) == 0) {
                // Mandatory properties
                if (dtstart.length() == 0 || from.length() == 0 || to.length() == 0) {
                    goto cleanupParse;
                }
                // if zonename is not available, create one from tzid
                if (zonename.length() == 0) {
                    getDefaultTZName(tzid, dst, zonename);
                }

                // create a time zone rule
                TimeZoneRule *rule = NULL;
                int32_t fromOffset = 0;
                int32_t toOffset = 0;
                int32_t rawOffset = 0;
                int32_t dstSavings = 0;
                UDate start = 0;

                // Parse TZOFFSETFROM/TZOFFSETTO
                fromOffset = offsetStrToMillis(from, status);
                toOffset = offsetStrToMillis(to, status);
                if (U_FAILURE(status)) {
                    goto cleanupParse;
                }

                if (dst) {
                    // If daylight, use the previous offset as rawoffset if positive
                    if (toOffset - fromOffset > 0) {
                        rawOffset = fromOffset;
                        dstSavings = toOffset - fromOffset;
                    } else {
                        // This is rare case..  just use 1 hour DST savings
                        rawOffset = toOffset - DEF_DSTSAVINGS;
                        dstSavings = DEF_DSTSAVINGS;                                
                    }
                } else {
                    rawOffset = toOffset;
                    dstSavings = 0;
                }

                // start time
                start = parseDateTimeString(dtstart, fromOffset, status);
                if (U_FAILURE(status)) {
                    goto cleanupParse;
                }

                // Create the rule
                UDate actualStart = MAX_MILLIS;
                if (isRRULE) {
                    rule = createRuleByRRULE(zonename, rawOffset, dstSavings, start, dates, fromOffset, status);
                } else {
                    rule = createRuleByRDATE(zonename, rawOffset, dstSavings, start, dates, fromOffset, status);
                }
                if (U_FAILURE(status) || rule == NULL) {
                    goto cleanupParse;
                } else {
                    UBool startAvail = rule->getFirstStart(fromOffset, 0, actualStart);
                    if (startAvail && actualStart < firstStart) {
                        // save from offset information for the earliest rule
                        firstStart = actualStart;
                        // If this is STD, assume the time before this transtion
                        // is DST when the difference is 1 hour.  This might not be
                        // accurate, but VTIMEZONE data does not have such info.
                        if (dstSavings > 0) {
                            initialRawOffset = fromOffset;
                            initialDSTSavings = 0;
                        } else {
                            if (fromOffset - toOffset == DEF_DSTSAVINGS) {
                                initialRawOffset = fromOffset - DEF_DSTSAVINGS;
                                initialDSTSavings = DEF_DSTSAVINGS;
                            } else {
                                initialRawOffset = fromOffset;
                                initialDSTSavings = 0;
                            }
                        }
                    }
                }
                rules->addElement(rule, status);
                if (U_FAILURE(status)) {
                    goto cleanupParse;
                }
                state = VTZ;
            }
            break;
        }
    }
    // Must have at least one rule
    if (rules->size() == 0) {
        goto cleanupParse;
    }

    // Create a initial rule
    getDefaultTZName(tzid, FALSE, zonename);
    initialRule = new InitialTimeZoneRule(zonename,
        initialRawOffset, initialDSTSavings);
    if (initialRule == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        goto cleanupParse;
    }

    // Finally, create the RuleBasedTimeZone
    rbtz = new RuleBasedTimeZone(tzid, initialRule);
    if (rbtz == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
        goto cleanupParse;
    }
    initialRule = NULL; // already adopted by RBTZ, no need to delete

    for (n = 0; n < rules->size(); n++) {
        TimeZoneRule *r = (TimeZoneRule*)rules->elementAt(n);
        AnnualTimeZoneRule *atzrule = dynamic_cast<AnnualTimeZoneRule *>(r);
        if (atzrule != NULL) {
            if (atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
                finalRuleCount++;
                finalRuleIdx = n;
            }
        }
    }
    if (finalRuleCount > 2) {
        // Too many final rules
        status = U_ILLEGAL_ARGUMENT_ERROR;
        goto cleanupParse;
    }

    if (finalRuleCount == 1) {
        if (rules->size() == 1) {
            // Only one final rule, only governs the initial rule,
            // which is already initialized, thus, we do not need to
            // add this transition rule
            rules->removeAllElements();
        } else {
            // Normalize the final rule
            AnnualTimeZoneRule *finalRule = (AnnualTimeZoneRule*)rules->elementAt(finalRuleIdx);
            int32_t tmpRaw = finalRule->getRawOffset();
            int32_t tmpDST = finalRule->getDSTSavings();

            // Find the last non-final rule
            UDate finalStart, start;
            finalRule->getFirstStart(initialRawOffset, initialDSTSavings, finalStart);
            start = finalStart;
            for (n = 0; n < rules->size(); n++) {
                if (finalRuleIdx == n) {
                    continue;
                }
                TimeZoneRule *r = (TimeZoneRule*)rules->elementAt(n);
                UDate lastStart;
                r->getFinalStart(tmpRaw, tmpDST, lastStart);
                if (lastStart > start) {
                    finalRule->getNextStart(lastStart,
                        r->getRawOffset(),
                        r->getDSTSavings(),
                        FALSE,
                        start);
                }
            }

            TimeZoneRule *newRule;
            UnicodeString tznam;
            if (start == finalStart) {
                // Transform this into a single transition
                newRule = new TimeArrayTimeZoneRule(
                        finalRule->getName(tznam),
                        finalRule->getRawOffset(),
                        finalRule->getDSTSavings(),
                        &finalStart,
                        1,
                        DateTimeRule::UTC_TIME);
            } else {
                // Update the end year
                int32_t y, m, d, dow, doy, mid;
                Grego::timeToFields(start, y, m, d, dow, doy, mid);
                newRule = new AnnualTimeZoneRule(
                        finalRule->getName(tznam),
                        finalRule->getRawOffset(),
                        finalRule->getDSTSavings(),
                        *(finalRule->getRule()),
                        finalRule->getStartYear(),
                        y);
            }
            if (newRule == NULL) {
                status = U_MEMORY_ALLOCATION_ERROR;
                goto cleanupParse;
            }
            rules->removeElementAt(finalRuleIdx);
            rules->addElement(newRule, status);
            if (U_FAILURE(status)) {
                delete newRule;
                goto cleanupParse;
            }
        }
    }

    while (!rules->isEmpty()) {
        TimeZoneRule *tzr = (TimeZoneRule*)rules->orphanElementAt(0);
        rbtz->addTransitionRule(tzr, status);
        if (U_FAILURE(status)) {
            goto cleanupParse;
        }
    }
    rbtz->complete(status);
    if (U_FAILURE(status)) {
        goto cleanupParse;
    }
    delete rules;
    delete dates;

    tz = rbtz;
    setID(tzid);
    return;

cleanupParse:
    if (rules != NULL) {
        while (!rules->isEmpty()) {
            TimeZoneRule *r = (TimeZoneRule*)rules->orphanElementAt(0);
            delete r;
        }
        delete rules;
    }
    if (dates != NULL) {
        delete dates;
    }
    if (initialRule != NULL) {
        delete initialRule;
    }
    if (rbtz != NULL) {
        delete rbtz;
    }
    return;
}

void
VTimeZone::write(VTZWriter& writer, UErrorCode& status) const {
    if (vtzlines != NULL) {
        for (int32_t i = 0; i < vtzlines->size(); i++) {
            UnicodeString *line = (UnicodeString*)vtzlines->elementAt(i);
            if (line->startsWith(ICAL_TZURL, -1)
                && line->charAt(u_strlen(ICAL_TZURL)) == COLON) {
                writer.write(ICAL_TZURL);
                writer.write(COLON);
                writer.write(tzurl);
                writer.write(ICAL_NEWLINE);
            } else if (line->startsWith(ICAL_LASTMOD, -1)
                && line->charAt(u_strlen(ICAL_LASTMOD)) == COLON) {
                UnicodeString utcString;
                writer.write(ICAL_LASTMOD);
                writer.write(COLON);
                writer.write(getUTCDateTimeString(lastmod, utcString));
                writer.write(ICAL_NEWLINE);
            } else {
                writer.write(*line);
                writer.write(ICAL_NEWLINE);
            }
        }
    } else {
        UVector *customProps = NULL;
        if (olsonzid.length() > 0 && icutzver.length() > 0) {
            customProps = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status);
            if (U_FAILURE(status)) {
                return;
            }
            UnicodeString *icutzprop = new UnicodeString(ICU_TZINFO_PROP);
            icutzprop->append(olsonzid);
            icutzprop->append((UChar)0x005B/*'['*/);
            icutzprop->append(icutzver);
            icutzprop->append((UChar)0x005D/*']'*/);
            customProps->addElement(icutzprop, status);
            if (U_FAILURE(status)) {
                delete icutzprop;
                delete customProps;
                return;
            }
        }
        writeZone(writer, *tz, customProps, status);
        delete customProps;
    }
}

void
VTimeZone::write(UDate start, VTZWriter& writer, UErrorCode& status) /*const*/ {
    if (U_FAILURE(status)) {
        return;
    }
    InitialTimeZoneRule *initial = NULL;
    UVector *transitionRules = NULL;
    UVector customProps(uprv_deleteUObject, uhash_compareUnicodeString, status);
    UnicodeString tzid;

    // Extract rules applicable to dates after the start time
    getTimeZoneRulesAfter(start, initial, transitionRules, status);
    if (U_FAILURE(status)) {
        return;
    }

    // Create a RuleBasedTimeZone with the subset rule
    getID(tzid);
    RuleBasedTimeZone rbtz(tzid, initial);
    if (transitionRules != NULL) {
        while (!transitionRules->isEmpty()) {
            TimeZoneRule *tr = (TimeZoneRule*)transitionRules->orphanElementAt(0);
            rbtz.addTransitionRule(tr, status);
            if (U_FAILURE(status)) {
                goto cleanupWritePartial;
            }
        }
        delete transitionRules;
        transitionRules = NULL;
    }
    rbtz.complete(status);
    if (U_FAILURE(status)) {
        goto cleanupWritePartial;
    }

    if (olsonzid.length() > 0 && icutzver.length() > 0) {
        UnicodeString *icutzprop = new UnicodeString(ICU_TZINFO_PROP);
        icutzprop->append(olsonzid);
        icutzprop->append((UChar)0x005B/*'['*/);
        icutzprop->append(icutzver);
        icutzprop->append(ICU_TZINFO_PARTIAL, -1);
        appendMillis(start, *icutzprop);
        icutzprop->append((UChar)0x005D/*']'*/);
        customProps.addElement(icutzprop, status);
        if (U_FAILURE(status)) {
            delete icutzprop;
            goto cleanupWritePartial;
        }
    }
    writeZone(writer, rbtz, &customProps, status);
    return;

cleanupWritePartial:
    if (initial != NULL) {
        delete initial;
    }
    if (transitionRules != NULL) {
        while (!transitionRules->isEmpty()) {
            TimeZoneRule *tr = (TimeZoneRule*)transitionRules->orphanElementAt(0);
            delete tr;
        }
        delete transitionRules;
    }
}

void
VTimeZone::writeSimple(UDate time, VTZWriter& writer, UErrorCode& status) /*const*/ {
    if (U_FAILURE(status)) {
        return;
    }

    UVector customProps(uprv_deleteUObject, uhash_compareUnicodeString, status);
    UnicodeString tzid;

    // Extract simple rules
    InitialTimeZoneRule *initial = NULL;
    AnnualTimeZoneRule *std = NULL, *dst = NULL;
    getSimpleRulesNear(time, initial, std, dst, status);
    if (U_SUCCESS(status)) {
        // Create a RuleBasedTimeZone with the subset rule
        getID(tzid);
        RuleBasedTimeZone rbtz(tzid, initial);
        if (std != NULL && dst != NULL) {
            rbtz.addTransitionRule(std, status);
            rbtz.addTransitionRule(dst, status);
        }
        if (U_FAILURE(status)) {
            goto cleanupWriteSimple;
        }

        if (olsonzid.length() > 0 && icutzver.length() > 0) {
            UnicodeString *icutzprop = new UnicodeString(ICU_TZINFO_PROP);
            icutzprop->append(olsonzid);
            icutzprop->append((UChar)0x005B/*'['*/);
            icutzprop->append(icutzver);
            icutzprop->append(ICU_TZINFO_SIMPLE, -1);
            appendMillis(time, *icutzprop);
            icutzprop->append((UChar)0x005D/*']'*/);
            customProps.addElement(icutzprop, status);
            if (U_FAILURE(status)) {
                delete icutzprop;
                goto cleanupWriteSimple;
            }
        }
        writeZone(writer, rbtz, &customProps, status);
    }
    return;

cleanupWriteSimple:
    if (initial != NULL) {
        delete initial;
    }
    if (std != NULL) {
        delete std;
    }
    if (dst != NULL) {
        delete dst;
    }
}

void
VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz,
                     UVector* customProps, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    writeHeaders(w, status);
    if (U_FAILURE(status)) {
        return;
    }

    if (customProps != NULL) {
        for (int32_t i = 0; i < customProps->size(); i++) {
            UnicodeString *custprop = (UnicodeString*)customProps->elementAt(i);
            w.write(*custprop);
            w.write(ICAL_NEWLINE);
        }
    }

    UDate t = MIN_MILLIS;
    UnicodeString dstName;
    int32_t dstFromOffset = 0;
    int32_t dstFromDSTSavings = 0;
    int32_t dstToOffset = 0;
    int32_t dstStartYear = 0;
    int32_t dstMonth = 0;
    int32_t dstDayOfWeek = 0;
    int32_t dstWeekInMonth = 0;
    int32_t dstMillisInDay = 0;
    UDate dstStartTime = 0.0;
    UDate dstUntilTime = 0.0;
    int32_t dstCount = 0;
    AnnualTimeZoneRule *finalDstRule = NULL;

    UnicodeString stdName;
    int32_t stdFromOffset = 0;
    int32_t stdFromDSTSavings = 0;
    int32_t stdToOffset = 0;
    int32_t stdStartYear = 0;
    int32_t stdMonth = 0;
    int32_t stdDayOfWeek = 0;
    int32_t stdWeekInMonth = 0;
    int32_t stdMillisInDay = 0;
    UDate stdStartTime = 0.0;
    UDate stdUntilTime = 0.0;
    int32_t stdCount = 0;
    AnnualTimeZoneRule *finalStdRule = NULL;

    int32_t year, month, dom, dow, doy, mid;
    UBool hasTransitions = FALSE;
    TimeZoneTransition tzt;
    UBool tztAvail;
    UnicodeString name;
    UBool isDst;

    // Going through all transitions
    while (TRUE) {
        tztAvail = basictz.getNextTransition(t, FALSE, tzt);
        if (!tztAvail) {
            break;
        }
        hasTransitions = TRUE;
        t = tzt.getTime();
        tzt.getTo()->getName(name);
        isDst = (tzt.getTo()->getDSTSavings() != 0);
        int32_t fromOffset = tzt.getFrom()->getRawOffset() + tzt.getFrom()->getDSTSavings();
        int32_t fromDSTSavings = tzt.getFrom()->getDSTSavings();
        int32_t toOffset = tzt.getTo()->getRawOffset() + tzt.getTo()->getDSTSavings();
        Grego::timeToFields(tzt.getTime() + fromOffset, year, month, dom, dow, doy, mid);
        int32_t weekInMonth = Grego::dayOfWeekInMonth(year, month, dom);
        UBool sameRule = FALSE;
        const AnnualTimeZoneRule *atzrule;
        if (isDst) {
            if (finalDstRule == NULL
                && (atzrule = dynamic_cast<const AnnualTimeZoneRule *>(tzt.getTo())) != NULL
                && atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR
            ) {
                finalDstRule = (AnnualTimeZoneRule*)tzt.getTo()->clone();
            }
            if (dstCount > 0) {
                if (year == dstStartYear + dstCount
                        && name.compare(dstName) == 0
                        && dstFromOffset == fromOffset
                        && dstToOffset == toOffset
                        && dstMonth == month
                        && dstDayOfWeek == dow
                        && dstWeekInMonth == weekInMonth
                        && dstMillisInDay == mid) {
                    // Update until time
                    dstUntilTime = t;
                    dstCount++;
                    sameRule = TRUE;
                }
                if (!sameRule) {
                    if (dstCount == 1) {
                        writeZonePropsByTime(w, TRUE, dstName, dstFromOffset, dstToOffset, dstStartTime,
                                TRUE, status);
                    } else {
                        writeZonePropsByDOW(w, TRUE, dstName, dstFromOffset, dstToOffset,
                                dstMonth, dstWeekInMonth, dstDayOfWeek, dstStartTime, dstUntilTime, status);
                    }
                    if (U_FAILURE(status)) {
                        goto cleanupWriteZone;
                    }
                }
            } 
            if (!sameRule) {
                // Reset this DST information
                dstName = name;
                dstFromOffset = fromOffset;
                dstFromDSTSavings = fromDSTSavings;
                dstToOffset = toOffset;
                dstStartYear = year;
                dstMonth = month;
                dstDayOfWeek = dow;
                dstWeekInMonth = weekInMonth;
                dstMillisInDay = mid;
                dstStartTime = dstUntilTime = t;
                dstCount = 1;
            }
            if (finalStdRule != NULL && finalDstRule != NULL) {
                break;
            }
        } else {
            if (finalStdRule == NULL
                && (atzrule = dynamic_cast<const AnnualTimeZoneRule *>(tzt.getTo())) != NULL
                && atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR
            ) {
                finalStdRule = (AnnualTimeZoneRule*)tzt.getTo()->clone();
            }
            if (stdCount > 0) {
                if (year == stdStartYear + stdCount
                        && name.compare(stdName) == 0
                        && stdFromOffset == fromOffset
                        && stdToOffset == toOffset
                        && stdMonth == month
                        && stdDayOfWeek == dow
                        && stdWeekInMonth == weekInMonth
                        && stdMillisInDay == mid) {
                    // Update until time
                    stdUntilTime = t;
                    stdCount++;
                    sameRule = TRUE;
                }
                if (!sameRule) {
                    if (stdCount == 1) {
                        writeZonePropsByTime(w, FALSE, stdName, stdFromOffset, stdToOffset, stdStartTime,
                                TRUE, status);
                    } else {
                        writeZonePropsByDOW(w, FALSE, stdName, stdFromOffset, stdToOffset,
                                stdMonth, stdWeekInMonth, stdDayOfWeek, stdStartTime, stdUntilTime, status);
                    }
                    if (U_FAILURE(status)) {
                        goto cleanupWriteZone;
                    }
                }
            }
            if (!sameRule) {
                // Reset this STD information
                stdName = name;
                stdFromOffset = fromOffset;
                stdFromDSTSavings = fromDSTSavings;
                stdToOffset = toOffset;
                stdStartYear = year;
                stdMonth = month;
                stdDayOfWeek = dow;
                stdWeekInMonth = weekInMonth;
                stdMillisInDay = mid;
                stdStartTime = stdUntilTime = t;
                stdCount = 1;
            }
            if (finalStdRule != NULL && finalDstRule != NULL) {
                break;
            }
        }
    }
    if (!hasTransitions) {
        // No transition - put a single non transition RDATE
        int32_t raw, dst, offset;
        basictz.getOffset(0.0/*any time*/, FALSE, raw, dst, status);
        if (U_FAILURE(status)) {
            goto cleanupWriteZone;
        }
        offset = raw + dst;
        isDst = (dst != 0);
        UnicodeString tzid;
        basictz.getID(tzid);
        getDefaultTZName(tzid, isDst, name);        
        writeZonePropsByTime(w, isDst, name,
                offset, offset, DEF_TZSTARTTIME - offset, FALSE, status);    
        if (U_FAILURE(status)) {
            goto cleanupWriteZone;
        }
    } else {
        if (dstCount > 0) {
            if (finalDstRule == NULL) {
                if (dstCount == 1) {
                    writeZonePropsByTime(w, TRUE, dstName, dstFromOffset, dstToOffset, dstStartTime,
                            TRUE, status);
                } else {
                    writeZonePropsByDOW(w, TRUE, dstName, dstFromOffset, dstToOffset,
                            dstMonth, dstWeekInMonth, dstDayOfWeek, dstStartTime, dstUntilTime, status);
                }
                if (U_FAILURE(status)) {
                    goto cleanupWriteZone;
                }
            } else {
                if (dstCount == 1) {
                    writeFinalRule(w, TRUE, finalDstRule,
                            dstFromOffset - dstFromDSTSavings, dstFromDSTSavings, dstStartTime, status);
                } else {
                    // Use a single rule if possible
                    if (isEquivalentDateRule(dstMonth, dstWeekInMonth, dstDayOfWeek, finalDstRule->getRule())) {
                        writeZonePropsByDOW(w, TRUE, dstName, dstFromOffset, dstToOffset,
                                dstMonth, dstWeekInMonth, dstDayOfWeek, dstStartTime, MAX_MILLIS, status);
                    } else {
                        // Not equivalent rule - write out two different rules
                        writeZonePropsByDOW(w, TRUE, dstName, dstFromOffset, dstToOffset,
                                dstMonth, dstWeekInMonth, dstDayOfWeek, dstStartTime, dstUntilTime, status);
                        if (U_FAILURE(status)) {
                            goto cleanupWriteZone;
                        }
                        writeFinalRule(w, TRUE, finalDstRule,
                                dstFromOffset - dstFromDSTSavings, dstFromDSTSavings, dstStartTime, status);
                    }
                }
                if (U_FAILURE(status)) {
                    goto cleanupWriteZone;
                }
            }
        }
        if (stdCount > 0) {
            if (finalStdRule == NULL) {
                if (stdCount == 1) {
                    writeZonePropsByTime(w, FALSE, stdName, stdFromOffset, stdToOffset, stdStartTime,
                            TRUE, status);
                } else {
                    writeZonePropsByDOW(w, FALSE, stdName, stdFromOffset, stdToOffset,
                            stdMonth, stdWeekInMonth, stdDayOfWeek, stdStartTime, stdUntilTime, status);
                }
                if (U_FAILURE(status)) {
                    goto cleanupWriteZone;
                }
            } else {
                if (stdCount == 1) {
                    writeFinalRule(w, FALSE, finalStdRule,
                            stdFromOffset - stdFromDSTSavings, stdFromDSTSavings, stdStartTime, status);
                } else {
                    // Use a single rule if possible
                    if (isEquivalentDateRule(stdMonth, stdWeekInMonth, stdDayOfWeek, finalStdRule->getRule())) {
                        writeZonePropsByDOW(w, FALSE, stdName, stdFromOffset, stdToOffset,
                                stdMonth, stdWeekInMonth, stdDayOfWeek, stdStartTime, MAX_MILLIS, status);                            
                    } else {
                        // Not equivalent rule - write out two different rules
                        writeZonePropsByDOW(w, FALSE, stdName, stdFromOffset, stdToOffset,
                                stdMonth, stdWeekInMonth, stdDayOfWeek, stdStartTime, stdUntilTime, status);
                        if (U_FAILURE(status)) {
                            goto cleanupWriteZone;
                        }
                        writeFinalRule(w, FALSE, finalStdRule,
                                stdFromOffset - stdFromDSTSavings, stdFromDSTSavings, stdStartTime, status);
                    }
                }
                if (U_FAILURE(status)) {
                    goto cleanupWriteZone;
                }
            }
        }            
    }
    writeFooter(w, status);

cleanupWriteZone:

    if (finalStdRule != NULL) {
        delete finalStdRule;
    }
    if (finalDstRule != NULL) {
        delete finalDstRule;
    }
}

void
VTimeZone::writeHeaders(VTZWriter& writer, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    UnicodeString tzid;
    tz->getID(tzid);

    writer.write(ICAL_BEGIN);
    writer.write(COLON);
    writer.write(ICAL_VTIMEZONE);
    writer.write(ICAL_NEWLINE);
    writer.write(ICAL_TZID);
    writer.write(COLON);
    writer.write(tzid);
    writer.write(ICAL_NEWLINE);
    if (tzurl.length() != 0) {
        writer.write(ICAL_TZURL);
        writer.write(COLON);
        writer.write(tzurl);
        writer.write(ICAL_NEWLINE);
    }
    if (lastmod != MAX_MILLIS) {
        UnicodeString lastmodStr;
        writer.write(ICAL_LASTMOD);
        writer.write(COLON);
        writer.write(getUTCDateTimeString(lastmod, lastmodStr));
        writer.write(ICAL_NEWLINE);
    }
}

/*
 * Write the closing section of the VTIMEZONE definition block
 */
void
VTimeZone::writeFooter(VTZWriter& writer, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    writer.write(ICAL_END);
    writer.write(COLON);
    writer.write(ICAL_VTIMEZONE);
    writer.write(ICAL_NEWLINE);
}

/*
 * Write a single start time
 */
void
VTimeZone::writeZonePropsByTime(VTZWriter& writer, UBool isDst, const UnicodeString& zonename,
                                int32_t fromOffset, int32_t toOffset, UDate time, UBool withRDATE,
                                UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    beginZoneProps(writer, isDst, zonename, fromOffset, toOffset, time, status);
    if (U_FAILURE(status)) {
        return;
    }
    if (withRDATE) {
        writer.write(ICAL_RDATE);
        writer.write(COLON);
        UnicodeString timestr;
        writer.write(getDateTimeString(time + fromOffset, timestr));
        writer.write(ICAL_NEWLINE);
    }
    endZoneProps(writer, isDst, status);
    if (U_FAILURE(status)) {
        return;
    }
}

/*
 * Write start times defined by a DOM rule using VTIMEZONE RRULE
 */
void
VTimeZone::writeZonePropsByDOM(VTZWriter& writer, UBool isDst, const UnicodeString& zonename,
                               int32_t fromOffset, int32_t toOffset,
                               int32_t month, int32_t dayOfMonth, UDate startTime, UDate untilTime,
                               UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    beginZoneProps(writer, isDst, zonename, fromOffset, toOffset, startTime, status);
    if (U_FAILURE(status)) {
        return;
    }
    beginRRULE(writer, month, status);
    if (U_FAILURE(status)) {
        return;
    }
    writer.write(ICAL_BYMONTHDAY);
    writer.write(EQUALS_SIGN);
    UnicodeString dstr;
    appendAsciiDigits(dayOfMonth, 0, dstr);
    writer.write(dstr);
    if (untilTime != MAX_MILLIS) {
        appendUNTIL(writer, getDateTimeString(untilTime + fromOffset, dstr), status);
        if (U_FAILURE(status)) {
            return;
        }
    }
    writer.write(ICAL_NEWLINE);
    endZoneProps(writer, isDst, status);
}

/*
 * Write start times defined by a DOW rule using VTIMEZONE RRULE
 */
void
VTimeZone::writeZonePropsByDOW(VTZWriter& writer, UBool isDst, const UnicodeString& zonename,
                               int32_t fromOffset, int32_t toOffset,
                               int32_t month, int32_t weekInMonth, int32_t dayOfWeek,
                               UDate startTime, UDate untilTime, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    beginZoneProps(writer, isDst, zonename, fromOffset, toOffset, startTime, status);
    if (U_FAILURE(status)) {
        return;
    }
    beginRRULE(writer, month, status);
    if (U_FAILURE(status)) {
        return;
    }
    writer.write(ICAL_BYDAY);
    writer.write(EQUALS_SIGN);
    UnicodeString dstr;
    appendAsciiDigits(weekInMonth, 0, dstr);
    writer.write(dstr);    // -4, -3, -2, -1, 1, 2, 3, 4
    writer.write(ICAL_DOW_NAMES[dayOfWeek - 1]);    // SU, MO, TU...

    if (untilTime != MAX_MILLIS) {
        appendUNTIL(writer, getDateTimeString(untilTime + fromOffset, dstr), status);
        if (U_FAILURE(status)) {
            return;
        }
    }
    writer.write(ICAL_NEWLINE);
    endZoneProps(writer, isDst, status);
}

/*
 * Write start times defined by a DOW_GEQ_DOM rule using VTIMEZONE RRULE
 */
void
VTimeZone::writeZonePropsByDOW_GEQ_DOM(VTZWriter& writer, UBool isDst, const UnicodeString& zonename,
                                       int32_t fromOffset, int32_t toOffset,
                                       int32_t month, int32_t dayOfMonth, int32_t dayOfWeek,
                                       UDate startTime, UDate untilTime, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    // Check if this rule can be converted to DOW rule
    if (dayOfMonth%7 == 1) {
        // Can be represented by DOW rule
        writeZonePropsByDOW(writer, isDst, zonename, fromOffset, toOffset,
                month, (dayOfMonth + 6)/7, dayOfWeek, startTime, untilTime, status);
        if (U_FAILURE(status)) {
            return;
        }
    } else if (month != UCAL_FEBRUARY && (MONTHLENGTH[month] - dayOfMonth)%7 == 6) {
        // Can be represented by DOW rule with negative week number
        writeZonePropsByDOW(writer, isDst, zonename, fromOffset, toOffset,
                month, -1*((MONTHLENGTH[month] - dayOfMonth + 1)/7), dayOfWeek, startTime, untilTime, status);
        if (U_FAILURE(status)) {
            return;
        }
    } else {
        // Otherwise, use BYMONTHDAY to include all possible dates
        beginZoneProps(writer, isDst, zonename, fromOffset, toOffset, startTime, status);
        if (U_FAILURE(status)) {
            return;
        }
        // Check if all days are in the same month
        int32_t startDay = dayOfMonth;
        int32_t currentMonthDays = 7;
    
        if (dayOfMonth <= 0) {
            // The start day is in previous month
            int32_t prevMonthDays = 1 - dayOfMonth;
            currentMonthDays -= prevMonthDays;

            int32_t prevMonth = (month - 1) < 0 ? 11 : month - 1;

            // Note: When a rule is separated into two, UNTIL attribute needs to be
            // calculated for each of them.  For now, we skip this, because we basically use this method
            // only for final rules, which does not have the UNTIL attribute
            writeZonePropsByDOW_GEQ_DOM_sub(writer, prevMonth, -prevMonthDays, dayOfWeek, prevMonthDays,
                MAX_MILLIS /* Do not use UNTIL */, fromOffset, status);
            if (U_FAILURE(status)) {
                return;
            }

            // Start from 1 for the rest
            startDay = 1;
        } else if (dayOfMonth + 6 > MONTHLENGTH[month]) {
            // Note: This code does not actually work well in February.  For now, days in month in
            // non-leap year.
            int32_t nextMonthDays = dayOfMonth + 6 - MONTHLENGTH[month];
            currentMonthDays -= nextMonthDays;

            int32_t nextMonth = (month + 1) > 11 ? 0 : month + 1;
            
            writeZonePropsByDOW_GEQ_DOM_sub(writer, nextMonth, 1, dayOfWeek, nextMonthDays,
                MAX_MILLIS /* Do not use UNTIL */, fromOffset, status);
            if (U_FAILURE(status)) {
                return;
            }
        }
        writeZonePropsByDOW_GEQ_DOM_sub(writer, month, startDay, dayOfWeek, currentMonthDays,
            untilTime, fromOffset, status);
        if (U_FAILURE(status)) {
            return;
        }
        endZoneProps(writer, isDst, status);
    }
}

/*
 * Called from writeZonePropsByDOW_GEQ_DOM
 */
void
VTimeZone::writeZonePropsByDOW_GEQ_DOM_sub(VTZWriter& writer, int32_t month, int32_t dayOfMonth,
                                           int32_t dayOfWeek, int32_t numDays,
                                           UDate untilTime, int32_t fromOffset, UErrorCode& status) const {

    if (U_FAILURE(status)) {
        return;
    }
    int32_t startDayNum = dayOfMonth;
    UBool isFeb = (month == UCAL_FEBRUARY);
    if (dayOfMonth < 0 && !isFeb) {
        // Use positive number if possible
        startDayNum = MONTHLENGTH[month] + dayOfMonth + 1;
    }
    beginRRULE(writer, month, status);
    if (U_FAILURE(status)) {
        return;
    }
    writer.write(ICAL_BYDAY);
    writer.write(EQUALS_SIGN);
    writer.write(ICAL_DOW_NAMES[dayOfWeek - 1]);    // SU, MO, TU...
    writer.write(SEMICOLON);
    writer.write(ICAL_BYMONTHDAY);
    writer.write(EQUALS_SIGN);

    UnicodeString dstr;
    appendAsciiDigits(startDayNum, 0, dstr);
    writer.write(dstr);
    for (int32_t i = 1; i < numDays; i++) {
        writer.write(COMMA);
        dstr.remove();
        appendAsciiDigits(startDayNum + i, 0, dstr);
        writer.write(dstr);
    }

    if (untilTime != MAX_MILLIS) {
        appendUNTIL(writer, getDateTimeString(untilTime + fromOffset, dstr), status);
        if (U_FAILURE(status)) {
            return;
        }
    }
    writer.write(ICAL_NEWLINE);
}

/*
 * Write start times defined by a DOW_LEQ_DOM rule using VTIMEZONE RRULE
 */
void
VTimeZone::writeZonePropsByDOW_LEQ_DOM(VTZWriter& writer, UBool isDst, const UnicodeString& zonename,
                                       int32_t fromOffset, int32_t toOffset,
                                       int32_t month, int32_t dayOfMonth, int32_t dayOfWeek,
                                       UDate startTime, UDate untilTime, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    // Check if this rule can be converted to DOW rule
    if (dayOfMonth%7 == 0) {
        // Can be represented by DOW rule
        writeZonePropsByDOW(writer, isDst, zonename, fromOffset, toOffset,
                month, dayOfMonth/7, dayOfWeek, startTime, untilTime, status);
    } else if (month != UCAL_FEBRUARY && (MONTHLENGTH[month] - dayOfMonth)%7 == 0){
        // Can be represented by DOW rule with negative week number
        writeZonePropsByDOW(writer, isDst, zonename, fromOffset, toOffset,
                month, -1*((MONTHLENGTH[month] - dayOfMonth)/7 + 1), dayOfWeek, startTime, untilTime, status);
    } else if (month == UCAL_FEBRUARY && dayOfMonth == 29) {
        // Specical case for February
        writeZonePropsByDOW(writer, isDst, zonename, fromOffset, toOffset,
                UCAL_FEBRUARY, -1, dayOfWeek, startTime, untilTime, status);
    } else {
        // Otherwise, convert this to DOW_GEQ_DOM rule
        writeZonePropsByDOW_GEQ_DOM(writer, isDst, zonename, fromOffset, toOffset,
                month, dayOfMonth - 6, dayOfWeek, startTime, untilTime, status);
    }
}

/*
 * Write the final time zone rule using RRULE, with no UNTIL attribute
 */
void
VTimeZone::writeFinalRule(VTZWriter& writer, UBool isDst, const AnnualTimeZoneRule* rule,
                          int32_t fromRawOffset, int32_t fromDSTSavings,
                          UDate startTime, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    UBool modifiedRule = TRUE;
    const DateTimeRule *dtrule = toWallTimeRule(rule->getRule(), fromRawOffset, fromDSTSavings);
    if (dtrule == NULL) {
        modifiedRule = FALSE;
        dtrule = rule->getRule();
    }

    // If the rule's mills in a day is out of range, adjust start time.
    // Olson tzdata supports 24:00 of a day, but VTIMEZONE does not.
    // See ticket#7008/#7518

    int32_t timeInDay = dtrule->getRuleMillisInDay();
    if (timeInDay < 0) {
        startTime = startTime + (0 - timeInDay);
    } else if (timeInDay >= U_MILLIS_PER_DAY) {
        startTime = startTime - (timeInDay - (U_MILLIS_PER_DAY - 1));
    }

    int32_t toOffset = rule->getRawOffset() + rule->getDSTSavings();
    UnicodeString name;
    rule->getName(name);
    switch (dtrule->getDateRuleType()) {
    case DateTimeRule::DOM:
        writeZonePropsByDOM(writer, isDst, name, fromRawOffset + fromDSTSavings, toOffset,
                dtrule->getRuleMonth(), dtrule->getRuleDayOfMonth(), startTime, MAX_MILLIS, status);
        break;
    case DateTimeRule::DOW:
        writeZonePropsByDOW(writer, isDst, name, fromRawOffset + fromDSTSavings, toOffset,
                dtrule->getRuleMonth(), dtrule->getRuleWeekInMonth(), dtrule->getRuleDayOfWeek(), startTime, MAX_MILLIS, status);
        break;
    case DateTimeRule::DOW_GEQ_DOM:
        writeZonePropsByDOW_GEQ_DOM(writer, isDst, name, fromRawOffset + fromDSTSavings, toOffset,
                dtrule->getRuleMonth(), dtrule->getRuleDayOfMonth(), dtrule->getRuleDayOfWeek(), startTime, MAX_MILLIS, status);
        break;
    case DateTimeRule::DOW_LEQ_DOM:
        writeZonePropsByDOW_LEQ_DOM(writer, isDst, name, fromRawOffset + fromDSTSavings, toOffset,
                dtrule->getRuleMonth(), dtrule->getRuleDayOfMonth(), dtrule->getRuleDayOfWeek(), startTime, MAX_MILLIS, status);
        break;
    }
    if (modifiedRule) {
        delete dtrule;
    }
}

/*
 * Write the opening section of zone properties
 */
void
VTimeZone::beginZoneProps(VTZWriter& writer, UBool isDst, const UnicodeString& zonename,
                          int32_t fromOffset, int32_t toOffset, UDate startTime, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    writer.write(ICAL_BEGIN);
    writer.write(COLON);
    if (isDst) {
        writer.write(ICAL_DAYLIGHT);
    } else {
        writer.write(ICAL_STANDARD);
    }
    writer.write(ICAL_NEWLINE);

    UnicodeString dstr;

    // TZOFFSETTO
    writer.write(ICAL_TZOFFSETTO);
    writer.write(COLON);
    millisToOffset(toOffset, dstr);
    writer.write(dstr);
    writer.write(ICAL_NEWLINE);

    // TZOFFSETFROM
    writer.write(ICAL_TZOFFSETFROM);
    writer.write(COLON);
    millisToOffset(fromOffset, dstr);
    writer.write(dstr);
    writer.write(ICAL_NEWLINE);

    // TZNAME
    writer.write(ICAL_TZNAME);
    writer.write(COLON);
    writer.write(zonename);
    writer.write(ICAL_NEWLINE);
    
    // DTSTART
    writer.write(ICAL_DTSTART);
    writer.write(COLON);
    writer.write(getDateTimeString(startTime + fromOffset, dstr));
    writer.write(ICAL_NEWLINE);        
}

/*
 * Writes the closing section of zone properties
 */
void
VTimeZone::endZoneProps(VTZWriter& writer, UBool isDst, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    // END:STANDARD or END:DAYLIGHT
    writer.write(ICAL_END);
    writer.write(COLON);
    if (isDst) {
        writer.write(ICAL_DAYLIGHT);
    } else {
        writer.write(ICAL_STANDARD);
    }
    writer.write(ICAL_NEWLINE);
}

/*
 * Write the beggining part of RRULE line
 */
void
VTimeZone::beginRRULE(VTZWriter& writer, int32_t month, UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    UnicodeString dstr;
    writer.write(ICAL_RRULE);
    writer.write(COLON);
    writer.write(ICAL_FREQ);
    writer.write(EQUALS_SIGN);
    writer.write(ICAL_YEARLY);
    writer.write(SEMICOLON);
    writer.write(ICAL_BYMONTH);
    writer.write(EQUALS_SIGN);
    appendAsciiDigits(month + 1, 0, dstr);
    writer.write(dstr);
    writer.write(SEMICOLON);
}

/*
 * Append the UNTIL attribute after RRULE line
 */
void
VTimeZone::appendUNTIL(VTZWriter& writer, const UnicodeString& until,  UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    if (until.length() > 0) {
        writer.write(SEMICOLON);
        writer.write(ICAL_UNTIL);
        writer.write(EQUALS_SIGN);
        writer.write(until);
    }
}

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

//eof
