public void MSOXWSMTGS_S01_TC09_CreateAndCancelMeeting()
        {
            #region Organizer creates a meeting
            #region Set the properties of the meeting to create
            CalendarItemType meeting = new CalendarItemType();
            meeting.Subject = this.Subject;
            meeting.UID = Guid.NewGuid().ToString();
            meeting.Start = DateTime.UtcNow.AddDays(1);
            meeting.StartSpecified = true;
            meeting.End = meeting.Start.AddHours(2);
            meeting.EndSpecified = true;
            meeting.Location = this.Location;
            meeting.ConferenceType = 0;
            meeting.ConferenceTypeSpecified = true;
            meeting.AllowNewTimeProposal = false;
            meeting.AllowNewTimeProposalSpecified = true;
            if (Common.IsRequirementEnabled(2301, this.Site))
            {
                meeting.IsOnlineMeeting = false;
                meeting.IsOnlineMeetingSpecified = true;
            }
			
            meeting.LegacyFreeBusyStatus = LegacyFreeBusyType.Free;
            meeting.LegacyFreeBusyStatusSpecified = true;

            meeting.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meeting.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meeting.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            if (Common.IsRequirementEnabled(697, this.Site))
            {
                meeting.EnhancedLocation = new EnhancedLocationType();
                meeting.EnhancedLocation.DisplayName = Common.GenerateResourceName(this.Site, "Enhanced Location");
                meeting.EnhancedLocation.Annotation = Common.GenerateResourceName(this.Site, "Enhanced Location Annotation");
                meeting.EnhancedLocation.PostalAddress = new PersonaPostalAddressType();
                meeting.EnhancedLocation.PostalAddress.LocationSource = LocationSourceType.PhonebookServices;
                meeting.EnhancedLocation.PostalAddress.LocationSourceSpecified = true;
            }
            #endregion

            #region Create the meeting and sends it to all attendees
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meeting, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "Create a meeting item should be successful.");
            #endregion
            #endregion

            #region Attendee gets and declines the meeting request in the Inbox folder
            CalendarItemType calendar = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meeting.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The calendar item should be found in attendee's Calendar folder after organizer calls CreateItem with CalendarItemCreateOrDeleteOperationType set to SendOnlyToAll.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R16501");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R16501
            this.Site.CaptureRequirementIfAreEqual<LegacyFreeBusyType>(
                LegacyFreeBusyType.Free,
                calendar.LegacyFreeBusyStatus,
                16501,
                @"[In t:CalendarItemType Complex Type] The LegacyFreeBusyStatus which value is ""Free"" specifies the status as free.");

            #region Decline the meeting request
            MeetingRequestMessageType receivedRequest = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meeting.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(receivedRequest, "The meeting request message should exist in attendee's inbox folder.");

            #region Capture Code
            if (Common.IsRequirementEnabled(707, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R707");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R707
                this.Site.CaptureRequirementIfIsNotNull(
                    receivedRequest.EnhancedLocation,
                    707,
                    @"[In Appendix C: Product Behavior] Implementation does support the complex type ""EnhancedLocation"" with type ""EnhancedLocationType (section 2.2.4.10)"" which specifies enhanced location information. (Exchange 2013 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(3541, this.Site))
            {
                Site.Assert.IsTrue(receivedRequest.ConferenceTypeSpecified, "Element ConferenceType in MeetingRequestMessageType should be present.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R35500");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R35500
                this.Site.CaptureRequirementIfAreEqual<int>(
                    meeting.ConferenceType,
                    receivedRequest.ConferenceType,
                    35500,
                    @"[In t:MeetingRequestMessageType Complex Type] The value of ""ConferenceType"" is ""0"" (zero) describes the type of conferencing is video conference");
            }

            if (Common.IsRequirementEnabled(2301, this.Site))
            {
                Site.Assert.IsTrue(receivedRequest.IsOnlineMeetingSpecified, "The element IsOnlineMeeting should be present.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R767");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R767
                this.Site.CaptureRequirementIfIsFalse(
                    receivedRequest.IsOnlineMeeting,
                    767,
                    @"[In t:MeetingRequestMessageType Complex Type] otherwise [if the meeting is not online], [IsOnlineMeeting is] false.");
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R28501");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R28501
            this.Site.CaptureRequirementIfAreEqual<LegacyFreeBusyType>(
                LegacyFreeBusyType.Free,
                receivedRequest.IntendedFreeBusyStatus,
                28501,
                @"[In t:MeetingRequestMessageType Complex Type] The IntendedFreeBusyStatus which value is ""Free"" specifies the status as free.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R329");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R329
            // The format of the value of Duration elements followed xs:duration (as specified in [XMLSCHEMA2]), because of the duration set to 2 hours when create the meeting, therefore the expected value is "PT2H".
            this.Site.CaptureRequirementIfAreEqual<string>(
                "PT2H",
                receivedRequest.Duration,
                329,
                @"[In t:MeetingRequestMessageType Complex Type] Duration: Represents the duration of the meeting.");

            if (Common.IsRequirementEnabled(3311, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R3311");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R3311
                this.Site.CaptureRequirementIfIsNotNull(
                    receivedRequest.TimeZone,
                    3311,
                    @"[In Appendix C: Product Behavior] Implementation does support TimeZone in MeetingRequestMessageType. (Exchange 2007, Exchange 2010 and Exchange 2013 follow this behavior.)");
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R335");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R335
            this.Site.CaptureRequirementIfAreEqual<int>(
                0,
                receivedRequest.AppointmentSequenceNumber,
                335,
                @"[In t:MeetingRequestMessageType Complex Type] AppointmentSequenceNumber: Specifies the sequence number of a version of an appointment.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R137");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R137
            Site.CaptureRequirementIfIsNotNull(
                receivedRequest,
                137,
                @"[In t:AttendeeType Complex Type]Mailbox:  Specifies a fully resolved e-mail address.");
            #endregion

            DeclineItemType declineItem = new DeclineItemType();
            declineItem.ReferenceItemId = new ItemIdType();
            declineItem.ReferenceItemId = receivedRequest.ItemId;

            item = this.CreateSingleCalendarItem(Role.Attendee, declineItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "Decline meeting request should be successful.");
            #endregion
            #endregion

            #region Organizer gets the meeting response message and verify ResponseTypeType set to decline
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meeting.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "Organizer should receive the meeting response message after attendee declines the meeting.");

            #region Capture Code
            if (Common.IsRequirementEnabled(80011, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R80011");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R80011
                this.Site.CaptureRequirementIfIsNotNull(
                    response.EnhancedLocation,
                    80011,
                    @"[In Appendix C: Product Behavior] Implementation does support the EnhancedLocation, which is an element of type EnhancedLocationType, as defined in section 2.2.4.10, that represents additional location information for the calendar item. (Exchange 2013 and above follow this behavior.)");
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R83");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R83
            this.Site.CaptureRequirementIfAreEqual<ResponseTypeType>(
                ResponseTypeType.Decline,
                response.ResponseType,
                83,
                @"[In t:ResponseTypeType Simple Type] Decline: Indicates that the recipient declined the meeting.");

            #endregion

            CancelCalendarItemType cancelMeetingItem = new CancelCalendarItemType();
            cancelMeetingItem.ReferenceItemId = response.AssociatedCalendarItemId;
            #endregion

            #region Organizer cancels the meeting
            item = this.CreateSingleCalendarItem(Role.Organizer, cancelMeetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R491");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R491
            Site.CaptureRequirementIfIsNotNull(
                item,
                491,
                @"[In CreateItem Operation] It [CreateItem operation] can also be used to cancel a meeting.");
            #endregion

            #region Attendee removes the canceled meeting
            MeetingCancellationMessageType meetingResponse = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Canceled", meeting.UID) as MeetingCancellationMessageType;
            Site.Assert.IsNotNull(meetingResponse, "Attendee should receive the meeting cancellation message after organizer calls CreateItem to create MeetingCancellationMessage with CalendarItemCreateOrDeleteOperationType set to SendOnlyToAll.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R490");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R490
            this.Site.CaptureRequirementIfAreEqual<string>(
                "IPM.Schedule.Meeting.Canceled",
                meetingResponse.ItemClass,
                490,
                @"[In CreateItem Operation] This operation [CreateItem] can be used to create meeting cancellation messages.");

            if (Common.IsRequirementEnabled(697, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R80003");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R80003
                this.Site.CaptureRequirementIfIsNotNull(
                    meetingResponse.EnhancedLocation,
                    80003,
                    @"[In t:MeetingCancellationMessageType Complex Type] EnhancedLocation: An element of type EnhancedLocationType, as defined in section 2.2.4.10, that specifies additional location information for a calendar item.");
            }

            #region Verify the child elements of MeetingResponseMessageType
            if (Common.IsRequirementEnabled(900, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R900");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R900
                this.Site.CaptureRequirementIfAreEqual<DateTime>(
                    meeting.Start.Date,
                    meetingResponse.Start.Date,
                    900,
                    @"[In Appendix C: Product Behavior] Implementation does support Start which is a dateTime element that represents the start time of the calendar item. (Exchange 2013 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(901, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R901");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R901
                this.Site.CaptureRequirementIfAreEqual<DateTime>(
                    meeting.End.Date,
                    meetingResponse.End.Date,
                    901,
                    @"[In Appendix C: Product Behavior] Implementation does support End which is a dateTime element that represents the ending time of the calendar item. (Exchange 2013 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(902, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R902");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R902
                this.Site.CaptureRequirementIfAreEqual<string>(
                    meeting.Location.ToLower(),
                    meetingResponse.Location.ToLower(),
                    902,
                    @"[In Appendix C: Product Behavior] Implementation does support Location which is a string element that represents the location of the calendar item. (Exchange 2013 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(904, this.Site))
            {
                CalendarItemTypeType actual;
                Site.Assert.IsTrue(Enum.TryParse<CalendarItemTypeType>(meetingResponse.CalendarItemType, out actual), "The current value of CalendarItemType should be able to convert into one of CalendarItemTypeType enum values.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R904");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R904
                this.Site.CaptureRequirementIfAreEqual<CalendarItemTypeType>(
                    CalendarItemTypeType.Single,
                    actual,
                    904,
                    @"[In Appendix C: Product Behavior] Implementation does support CalendarItemType which is a string element that represents the type of calendar item. (Exchange 2013 and above follow this behavior.)");
            }
            #endregion

            RemoveItemType removeItem = removeItem = new RemoveItemType();
            removeItem.ReferenceItemId = new ItemIdType();
            removeItem.ReferenceItemId = meetingResponse.ItemId;

            #region Remove the canceled meeting
            item = this.CreateSingleCalendarItem(Role.Attendee, removeItem, CalendarItemCreateOrDeleteOperationType.SendToNone);

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R492");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R492
            this.Site.CaptureRequirementIfIsNotNull(
                item,
                492,
                @"[In CreateItem Operation] and when a meeting is cancelled, it [CreateItem Operation] can be used to remove the meeting item and corresponding meeting cancellation message from the server.");
            #endregion
            #endregion

            #region Clean up organizer's inbox, sentitems and deleteditems folders, and attendee's inbox, sentitems and deleteditems folders
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems });
            #endregion
        }
        public void MSOXWSMTGS_S01_TC03_CreateRecurringMeetingAndDecline()
        {
            #region Organizer creates a recurring meeting with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            #region Define a recurring meeting
            int timeInterval = this.TimeInterval;
            DateTime startTime = DateTime.Now.AddHours(timeInterval);

            DailyRecurrencePatternType pattern = new DailyRecurrencePatternType();
            pattern.Interval = this.PatternInterval;

            NumberedRecurrenceRangeType range = new NumberedRecurrenceRangeType();
            range.NumberOfOccurrences = this.NumberOfOccurrences;
            range.StartDate = startTime;

            CalendarItemType meetingItem = new CalendarItemType();
            meetingItem.UID = Guid.NewGuid().ToString();
            meetingItem.Subject = this.Subject;
            meetingItem.Start = startTime;

            // Indicates the Start property is serialized in the SOAP message.
            meetingItem.StartSpecified = true;
            timeInterval++;
            meetingItem.End = startTime.AddHours(timeInterval);
            meetingItem.EndSpecified = true;
            meetingItem.Location = this.Location;
            meetingItem.Recurrence = new RecurrenceType();
            meetingItem.Recurrence.Item = pattern;
            meetingItem.Recurrence.Item1 = range;
            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meetingItem.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };

            if (Common.IsRequirementEnabled(715, this.Site))
            {
                meetingItem.MeetingTimeZone = new TimeZoneType();
                meetingItem.MeetingTimeZone.BaseOffset = "PT7H";
                meetingItem.MeetingTimeZone.Standard = new TimeChangeType();
                meetingItem.MeetingTimeZone.Standard.Offset = "PT0H";
                meetingItem.MeetingTimeZone.Standard.Time = DateTime.Now;
                RelativeYearlyRecurrencePatternType yearlyRecurrence = new RelativeYearlyRecurrencePatternType();
                yearlyRecurrence.DaysOfWeek = "Sunday";
                yearlyRecurrence.DayOfWeekIndex = DayOfWeekIndexType.First;
                yearlyRecurrence.Month = MonthNamesType.November;
                meetingItem.MeetingTimeZone.Standard.Item = yearlyRecurrence;
                meetingItem.MeetingTimeZone.Daylight = new TimeChangeType();
                meetingItem.MeetingTimeZone.Daylight.Offset = "-PT1H";
                yearlyRecurrence = new RelativeYearlyRecurrencePatternType();
                yearlyRecurrence.DaysOfWeek = "Sunday";
                yearlyRecurrence.DayOfWeekIndex = DayOfWeekIndexType.Second;
                yearlyRecurrence.Month = MonthNamesType.March;
                meetingItem.MeetingTimeZone.Daylight.Item = yearlyRecurrence;
                meetingItem.MeetingTimeZone.Daylight.Time = DateTime.Now;
                meetingItem.MeetingTimeZone.TimeZoneName = "Time Zone";
            }
            #endregion

            // Create the recurring meeting
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "Server should return success for creating a recurring meeting.");
            ItemIdType meetingId = item.Items.Items[0].ItemId;

            #region Verify FirstOccurrence and LastOccurrence in the CalendarItemType
            ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, meetingId);
            Site.Assert.IsNotNull(getItem, "The calendar item to be deleted should exist.");

            if (Common.IsRequirementEnabled(715, this.Site))
            {
                CalendarItemType calendar = (CalendarItemType)getItem.Items.Items[0];

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R715");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R715
                this.Site.CaptureRequirementIfIsNotNull(
                    calendar.MeetingTimeZone,
                    715,
                    @"[In Appendix C: Product Behavior] Implementation does support complex type ""MeetingTimeZone"" with type ""t:TimeZoneType (section 2.2.4.40)"" which does specify the time zone of the location where the meeting is hosted. (<28> Section 2.2.4.9: Only Exchange 2007 supports the MeetingTimeZone element.)");
                
                if (Common.IsRequirementEnabled(654, this.Site))
                {
                    // Add the debug information
                    this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R654");

                    // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R654
                    this.Site.CaptureRequirementIfIsNotNull(
                        calendar.MeetingTimeZone,
                        654,
                        @"[In Appendix C: Product Behavior] Implementation does support the TimeZoneType complex type. (<17> Section 2.2.4: Only Exchange 2007 supports the TimeZoneType complex type.)");
                }

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1053");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1053
                this.Site.CaptureRequirementIfIsNotNull(
                    calendar.MeetingTimeZone,
                    1053,
                    @"[In t:CalendarItemType Complex Type] This element [MeetingTimeZone] is returned only if the value of the CalendarItemType element is RecurringMaster.");

                TimeZoneType timeZone = calendar.MeetingTimeZone;

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R407");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R407
                this.Site.CaptureRequirementIfIsNotNull(
                    timeZone.BaseOffset,
                    407,
                    @"[In t:TimeZoneType Complex Type] BaseOffset: Specifies the hourly offset from Coordinated Universal Time (UTC) for the current time zone.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R409");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R409
                this.Site.CaptureRequirementIfIsNotNull(
                    timeZone.Standard,
                    409,
                    @"[In t:TimeZoneType Complex Type] Standard: Specifies the date and time when the time changes from daylight saving time to standard time.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R411");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R411
                this.Site.CaptureRequirementIfIsNotNull(
                    timeZone.Daylight,
                    411,
                    @"[In t:TimeZoneType Complex Type] Daylight: Specifies the date and time when the time changes from standard time to daylight saving time.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R585");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R585
                this.Site.CaptureRequirementIfIsNotNull(
                    timeZone.TimeZoneName,
                    585,
                    @"[In t:TimeZoneType Complex Type] TimeZoneName: Specifies the time zone name.");

                TimeChangeType timeChange = timeZone.Standard;

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R399");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R399
                this.Site.CaptureRequirementIfIsNotNull(
                    timeChange.Offset,
                    399,
                    @"[In t:TimeChangeType Complex Type] Offset: Specifies the offset from the duration specified by the BaseOffset element (section 2.2.4.24).");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R401");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R401
                this.Site.CaptureRequirementIfIsNotNull(
                    timeChange.Time,
                    401,
                    @"[In t:TimeChangeType Complex Type] Time: Specifies the time when the time changes between standard time and daylight saving time.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R403");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R403
                this.Site.CaptureRequirementIfIsNotNull(
                    timeChange.TimeZoneName,
                    403,
                    @"[In t:TimeChangeType Complex Type] TimeZoneName: Specifies the time zone name.");
            }

            string actualFirstOccurrenceId = ((CalendarItemType)getItem.Items.Items[0]).FirstOccurrence.ItemId.Id;
            string actualLastOccurrenceId = ((CalendarItemType)getItem.Items.Items[0]).LastOccurrence.ItemId.Id;

            // Get the first occurrence by item id
            OccurrenceItemIdType firstOccurrenceId = new OccurrenceItemIdType();
            firstOccurrenceId.ChangeKey = meetingId.ChangeKey;
            firstOccurrenceId.RecurringMasterId = meetingId.Id;
            firstOccurrenceId.InstanceIndex = 1;

            getItem = this.GetSingleCalendarItem(Role.Organizer, firstOccurrenceId);
            Site.Assert.IsNotNull(getItem, "The first occurrence should be found.");
            CalendarItemType firstOccurrence = getItem.Items.Items[0] as CalendarItemType;

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R213");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R213
            this.Site.CaptureRequirementIfAreEqual<string>(
                firstOccurrence.ItemId.Id,
                actualFirstOccurrenceId,
                213,
                "[In t:CalendarItemType Complex Type]FirstOccurrence: Specifies the first occurrence of a recurring calendar item.");

            // Get the last occurrence by item id
            OccurrenceItemIdType lastOccurrenceId = new OccurrenceItemIdType();
            lastOccurrenceId.ChangeKey = meetingId.ChangeKey;
            lastOccurrenceId.RecurringMasterId = meetingId.Id;
            lastOccurrenceId.InstanceIndex = this.NumberOfOccurrences;

            getItem = this.GetSingleCalendarItem(Role.Organizer, lastOccurrenceId);
            Site.Assert.IsNotNull(getItem, "The last occurrence should be found.");
            CalendarItemType lastOccurrence = getItem.Items.Items[0] as CalendarItemType;

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R215");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R215
            this.Site.CaptureRequirementIfAreEqual<string>(
                lastOccurrence.ItemId.Id,
                actualLastOccurrenceId,
                215,
                "[In t:CalendarItemType Complex Type]LastOccurrence: Specifies the last occurrence of a recurring calendar item.");
            #endregion
            #endregion

            #region Organizer deletes an occurrence of the recurring calendar item with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            OccurrenceItemIdType occurrenceItemId = new OccurrenceItemIdType();
            occurrenceItemId.ChangeKey = meetingId.ChangeKey;
            occurrenceItemId.RecurringMasterId = meetingId.Id;
            occurrenceItemId.InstanceIndex = this.InstanceIndex;

            getItem = this.GetSingleCalendarItem(Role.Organizer, occurrenceItemId);
            Site.Assert.IsNotNull(getItem, "The calendar item to be deleted should exist.");

            ResponseMessageType deletedItem = this.DeleteSingleCalendarItem(Role.Organizer, occurrenceItemId, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(deletedItem, "The occurrence of the recurring calendar item should be deleted.");
            #endregion

            #region Attendee calls CreateItem to decline the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            MeetingRequestMessageType request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(request, "Attendee should receive the meeting request message in the Inbox folder after organizer calls CreateItem with CalendarItemCreateOrDeleteOperationType set to SendOnlyToAll.");

            bool isFirstOccurrence = (firstOccurrence.Start == request.FirstOccurrence.Start) && (firstOccurrence.End == request.FirstOccurrence.End);

            if (Common.IsRequirementEnabled(715, this.Site)
                && Common.IsRequirementEnabled(706, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R706");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R706
                this.Site.CaptureRequirementIfIsNotNull(
                    request.MeetingTimeZone,
                    706,
                    @"[In Appendix C: Product Behavior] Implementation does support the complex type ""MeetingTimeZone"" with type ""t:TimeZoneType (section 2.2.4.24)"" which does specify the time zone of the location where the meeting is hosted. (<52> Section 2.2.4.22:  Only Exchange 2007 supports the MeetingTimeZone element.)");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1090");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1090
                this.Site.CaptureRequirementIfIsNotNull(
                    request.MeetingTimeZone,
                    1090,
                    @"[In t:MeetingRequestMessageType Complex Type] This element [MeetingTimeZone] is returned only if the value of the CalendarItemType element is RecurringMaster.");
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R341, expected value of Start of first occurrence is {0} and actual value is {1}; expected value of End of first occurrence is {2} and actual value is {3}", firstOccurrence.Start, request.FirstOccurrence.Start, firstOccurrence.End, request.FirstOccurrence.End);

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R341
            this.Site.CaptureRequirementIfIsTrue(
                isFirstOccurrence,
                341,
                "[In t:MeetingRequestMessageType Complex Type] FirstOccurrence: Represents the first occurrence of a recurring meeting item.");

            bool isLastOccurrence = (lastOccurrence.Start == request.LastOccurrence.Start) && (lastOccurrence.End == request.LastOccurrence.End);

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R343, expected value of Start of last occurrence is {0} and actual value is {1}; expected value of End of last occurrence is {2} and actual value is {3}", lastOccurrence.Start, request.LastOccurrence.Start, lastOccurrence.End, request.LastOccurrence.End);

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R343
            this.Site.CaptureRequirementIfIsTrue(
                isLastOccurrence,
                343,
                "[In t:MeetingRequestMessageType Complex Type] LastOccurrence: Represents the last occurrence of a recurring meeting item.");

            DeclineItemType declinedItem = new DeclineItemType();
            declinedItem.ReferenceItemId = new ItemIdType();
            declinedItem.ReferenceItemId.Id = request.ItemId.Id;

            item = this.CreateSingleCalendarItem(Role.Attendee, declinedItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "Decline meeting request should be successful.");
            #endregion

            #region Organizer calls CreateItem with MeetingCancellationMessageType to cancel the created meeting with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The decline response should be in the Inbox folder.");
            CancelCalendarItemType cancelCalendarItem = new CancelCalendarItemType();
            cancelCalendarItem.ReferenceItemId = response.AssociatedCalendarItemId;

            item = this.CreateSingleCalendarItem(Role.Organizer, cancelCalendarItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "Cancel the meeting through CancelCalendarItemType using CreateItem should be successful.");
            #endregion

            #region Attendee finds the meeting cancellation message from his Inbox folder
            MeetingCancellationMessageType canceledMeeting = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Canceled", meetingItem.UID) as MeetingCancellationMessageType;
            Site.Assert.IsNotNull(canceledMeeting, "The canceled meeting should be in the Inbox folder.");
            #endregion

            #region Clean up organizer's inbox, sentitems and deleteditems folders, and attendee's inbox, sentitems and deleteditems folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems });
            #endregion
        }
        public void MSOXWSMTGS_S02_TC03_UpdateRecurringCalendar()
        {
            #region Define a recurring calendar item
            DateTime startTime = DateTime.Now;

            DailyRecurrencePatternType pattern = new DailyRecurrencePatternType();
            pattern.Interval = this.PatternInterval;

            NumberedRecurrenceRangeType range = new NumberedRecurrenceRangeType();
            range.NumberOfOccurrences = this.NumberOfOccurrences;
            range.StartDate = startTime;

            CalendarItemType meetingItem = new CalendarItemType();
            meetingItem.UID = Guid.NewGuid().ToString();
            meetingItem.Subject = this.Subject;
            meetingItem.Start = startTime;
            meetingItem.StartSpecified = true;
            meetingItem.End = startTime.AddHours(this.TimeInterval);
            meetingItem.EndSpecified = true;
            meetingItem.Location = this.Location;
            meetingItem.Recurrence = new RecurrenceType();
            meetingItem.Recurrence.Item = pattern;
            meetingItem.Recurrence.Item1 = range;
            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meetingItem.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            #endregion

            #region Organizer creates a recurring calendar item with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R494");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R494
            Site.CaptureRequirementIfIsNotNull(
                 item,
                 494,
                 @"[In CreateItem Operation] This operation [CreateItem] can be used to create meetings.");
            #endregion

            #region Organizer updates the Location element of the first occurrence of the recurring calendar item
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The meeting should be found in the organizer's Calendar folder after organizer calls CreateItem with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll.");

            OccurrenceItemIdType occurrenceId = new OccurrenceItemIdType();
            occurrenceId.RecurringMasterId = calendar.ItemId.Id;
            occurrenceId.InstanceIndex = 1;

            ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, occurrenceId);
            Site.Assert.IsNotNull(getItem, "The updated occurrence should exist.");

            // Update the first occurrence of the recurring meeting
            CalendarItemType calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;

            AdapterHelper itemChangeInfo = new AdapterHelper();
            itemChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            itemChangeInfo.Item = calendarUpdate;
            itemChangeInfo.ItemId = getItem.Items.Items[0].ItemId;

            UpdateItemResponseMessageType updatedItem = this.UpdateSingleCalendarItem(Role.Organizer, itemChangeInfo, CalendarItemUpdateOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(updatedItem, "The UpdateItem operation should be successful.");
            #endregion

            #region Attendee verifies whether the location of the first occurrence of the recurring calendar item has been updated
            CalendarItemType updatedOccurrence = null;
            bool locationUpdateSuccess = false;
            int counter = 0;
            while (counter < this.UpperBound)
            {
                System.Threading.Thread.Sleep(this.WaitTime);
                calendar = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
                Site.Assert.IsNotNull(calendar, "The meeting should be found in attendee's Calendar folder after organizer updates the meeting.");

                occurrenceId = new OccurrenceItemIdType();
                occurrenceId.RecurringMasterId = calendar.ItemId.Id;
                occurrenceId.InstanceIndex = 1;

                getItem = this.GetSingleCalendarItem(Role.Attendee, occurrenceId);
                Site.Assert.IsNotNull(getItem, "The updated occurrence should exist.");

                updatedOccurrence = getItem.Items.Items[0] as CalendarItemType;

                locationUpdateSuccess = string.Compare(this.LocationUpdate, updatedOccurrence.Location, true) == 0;
                if (locationUpdateSuccess)
                {
                    break;
                }

                counter++;
            }

            if (counter == this.UpperBound && !locationUpdateSuccess)
            {
                Site.Assert.Fail("Attendee should get the update information of calendar by the organizer.");
            }

            MeetingRequestMessageType updateRequest = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(updateRequest, "The meeting update request should be found in attendee's inbox folder after organizer updates the meeting.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R277");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R277
            this.Site.CaptureRequirementIfIsNotNull(
                updateRequest.RecurrenceId,
                277,
                "[In t:MeetingMessageType Complex Type] RecurrenceId: Identifies a specific instance of a recurring calendar item.");
            #endregion

            #region Attendee declines the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            DeclineItemType declineItem = new DeclineItemType();
            declineItem.ReferenceItemId = new ItemIdType();
            declineItem.ReferenceItemId = updatedOccurrence.ItemId;

            item = this.CreateSingleCalendarItem(Role.Attendee, declineItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "The response messages returned by the CreateItem operation should succeed.");
            #endregion

            #region Organizer calls FindItem to re-obtain the ItemId of the updated recurring calendar item because the changekey of ItemId is updated
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The declined meeting response returned by Attendee should be in organizer's Inbox folder.");

            if (Common.IsRequirementEnabled(80049, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R80049");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R80049
                this.Site.CaptureRequirementIfIsTrue(
                    response.IsOrganizer,
                    80049,
                    "[In Appendix C: Product Behavior] Implementation does support the IsOrganizer, which specifies whether the current user is the organizer of the meeting. (Exchange 2013 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(909, this.Site))
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R909");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R909
                Site.CaptureRequirementIfIsNotNull(
                     response.Recurrence,
                     909,
                     @"[In Appendix C: Product Behavior] Implementation does support Recurrence which is a RecurrenceType element that represents the recurrence for the calendar item. (Exchange 2013 and above follow this behavior.)");
            }
            #endregion

            #region Clean up organizer's inbox, calendar and deleteditems folders, and attendee's inbox, calendar and sentitems folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.calendar });
            #endregion
        }