Inheritance: BaseItemIdType
        public void MSOXWSMTGS_S04_TC03_MoveRecurringCalendar()
        {
            #region Define a recurring calendar item to move
            DateTime startTime = DateTime.Now;

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

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

            CalendarItemType calendarItem = new CalendarItemType();
            calendarItem.UID = Guid.NewGuid().ToString();
            calendarItem.Subject = this.Subject;
            calendarItem.Start = startTime;
            calendarItem.StartSpecified = true;
            calendarItem.End = startTime.AddHours(this.TimeInterval);
            calendarItem.EndSpecified = true;
            calendarItem.Recurrence = new RecurrenceType();
            calendarItem.Recurrence.Item = pattern;
            calendarItem.Recurrence.Item1 = range;
            #endregion

            #region Create the recurring calendar item and extract the Id of an occurrence item
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, calendarItem, CalendarItemCreateOrDeleteOperationType.SendToNone);
            OccurrenceItemIdType occurrenceItemId = new OccurrenceItemIdType();
            occurrenceItemId.ChangeKey = item.Items.Items[0].ItemId.ChangeKey;
            occurrenceItemId.RecurringMasterId = item.Items.Items[0].ItemId.Id;
            occurrenceItemId.InstanceIndex = this.InstanceIndex;
            #endregion

            #region Get the Id of the occurrence item
            ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, occurrenceItemId);
            Site.Assert.IsNotNull(getItem, "Organizer should get the occurrence item successfully.");

            RecurringMasterItemIdType recurringMasterItemId = new RecurringMasterItemIdType();
            recurringMasterItemId.ChangeKey = getItem.Items.Items[0].ItemId.ChangeKey;
            recurringMasterItemId.OccurrenceId = getItem.Items.Items[0].ItemId.Id;
            #endregion

            #region Move the recurring calendar item to Inbox folder
            DistinguishedFolderIdType folderId = new DistinguishedFolderIdType();
            folderId.Id = DistinguishedFolderIdNameType.inbox;
            TargetFolderIdType targetFolderId = new TargetFolderIdType();
            targetFolderId.Item = folderId;

            ItemInfoResponseMessageType movedItem = this.MoveSingleCalendarItem(Role.Organizer, recurringMasterItemId, targetFolderId);
            Site.Assert.IsNotNull(movedItem, @"Server should return success for moving the recurring calendar item.");
            #endregion

            #region Call FindItem to verify the recurring calendar item is moved to Inbox folder
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Appointment", calendarItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The recurring calendar should be in organizer's inbox folder.");

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R808
                this.Site.CaptureRequirementIfAreEqual<CalendarItemTypeType>(
                    CalendarItemTypeType.RecurringMaster,
                    calendar.CalendarItemType1,
                    808,
                    @"[In Appendix C: Product Behavior] MoveItemSoapIn: For each item being moved that is a recurring calendar item, implementation does contain a RecurringMasterItemId child element ([MS-OXWSCORE] section 2.2.4.11). (Exchange 2007 and above follow this behavior.)");
            }
            #endregion

            #region Clean up organizer's inbox folder.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox });
            #endregion
        }
        public void MSOXWSMTGS_S04_TC04_MoveItemErrorCalendarCannotMoveOrCopyOccurrence()
        {
            #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 calendarItem = new CalendarItemType();
            calendarItem.UID = Guid.NewGuid().ToString();
            calendarItem.Subject = this.Subject;
            calendarItem.Start = startTime;
            calendarItem.StartSpecified = true;
            calendarItem.End = startTime.AddHours(this.TimeInterval);
            calendarItem.EndSpecified = true;
            calendarItem.Recurrence = new RecurrenceType();
            calendarItem.Recurrence.Item = pattern;
            calendarItem.Recurrence.Item1 = range;
            #endregion

            #region Create the recurring calendar item and extract the Id of an occurrence item
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, calendarItem, CalendarItemCreateOrDeleteOperationType.SendToNone);

            OccurrenceItemIdType occurrenceItemId = new OccurrenceItemIdType();
            occurrenceItemId.ChangeKey = item.Items.Items[0].ItemId.ChangeKey;
            occurrenceItemId.RecurringMasterId = item.Items.Items[0].ItemId.Id;
            occurrenceItemId.InstanceIndex = this.InstanceIndex;
            #endregion

            #region Copy one occurrence of the recurring calendar item
            DistinguishedFolderIdType folderId = new DistinguishedFolderIdType();
            folderId.Id = DistinguishedFolderIdNameType.drafts;
            TargetFolderIdType targetFolderId = new TargetFolderIdType();
            targetFolderId.Item = folderId;

            MoveItemType moveItemRequest = new MoveItemType();
            moveItemRequest.ItemIds = new BaseItemIdType[] { occurrenceItemId };
            moveItemRequest.ToFolderId = targetFolderId;
            MoveItemResponseType response = this.MTGSAdapter.MoveItem(moveItemRequest);

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

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1228
            Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                ResponseClassType.Error,
                response.ResponseMessages.Items[0].ResponseClass,
                1228,
                @"[In Messages] If the request is unsuccessful, the MoveItem operation returns a MoveItemResponse element with the ResponseClass attribute of the MoveItemResponseMessage element set to ""Error"". ");

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

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1231
            Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                ResponseCodeType.ErrorCalendarCannotMoveOrCopyOccurrence,
                response.ResponseMessages.Items[0].ResponseCode,
                1231,
                @"[In Messages] ErrorCalendarCannotMoveOrCopyOccurrence: Specifies that an attempt was made to move or copy an occurrence of a recurring calendar item.");
            #endregion

            #region Clean up organizer's calendar folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar });
            #endregion
        }
        public void MSOXWSCORE_S05_TC22_VerifyCompareOriginalStartTime()
        {
            #region Step 1: Create and get a recurring calendar item.
            DateTime start = DateTime.Now;
            int numberOfOccurrences = 5;
            CalendarItemType calendar = this.CreateAndGetRecurringCalendarItem(start, numberOfOccurrences);

            #endregion

            #region Step 2: Get the first occurrence of the recurring calendar item by OccurrenceItemIdType.
            // The calendar item to get.
            OccurrenceItemIdType[] occurrenceItemId = new OccurrenceItemIdType[1];
            occurrenceItemId[0] = new OccurrenceItemIdType();
            occurrenceItemId[0].RecurringMasterId = calendar.ItemId.Id;
            occurrenceItemId[0].ChangeKey = calendar.FirstOccurrence.ItemId.ChangeKey;
            occurrenceItemId[0].InstanceIndex = 1;

            // Call the GetItem operation.
            GetItemResponseType getItemResponse = this.CallGetItemOperation(occurrenceItemId);

            // Check the operation response.
            Common.CheckOperationSuccess(getItemResponse, 1, this.Site);

            CalendarItemType[] getCalendarOccurences = Common.GetItemsFromInfoResponse<CalendarItemType>(getItemResponse);

            // One calendar item should be returned.
            Site.Assert.AreEqual<int>(
                1,
                 getCalendarOccurences.GetLength(0),
                 "One calendar item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 getCalendarOccurences.GetLength(0));

            ItemIdType[] itemIds = Common.GetItemIdsFromInfoResponse(getItemResponse);
            ItemIdId itemIdId = this.ITEMIDAdapter.ParseItemId(itemIds[0]);
            #endregion

            #region Step 3: Update the start date of the calendar item.

            ItemChangeType itemChange = new ItemChangeType();
            itemChange.Item = itemIds[0];

            CalendarItemType calendarChange = new CalendarItemType();
            calendarChange.Start = calendar.Start.AddMinutes(20);
            calendarChange.StartSpecified = true;

            itemChange.Updates = new ItemChangeDescriptionType[1];
            SetItemFieldType setItemField = new SetItemFieldType();
            setItemField.Item = new PathToUnindexedFieldType()
            {
                FieldURI = UnindexedFieldURIType.calendarStart
            };

            setItemField.Item1 = calendarChange;
            itemChange.Updates[0] = setItemField;

            UpdateItemResponseType updatedItem = this.CallUpdateItemOperation(DistinguishedFolderIdNameType.calendar, true, new ItemChangeType[] { itemChange });

            #endregion

            SutVersion currentSutVersion = (SutVersion)Enum.Parse(typeof(SutVersion), Common.GetConfigurationPropertyValue("SutVersion", this.Site));
            if (currentSutVersion.Equals(SutVersion.ExchangeServer2016))
            {
                #region Step 4: Get the recurring calendar item by RecurringMasterItemIdRangesType with set CompareOriginalStartTime to true.

                // The calendar item to get.
                RecurringMasterItemIdRangesType[] recurringMasterItemIdRanges = new RecurringMasterItemIdRangesType[1];
                recurringMasterItemIdRanges[0] = new RecurringMasterItemIdRangesType();

                // Use the first occurrence item id and change key to form the recurringMasterItemId
                recurringMasterItemIdRanges[0].Id = calendar.ItemId.Id;
                recurringMasterItemIdRanges[0].ChangeKey = calendar.ItemId.ChangeKey;
                recurringMasterItemIdRanges[0].Ranges = new OccurrencesRangeType[1];
                recurringMasterItemIdRanges[0].Ranges[0] = new OccurrencesRangeType();
                recurringMasterItemIdRanges[0].Ranges[0].Start = calendar.Start.AddMinutes(10);
                recurringMasterItemIdRanges[0].Ranges[0].StartSpecified = true;
                recurringMasterItemIdRanges[0].Ranges[0].End = start.AddDays(5);
                recurringMasterItemIdRanges[0].Ranges[0].EndSpecified = true;
                recurringMasterItemIdRanges[0].Ranges[0].Count = 5;
                recurringMasterItemIdRanges[0].Ranges[0].CountSpecified = true;
                recurringMasterItemIdRanges[0].Ranges[0].CompareOriginalStartTime = true;
                recurringMasterItemIdRanges[0].Ranges[0].CompareOriginalStartTimeSpecified = true;

                // Call the GetItem operation.
                GetItemResponseType getItemResponse1 = this.CallGetItemOperation(recurringMasterItemIdRanges);

                // Check the operation response.
                Common.CheckOperationSuccess(getItemResponse1, 1, this.Site);

                CalendarItemType[] getCalendarRecurring = Common.GetItemsFromInfoResponse<CalendarItemType>(getItemResponse1);

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

                // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1697
                this.Site.CaptureRequirementIfAreEqual(
                    5,
                    getCalendarRecurring.Length,
                    1697,
                    @"[In t:OccurrencesRangeType Complex Type] [CompareOriginalStartTime is] True, indicates comparing the specified ranges to an original start time.");

                #endregion

                #region Step 5: Get the recurrence master calendar item by RecurringMasterItemIdRangesType with set CompareOriginalStartTime to false.

                // The calendar item to get.
                recurringMasterItemIdRanges[0].Ranges[0].CompareOriginalStartTime = false;
                recurringMasterItemIdRanges[0].Ranges[0].CompareOriginalStartTimeSpecified = true;

                // Call the GetItem operation.
                getItemResponse1 = this.CallGetItemOperation(recurringMasterItemIdRanges);

                // Check the operation response.
                Common.CheckOperationSuccess(getItemResponse1, 1, this.Site);

                getCalendarRecurring = Common.GetItemsFromInfoResponse<CalendarItemType>(getItemResponse1);

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

                // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1698
                this.Site.CaptureRequirementIfAreEqual(
                    6,
                    getCalendarRecurring.Length,
                    1698,
                    @"[In t:OccurrencesRangeType Complex Type] otherwise [CompareOriginalStartTime is] false, indicates comparing the specified ranges to a pair of start and end values.");
                #endregion
            }

            // Clear ExistItemIds for DeleteItem.
            this.ExistItemIds.Clear();
            this.ExistItemIds.Add(calendar.ItemId);
        }
        public void MSOXWSMTGS_S03_TC03_CopyRecurringCalendar()
        {
            #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 calendarItem = new CalendarItemType();
            calendarItem.UID = Guid.NewGuid().ToString();
            calendarItem.Subject = this.Subject;
            calendarItem.Start = startTime;
            calendarItem.StartSpecified = true;
            calendarItem.End = startTime.AddHours(this.TimeInterval);
            calendarItem.EndSpecified = true;
            calendarItem.Recurrence = new RecurrenceType();
            calendarItem.Recurrence.Item = pattern;
            calendarItem.Recurrence.Item1 = range;
            #endregion

            #region Create the recurring calendar item and extract the Id of an occurrence item
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, calendarItem, CalendarItemCreateOrDeleteOperationType.SendToNone);

            OccurrenceItemIdType occurrenceItemId = new OccurrenceItemIdType();
            occurrenceItemId.ChangeKey = item.Items.Items[0].ItemId.ChangeKey;
            occurrenceItemId.RecurringMasterId = item.Items.Items[0].ItemId.Id;
            occurrenceItemId.InstanceIndex = this.InstanceIndex;
            #endregion

            #region Get the targeted occurrence item
            ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, occurrenceItemId);
            Site.Assert.IsNotNull(getItem, @"Get the occurrence should be successful.");

            RecurringMasterItemIdType recurringMasterItemId = new RecurringMasterItemIdType();
            recurringMasterItemId.ChangeKey = getItem.Items.Items[0].ItemId.ChangeKey;
            recurringMasterItemId.OccurrenceId = getItem.Items.Items[0].ItemId.Id;
            #endregion

            #region Copy the recurring calendar item to Drafts folder through Id of recurring master getItem
            DistinguishedFolderIdType folderId = new DistinguishedFolderIdType();
            folderId.Id = DistinguishedFolderIdNameType.drafts;
            TargetFolderIdType targetFolderId = new TargetFolderIdType();
            targetFolderId.Item = folderId;

            ItemInfoResponseMessageType copiedItem = this.CopySingleCalendarItem(Role.Organizer, recurringMasterItemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, @"Copy recurring calendar item through RecurringMasterItemId should be successful.");
            ItemIdType calendarIdByCopied = copiedItem.Items.Items[0].ItemId;
            #endregion

            #region Call GetItem operation to verify whether the recurring calendar item is really copied
            getItem = this.GetSingleCalendarItem(Role.Organizer, calendarIdByCopied);

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R806
                this.Site.CaptureRequirementIfIsNotNull(
                    getItem,
                    806,
                    @"[In Appendix C: Product Behavior] CopyItemSoapIn: For each item being copied that is a recurring calendar item, implementation does contain a RecurringMasterItemId child element ([MS-OXWSCORE] section 2.2.4.11). (Exchange 2007 and above follow this behavior.)");
            }
            #endregion

            #region Clean up organizer's drafts and calendar folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.drafts });
            #endregion
        }
        public void MSOXWSCORE_S05_TC17_GetMeetingItemWithFourItemIdTypesSuccessfully()
        {
            #region Step 1: Create a recurring calendar item.
            DateTime start = DateTime.Now;
            int numberOfOccurrences = 5;
            CalendarItemType item = this.CreateAndGetRecurringCalendarItem(start, numberOfOccurrences);
            #endregion

            #region Step 2: Get the first occurrence of the recurring calendar item by OccurrenceItemIdType.
            // The calendar item to get.
            OccurrenceItemIdType[] occurrenceItemId = new OccurrenceItemIdType[1];
            occurrenceItemId[0] = new OccurrenceItemIdType();
            occurrenceItemId[0].RecurringMasterId = item.ItemId.Id;
            occurrenceItemId[0].ChangeKey = item.FirstOccurrence.ItemId.ChangeKey;
            occurrenceItemId[0].InstanceIndex = 1;

            // Call the GetItem operation.
            GetItemResponseType getItemResponse = this.CallGetItemOperation(occurrenceItemId);
            
            // Check the operation response.
            Common.CheckOperationSuccess(getItemResponse, 1, this.Site);

            CalendarItemType[] getCalendarOccurences = Common.GetItemsFromInfoResponse<CalendarItemType>(getItemResponse);

            // One calendar item should be returned.
            Site.Assert.AreEqual<int>(
                1,
                 getCalendarOccurences.GetLength(0),
                 "One calendar item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 getCalendarOccurences.GetLength(0));

            ItemIdType[] itemIds = Common.GetItemIdsFromInfoResponse(getItemResponse);
            ItemIdId itemIdId = this.ITEMIDAdapter.ParseItemId(itemIds[0]);
            #endregion

            #region Step 3: Get the recurrence master calendar item by RecurringMasterItemIdType.
            // The calendar item to get.
            RecurringMasterItemIdType[] recurringMasterItemId = new RecurringMasterItemIdType[1];
            recurringMasterItemId[0] = new RecurringMasterItemIdType();

            // Use the first occurrence item id and change key to form the recurringMasterItemId
            recurringMasterItemId[0].OccurrenceId = item.FirstOccurrence.ItemId.Id;
            recurringMasterItemId[0].ChangeKey = item.FirstOccurrence.ItemId.ChangeKey;

            // Call the GetItem operation.
            getItemResponse = this.CallGetItemOperation(recurringMasterItemId);

            // Check the operation response.
            Common.CheckOperationSuccess(getItemResponse, 1, this.Site);

            CalendarItemType[] getCalendarRecurring = Common.GetItemsFromInfoResponse<CalendarItemType>(getItemResponse);

            // One calendar item should be returned.
            Site.Assert.AreEqual<int>(
                1,
                 getCalendarRecurring.GetLength(0),
                 "One calendar item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 getCalendarRecurring.GetLength(0));

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

            // Verify MS-OXWSITEMID requirement: MS-OXWSITEMID_R67
            Site.CaptureRequirementIfAreEqual<IdProcessingInstructionType>(
                IdProcessingInstructionType.Recurrence,
                (IdProcessingInstructionType)itemIdId.IdProcessingInstruction,
                "MS-OXWSITEMID",
                67,
                @"[In Id Storage Type (byte)] The Id processing uses the value of the following enumeration.
                        /// <summary>
                        /// Indicates any special processing to perform on an Id when deserializing it.
                        /// </summary>
                        internal enum IdProcessingInstruction : byte
                        {
                    [        /// <summary>
                            /// No special processing.  The Id represents a PR_ENTRY_ID
                            /// </summary>
                            Normal = 0,
                    ]
                             /// <summary>
                            /// The Id represents an OccurenceStoreObjectId and therefore
                           /// must be deserialized as a StoreObjectId.
                            /// </summary>
                            Recurrence = 1,

                    [       /// <summary>
                            /// The Id represents a series.
                            /// </summary>
                            Series = 2,]
                    }");
            #endregion
            
            // Clear ExistItemIds for DeleteItem.
            this.ExistItemIds.Clear();
            this.ExistItemIds.Add(item.ItemId);
        }
        public void MSOXWSCORE_S05_TC18_DeleteMeetingItemWithThreeItemIdTypesSuccessfully()
        {
            #region Step 1: Create and get a recurring calendar item.
            DateTime start = DateTime.Now;
            int numberOfOccurrences = 5;
            CalendarItemType calendar = this.CreateAndGetRecurringCalendarItem(start, numberOfOccurrences);

            #endregion

            #region Step 2: Delete the recurring calendar item by ItemIdType.
            DeleteItemResponseType deleteItemResponse = this.CallDeleteItemOperation();

            // Check the operation response.
            Common.CheckOperationSuccess(deleteItemResponse, 1, this.Site);

            // Clear ExistItemIds for DeleteItem.
            this.InitializeCollection();
            #endregion 

            #region Step 3: Create and get a recurring calendar item.
            calendar = this.CreateAndGetRecurringCalendarItem(start, numberOfOccurrences);

            #endregion 

            #region Step 4: Delete the recurrence master calendar item by RecurringMasterItemIdType.
            DeleteItemType deleteItemRequest = new DeleteItemType();

            // The calendar item to delete.
            RecurringMasterItemIdType[] recurringMasterItemIds = new RecurringMasterItemIdType[1];
            recurringMasterItemIds[0] = new RecurringMasterItemIdType();
            recurringMasterItemIds[0].OccurrenceId = calendar.FirstOccurrence.ItemId.Id;
            recurringMasterItemIds[0].ChangeKey = calendar.FirstOccurrence.ItemId.ChangeKey;

            deleteItemRequest.ItemIds = recurringMasterItemIds;

            // Enumeration value to describe how an item is to be deleted.
            deleteItemRequest.DeleteType = DisposalType.HardDelete;

            // AffectedTaskOccurrences indicates whether a task instance or a task master is to be deleted.
            deleteItemRequest.AffectedTaskOccurrencesSpecified = true;
            deleteItemRequest.AffectedTaskOccurrences = AffectedTaskOccurrencesType.AllOccurrences;

            // SendMeetingCancellations describes how cancellations are to be handled for deleted meetings.
            deleteItemRequest.SendMeetingCancellationsSpecified = true;
            deleteItemRequest.SendMeetingCancellations = CalendarItemCreateOrDeleteOperationType.SendToNone;
            deleteItemResponse = this.COREAdapter.DeleteItem(deleteItemRequest);

            // Check the operation response.
            Common.CheckOperationSuccess(deleteItemResponse, 1, this.Site);

            // Clear ExistItemIds for DeleteItem.
            this.InitializeCollection();
            #endregion

            #region Step 5: Create and get a recurring calendar item.
            calendar = this.CreateAndGetRecurringCalendarItem(start, numberOfOccurrences);

            #endregion

            #region Step 6: Delete the first occurrence of the recurring calendar item by OccurrenceItemIdType.
            deleteItemRequest = new DeleteItemType();

            // The calendar item to delete.
            OccurrenceItemIdType[] occurrenceItemIds = new OccurrenceItemIdType[1];
            occurrenceItemIds[0] = new OccurrenceItemIdType();
            occurrenceItemIds[0].RecurringMasterId = calendar.ItemId.Id;
            occurrenceItemIds[0].ChangeKey = calendar.FirstOccurrence.ItemId.ChangeKey;
            occurrenceItemIds[0].InstanceIndex = 1;

            deleteItemRequest.ItemIds = occurrenceItemIds;

            // Enumeration value to describe how an item is to be deleted.
            deleteItemRequest.DeleteType = DisposalType.HardDelete;

            // AffectedTaskOccurrences indicates whether a task instance or a task master is to be deleted.
            deleteItemRequest.AffectedTaskOccurrencesSpecified = true;
            deleteItemRequest.AffectedTaskOccurrences = AffectedTaskOccurrencesType.AllOccurrences;

            // SendMeetingCancellations describes how cancellations are to be handled for deleted meetings.
            deleteItemRequest.SendMeetingCancellationsSpecified = true;
            deleteItemRequest.SendMeetingCancellations = CalendarItemCreateOrDeleteOperationType.SendToNone;
            deleteItemResponse = this.COREAdapter.DeleteItem(deleteItemRequest);

            // Check the operation response.
            Common.CheckOperationSuccess(deleteItemResponse, 1, this.Site);

            #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
        }
        /// <summary>
        /// Get the first occurrence of a recurring meeting.
        /// </summary>
        /// <param name="meetingItem">A recurring meeting.</param>
        /// <param name="role">The role to get the recurring meeting.</param>
        /// <returns>The first occurrence of the recurring meeting.</returns>
        private ItemType GetFirstOccurrenceItem(CalendarItemType meetingItem, Role role)
        {
            if (meetingItem != null)
            {
                #region Get the calendar the targeted occurrence belongs to.
                CalendarItemType calendar = this.SearchSingleItem(role, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
                Site.Assert.IsNotNull(calendar, "The calendar the targeted occurrence belongs to should exist.");

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

                #region Get the occurrence item
                ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(role, occurrenceId);
                if (getItem != null)
                {
                    return getItem.Items.Items[0];
                }
                #endregion
            }

            return null;
        }
        public void MSOXWSMTGS_S01_TC21_DeleteItemErrorSendMeetingCancellationsRequired()
        {
            #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 calendarItem = new CalendarItemType();
            calendarItem.UID = Guid.NewGuid().ToString();
            calendarItem.Subject = this.Subject;
            calendarItem.Start = startTime;
            calendarItem.StartSpecified = true;
            calendarItem.End = startTime.AddHours(this.TimeInterval);
            calendarItem.EndSpecified = true;
            calendarItem.Recurrence = new RecurrenceType();
            calendarItem.Recurrence.Item = pattern;
            calendarItem.Recurrence.Item1 = range;
            #endregion

            #region Create the recurring calendar item and extract the Id of an occurrence item
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, calendarItem, CalendarItemCreateOrDeleteOperationType.SendToNone);

            OccurrenceItemIdType occurrenceItemId = new OccurrenceItemIdType();
            occurrenceItemId.ChangeKey = item.Items.Items[0].ItemId.ChangeKey;
            occurrenceItemId.RecurringMasterId = item.Items.Items[0].ItemId.Id;
            occurrenceItemId.InstanceIndex = this.InstanceIndex;
            #endregion

            #region Get the targeted occurrence item
            ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, occurrenceItemId);
            Site.Assert.IsNotNull(getItem, @"Get the occurrence should be successful.");

            RecurringMasterItemIdType invalidRecurringMasterItemId = new RecurringMasterItemIdType();
            invalidRecurringMasterItemId.ChangeKey = getItem.Items.Items[0].ItemId.ChangeKey;
            invalidRecurringMasterItemId.OccurrenceId = getItem.Items.Items[0].ItemId.Id;
            #endregion

            #region Delete the occurrence
            DeleteItemType deleteItemRequest = new DeleteItemType();
            deleteItemRequest.ItemIds = new BaseItemIdType[] { occurrenceItemId };
            deleteItemRequest.DeleteType = DisposalType.HardDelete;
            DeleteItemResponseType deleteItemResponse = this.MTGSAdapter.DeleteItem(deleteItemRequest);

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

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1209
            Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                ResponseClassType.Error,
                deleteItemResponse.ResponseMessages.Items[0].ResponseClass,
                1209,
                @"[In Messages] If the request is unsuccessful, the DeleteItem operation returns a DeleteItemResponse element with the ResponseClass attribute of the DeleteItemResponseMessage element set to ""Error"". ");

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

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1213
            Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                ResponseCodeType.ErrorSendMeetingCancellationsRequired,
                deleteItemResponse.ResponseMessages.Items[0].ResponseCode,
                1213,
                @"[In Messages] ErrorSendMeetingCancellationsRequired: Occurs during a DeleteItem call, when the SendMeetingCancellations property is missing from the request and the item to delete is a calendar item. ");
            #endregion

            #region Clean up organizer's calendar folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar });
            #endregion
        }
        public void MSOXWSMTGS_S01_TC17_UpdateAndDeleteoccurrenceOfRecurringMeeting()
        {
            #region Organizer creates a recurring meeting
            // Verify DailyRecurrencePatternType and NumberedRecurrenceRangeType.
            DailyRecurrencePatternType dailyPattern = new DailyRecurrencePatternType();
            NumberedRecurrenceRangeType numberedRange = new NumberedRecurrenceRangeType();
            numberedRange.NumberOfOccurrences = this.NumberOfOccurrences;

            // Define a recurring meeting.
            CalendarItemType meetingItem = this.DefineRecurringMeeting(dailyPattern, numberedRange);
            Site.Assert.IsNotNull(meetingItem, "The meeting item should be created.");

            // Create the recurring meeting.
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "The recurring meeting should be created successfully.");
            #endregion

            #region Attendee gets the meeting request
            MeetingRequestMessageType request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(request, "The meeting request message should be found in attendee's Inbox folder after organizer calls CreateItem with CalendarItemCreateOrDeleteOperationType set to SendOnlyToAll.");
            #endregion

            #region Attendee accepts the meeting request
            AcceptItemType acceptItem = new AcceptItemType();
            acceptItem.ReferenceItemId = new ItemIdType();
            acceptItem.ReferenceItemId.Id = request.ItemId.Id;
            item = this.CreateSingleCalendarItem(Role.Attendee, acceptItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "Accept the meeting request should be successful.");
            #endregion

            #region Attendee gets the accepted meeting request.
            request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.deleteditems, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(request, "The meeting request should exist in attendee's Deleted Items folder after attendee accepts the meeting request.");
            Site.Assert.IsTrue(request.IsOutOfDateSpecified, "Element IsOutOfDate should be present.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R751
            this.Site.CaptureRequirementIfIsFalse(
                request.IsOutOfDate,
                751,
                @"[In t:MeetingMessageType Complex Type] otherwise [ there has not been an update to the meeting and the current item in the calendar is not out of date] false.");
            #endregion

            #region Organizer gets the calendar item
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(item, "The calendar item should be found in organizer's Calendar folder.");
            #endregion

            #region Organizer deletes one of the occurrences of the recurring meeting
            OccurrenceItemIdType occurrenceId = new OccurrenceItemIdType();
            occurrenceId.RecurringMasterId = calendar.ItemId.Id;
            occurrenceId.InstanceIndex = 1;

            DeleteItemType deleteItemRequest = new DeleteItemType();
            deleteItemRequest.ItemIds = new BaseItemIdType[] { occurrenceId };
            deleteItemRequest.DeleteType = DisposalType.HardDelete;
            deleteItemRequest.SendMeetingCancellations = CalendarItemCreateOrDeleteOperationType.SendOnlyToAll;
            deleteItemRequest.SendMeetingCancellationsSpecified = true;
            DeleteItemResponseType deleteItemResponse = this.MTGSAdapter.DeleteItem(deleteItemRequest);
            Common.CheckOperationSuccess(deleteItemResponse, 1, this.Site);

            calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The calendar item should exist.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1214
            // SendMeetingCancellationsSpecified is specified as true, and the occurrence is deleted successfully, this requirement can be captured.
            this.Site.CaptureRequirement(
                1214,
                @"[In Messages] If you are using the proxy objects, make sure that the SendMeetingCancellationsSpecified property is set to true.");
            #endregion

            #region Organizer updates one of the occurrences of the recurring meeting
            occurrenceId = new OccurrenceItemIdType();
            occurrenceId.RecurringMasterId = calendar.ItemId.Id;
            occurrenceId.ChangeKey = calendar.ItemId.ChangeKey;
            occurrenceId.InstanceIndex = 2;
            UpdateItemType updateItemRequest = new UpdateItemType();
            updateItemRequest.ItemChanges = new ItemChangeType[1];
            updateItemRequest.SendMeetingInvitationsOrCancellations = CalendarItemUpdateOperationType.SendToAllAndSaveCopy;
            updateItemRequest.SendMeetingInvitationsOrCancellationsSpecified = true;
            updateItemRequest.MessageDisposition = MessageDispositionType.SendAndSaveCopy;
            updateItemRequest.MessageDispositionSpecified = true;
            updateItemRequest.ConflictResolution = ConflictResolutionType.AlwaysOverwrite;
            updateItemRequest.ItemChanges[0] = new ItemChangeType();
            updateItemRequest.ItemChanges[0].Item = occurrenceId;
            SetItemFieldType setItemField = new SetItemFieldType();
            PathToUnindexedFieldType pathToUnindexed = new PathToUnindexedFieldType();
            pathToUnindexed.FieldURI = UnindexedFieldURIType.calendarLocation;
            setItemField.Item = pathToUnindexed;
            setItemField.Item1 = new CalendarItemType() { Location = this.LocationUpdate };
            updateItemRequest.ItemChanges[0].Updates = new ItemChangeDescriptionType[] { setItemField };
            UpdateItemResponseType updateItemResponse = this.MTGSAdapter.UpdateItem(updateItemRequest);
            Common.CheckOperationSuccess(updateItemResponse, 1, this.Site);
            #endregion

            #region Organizer gets the udpated calendar item
            calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            #endregion

            #region Organizer updates the calendar item
            updateItemRequest.ItemChanges[0].Item = calendar.ItemId;
            string locationUpdated = Common.GenerateResourceName(this.Site, "NewLocation");
            setItemField.Item1 = new CalendarItemType() { Location = locationUpdated };
            updateItemRequest.ItemChanges[0].Updates = new ItemChangeDescriptionType[] { setItemField };

            updateItemResponse = this.MTGSAdapter.UpdateItem(updateItemRequest);
            Common.CheckOperationSuccess(updateItemResponse, 1, this.Site);
            #endregion

            #region Attendee gets the updated meeting request
            request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, locationUpdated, meetingItem.UID, UnindexedFieldURIType.calendarLocation) as MeetingRequestMessageType;

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R345
            this.Site.CaptureRequirementIfAreEqual<int>(
                1,
                request.ModifiedOccurrences.Length,
                345,
                @"[In t:MeetingRequestMessageType Complex Type] ModifiedOccurrences: Contains an array of recurring meeting item occurrences that have been modified so that they are different from the original instances of the recurrence master item.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R347
            this.Site.CaptureRequirementIfAreEqual<int>(
                1,
                request.DeletedOccurrences.Length,
                347,
                @"[In t:MeetingRequestMessageType Complex Type] DeletedOccurrences: Contains an array of deleted occurrences of a recurring meeting item.");
            #endregion

            #region Attendee gets the accepted meeting request again.
            request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.deleteditems, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(request, "The meeting request should exist in attendee's Deleted Items folder after attendee accepts the meeting request.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R750
            this.Site.CaptureRequirementIfIsTrue(
                request.IsOutOfDate,
                750,
                @"[In t:MeetingMessageType Complex Type] [IsOutOfDate is] True,  there has been an update to the meeting and the current item in the calendar is out of date.");
            #endregion

            #region Clean up organizer's deleteditems and sentitems folder, and attendee's inbox, calendar and deleteditems folders.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar, 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
        }