/// <summary>
    /// Initializes a new instance of the <see cref="LegacyAvailabilityTimeZone"/> class.
    /// </summary>
    /// <param name="timeZoneInfo">The time zone used to initialize this instance.</param>
    LegacyAvailabilityTimeZone(TimeZoneInfo timeZoneInfo)
        : this()
    {
        // Availability uses the opposite sign for the bias, e.g. if TimeZoneInfo.BaseUtcOffset = 480 than
        // SerializedTimeZone.Bias must be -480.
        this.bias = -timeZoneInfo.BaseUtcOffset;

        // To convert TimeZoneInfo into SerializableTimeZone, we need two time changes: one to Standard
        // time, the other to Daylight time. TimeZoneInfo holds a list of adjustment rules that represent
        // the different rules that govern time changes over the years. We need to grab one of those rules
        // to initialize this instance.
        TimeZoneInfo.AdjustmentRule[] adjustmentRules = timeZoneInfo.GetAdjustmentRules();

        if (adjustmentRules.Length == 0)
        {
            // If there are no adjustment rules (which is the case for UTC), we have to come up with two
            // dummy time changes which both have a delta of zero and happen at two hard coded dates. This
            // simulates a time zone in which there are no time changes.
            this.daylightTime              = new LegacyAvailabilityTimeZoneTime();
            this.daylightTime.Delta        = TimeSpan.Zero;
            this.daylightTime.DayOrder     = 1;
            this.daylightTime.DayOfTheWeek = DayOfTheWeek.Sunday;
            this.daylightTime.Month        = 10;
            this.daylightTime.TimeOfDay    = TimeSpan.FromHours(2);
            this.daylightTime.Year         = 0;

            this.standardTime              = new LegacyAvailabilityTimeZoneTime();
            this.standardTime.Delta        = TimeSpan.Zero;
            this.standardTime.DayOrder     = 1;
            this.standardTime.DayOfTheWeek = DayOfTheWeek.Sunday;
            this.standardTime.Month        = 3;
            this.standardTime.TimeOfDay    = TimeSpan.FromHours(2);
            this.daylightTime.Year         = 0;
        }
        else
        {
            // When there is at least one adjustment rule, we need to grab the last one which is the
            // one that currently applies (TimeZoneInfo stores adjustment rules sorted from oldest to
            // most recent).
            TimeZoneInfo.AdjustmentRule currentRule = adjustmentRules[adjustmentRules.Length - 1];

            this.standardTime = new LegacyAvailabilityTimeZoneTime(currentRule.DaylightTransitionEnd, TimeSpan.Zero);

            // Again, TimeZoneInfo and SerializableTime use opposite signs for bias.
            this.daylightTime = new LegacyAvailabilityTimeZoneTime(currentRule.DaylightTransitionStart, -currentRule.DaylightDelta);
        }
    }
    bool TryReadElementFromXml(EwsServiceXmlReader reader)
    {
        switch (reader.LocalName)
        {
        case XmlElementNames.Bias:
            this.bias = TimeSpan.FromMinutes(reader.ReadElementValue <int>());
            return(true);

        case XmlElementNames.StandardTime:
            this.standardTime = new LegacyAvailabilityTimeZoneTime();
            this.standardTime.LoadFromXml(reader, reader.LocalName);
            return(true);

        case XmlElementNames.DaylightTime:
            this.daylightTime = new LegacyAvailabilityTimeZoneTime();
            this.daylightTime.LoadFromXml(reader, reader.LocalName);
            return(true);

        default:
            return(false);
        }
    }