/// <summary>
        /// Log on to a mailbox with a specified user account and find the specified meeting message in the Inbox folder, then accept it.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="userPassword">Password of the user.</param>
        /// <param name="userDomain">Domain of the user.</param>
        /// <param name="itemSubject">Subject of the meeting message which should be accepted.</param>
        /// <param name="itemType">Type of the item which should be accepted.</param>
        /// <returns>If the specified meeting message is accepted successfully, return true; otherwise, return false.</returns>
        public bool FindAndAcceptMeetingMessage(string userName, string userPassword, string userDomain, string itemSubject, string itemType)
        {
            // Define the Inbox folder as parent folder.
            DistinguishedFolderIdNameType parentFolderIdName = DistinguishedFolderIdNameType.inbox;

            // Switch to specified user mailbox.
            bool isSwitched = AdapterHelper.SwitchUser(userName, userPassword, userDomain, this.exchangeServiceBinding, this.Site);

            Site.Assert.IsTrue(
                isSwitched,
                string.Format("Log on mailbox with the UserName: {0}, Password: {1}, Domain: {2} should be successful.", userName, userPassword, userDomain));

            Item item = (Item)Enum.Parse(typeof(Item), itemType, true);

            // Loop to find the specified item in the specified folder.
            ItemType type       = this.LoopToFindItem(parentFolderIdName, itemSubject, item);
            bool     isAccepted = false;

            if (type != null)
            {
                MeetingRequestMessageType message = type as MeetingRequestMessageType;

                // Create a request for the CreateItem operation.
                CreateItemType createItemRequest = new CreateItemType();

                // Add the CalendarItemType item to the items to be created.
                createItemRequest.Items = new NonEmptyArrayOfAllItemsType();

                // Create an AcceptItemType item to reply to a meeting request.
                AcceptItemType acceptItem = new AcceptItemType();

                // Set the related meeting request.
                acceptItem.ReferenceItemId    = message.ItemId;
                createItemRequest.Items.Items = new ItemType[] { acceptItem };

                // Set the MessageDisposition property to SendOnly.
                createItemRequest.MessageDisposition          = MessageDispositionType.SendOnly;
                createItemRequest.MessageDispositionSpecified = true;

                // Invoke the CreateItem operation.
                CreateItemResponseType createItemResponse = this.exchangeServiceBinding.CreateItem(createItemRequest);

                if (createItemResponse != null && createItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Success)
                {
                    isAccepted = true;
                }
            }

            return(isAccepted);
        }
        public void MSOXWSMTGS_S04_TC02_MoveMeeting()
        {
            #region Define the target folder to move
            // Define the Inbox folder as the target folder for moving meeting item.
            DistinguishedFolderIdType inboxFolder = new DistinguishedFolderIdType();
            inboxFolder.Id = DistinguishedFolderIdNameType.inbox;
            TargetFolderIdType meetingTargetFolder = new TargetFolderIdType();
            meetingTargetFolder.Item = inboxFolder;

            // Define the Calendar folder as the target folder for moving meeting request message, meeting response message and meeting cancellation message.
            DistinguishedFolderIdType calendarFolder = new DistinguishedFolderIdType();
            calendarFolder.Id = DistinguishedFolderIdNameType.calendar;
            TargetFolderIdType msgTargetFolder = new TargetFolderIdType();
            msgTargetFolder.Item = calendarFolder;
            #endregion

            #region Organizer creates a meeting with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            #region Define a meeting to be moved
            CalendarItemType meetingItem = new CalendarItemType();
            meetingItem.Subject           = this.Subject;
            meetingItem.UID               = Guid.NewGuid().ToString();
            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meetingItem.Resources         = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            #endregion

            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            ItemIdType meetingId             = item.Items.Items[0].ItemId;
            #endregion

            #region Organizer moves the meeting item to Inbox folder
            ItemInfoResponseMessageType movedItem = this.MoveSingleCalendarItem(Role.Organizer, meetingId, meetingTargetFolder);

            Site.Assert.AreEqual <ResponseClassType>(
                ResponseClassType.Success,
                movedItem.ResponseClass,
                "Server should return success for moving the meeting item.");

            ItemIdType movedMeetingItemId = movedItem.Items.Items[0].ItemId;
            #endregion

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

            #region Attendee finds the meeting request message in his Inbox folder
            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 exist in attendee's inbox folder.");
            #endregion

            #region Attendee moves the meeting request message to the Calendar folder
            movedItem = this.MoveSingleCalendarItem(Role.Attendee, request.ItemId, msgTargetFolder);

            Site.Assert.AreEqual <ResponseClassType>(
                ResponseClassType.Success,
                movedItem.ResponseClass,
                @"Server should return success for moving meeting request message.");
            #endregion

            #region Attendee calls FindItem to verify the meeting request message is moved to Calendar folder
            request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(request, "The meeting request message should exist in attendee's calendar folder.");
            #endregion

            #region Attendee calls CreateItem to accept the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            AcceptItemType acceptItem = new AcceptItemType();
            acceptItem.ReferenceItemId = request.ItemId;

            item = this.CreateSingleCalendarItem(Role.Attendee, acceptItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            #endregion

            #region Organizer finds the meeting response message in its Inbox folder
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The meeting response message should exist in organizer's inbox folder.");
            #endregion

            #region Organizer moves the meeting response message to his Calendar folder
            movedItem = this.MoveSingleCalendarItem(Role.Organizer, response.ItemId, msgTargetFolder);

            Site.Assert.AreEqual <ResponseClassType>(
                ResponseClassType.Success,
                movedItem.ResponseClass,
                "EWS should return success for moving the meeting response message.");
            #endregion

            #region Organizer calls FindItem to verify the meeting response message is moved to Calendar folder
            response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The meeting response message should be in organizer's calendar folder.");
            #endregion

            #region Organizer calls DeleteItem to delete the meeting with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            ResponseMessageType deletedItem = this.DeleteSingleCalendarItem(Role.Organizer, movedMeetingItemId, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(deletedItem, "Delete the meeting should be successful.");
            #endregion

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

            #region Attendee moves the meeting cancellation message to his Calendar folder
            movedItem = this.MoveSingleCalendarItem(Role.Attendee, canceledMeeting.ItemId, msgTargetFolder);

            Site.Assert.AreEqual <ResponseClassType>(
                ResponseClassType.Success,
                movedItem.ResponseClass,
                "EWS should return success for moving the meeting cancellation message.");
            #endregion

            #region Attendee calls FindItem to verify the meeting cancellation message is moved to Calendar folder
            canceledMeeting = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Schedule.Meeting.Canceled", meetingItem.UID) as MeetingCancellationMessageType;
            Site.Assert.IsNotNull(canceledMeeting, "The meeting cancellation message should be in attendee's calendar folder.");
            #endregion

            #region Attendee removes the meeting item
            RemoveItemType removeItem = new RemoveItemType();
            removeItem.ReferenceItemId = canceledMeeting.ItemId;
            item = this.CreateSingleCalendarItem(Role.Attendee, removeItem, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(item, "The meeting item should be removed.");
            #endregion

            #region Clean up organizer's calendar and deleteditems folders, and attendee's sentitems and deleteditems folders
            this.CleanupFoldersByRole(Role.Organizer, new List <DistinguishedFolderIdNameType>()
            {
                DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.deleteditems
            });
            this.CleanupFoldersByRole(Role.Attendee, new List <DistinguishedFolderIdNameType>()
            {
                DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems
            });
            #endregion
        }
예제 #3
0
        public void MSOXWSMTGS_S03_TC02_CopySingleMeetingItem()
        {
            #region Organizer creates a single meeting getItem with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            CalendarItemType meetingItem = new CalendarItemType();
            meetingItem.Subject           = this.Subject;
            meetingItem.UID               = Guid.NewGuid().ToString();
            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meetingItem.Resources         = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };

            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "Create single meeting item should be successful.");
            #endregion

            #region Organizer copies the created single meeting item to Drafts folder
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The created calendar should exist in organizer's calendar folder.");
            ItemIdType itemId = calendar.ItemId;

            DistinguishedFolderIdType folderId = new DistinguishedFolderIdType();
            folderId.Id = DistinguishedFolderIdNameType.drafts;
            TargetFolderIdType targetFolderId = new TargetFolderIdType();
            targetFolderId.Item = folderId;

            ItemInfoResponseMessageType copiedItem = this.CopySingleCalendarItem(Role.Organizer, itemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, @"Copy the single meeting item should be successful.");
            #endregion

            #region Organizer calls GetItem operation to verify whether the meeting item is really copied
            calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.drafts, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The copied calendar should exist in organizer's Drafts folder.");
            #endregion

            #region Attendee gets the meeting request message in the Inbox folder
            MeetingRequestMessageType request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, meetingItem.Subject, meetingItem.UID, UnindexedFieldURIType.itemSubject) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(request, "The meeting request message should exist in attendee's inbox folder.");
            #endregion

            #region Attendee copies the meeting request message to the Drafts folder
            copiedItem = this.CopySingleCalendarItem(Role.Attendee, request.ItemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, @"Copy the single meeting request message should be successful.");
            #endregion

            #region Attendee calls CreateItem to accept the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            AcceptItemType acceptItem = new AcceptItemType();
            acceptItem.ReferenceItemId = request.ItemId;

            Site.Assert.IsNotNull(
                this.CreateSingleCalendarItem(Role.Attendee, acceptItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll),
                "Attendee creates items for meeting request should succeed.");
            #endregion

            #region Organizer finds the meeting response message in his Inbox folder and copies it to the Drafts folder
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The response message from Attendee should be in organizer's Inbox folder.");

            copiedItem = this.CopySingleCalendarItem(Role.Organizer, response.ItemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, @"Copy the single meeting response message should be successful.");
            #endregion

            #region Organizer deletes the meeting item with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            ResponseMessageType deletedItem = this.DeleteSingleCalendarItem(Role.Organizer, itemId, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(deletedItem, @"Delete the single meeting item should be successful.");
            #endregion

            #region Attendee finds the meeting cancellation message in the Inbox folder and copies it to the Drafts folder
            int upperBound = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));
            int waitTime   = int.Parse(Common.GetConfigurationPropertyValue("WaitTime", this.Site));
            int count      = 1;

            MeetingCancellationMessageType canceledItem = null;

            while (canceledItem == null && count++ <= upperBound)
            {
                canceledItem = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Canceled", meetingItem.UID) as MeetingCancellationMessageType;
                System.Threading.Thread.Sleep(waitTime);
            }

            Site.Assert.IsNotNull(canceledItem, "The cancellation meeting message should be in attendee's Inbox folder.");

            ItemIdType canceledItemId = canceledItem.ItemId;
            copiedItem = this.CopySingleCalendarItem(Role.Attendee, canceledItemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, "Attendee should copy the meeting cancellation message to the Drafts folder.");
            #endregion

            #region Clean up inbox, drafts and deleteditems folders of both organizer and attendee. Attendee's sentitems and calendar should also be cleaned up.
            this.CleanupFoldersByRole(Role.Organizer, new List <DistinguishedFolderIdNameType>()
            {
                DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.drafts, DistinguishedFolderIdNameType.deleteditems
            });
            this.CleanupFoldersByRole(Role.Attendee, new List <DistinguishedFolderIdNameType>()
            {
                DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.drafts, DistinguishedFolderIdNameType.deleteditems
            });
            #endregion
        }
        public void MSOXWSMTGS_S04_TC02_MoveMeeting()
        {
            #region Define the target folder to move
            // Define the Inbox folder as the target folder for moving meeting item.
            DistinguishedFolderIdType inboxFolder = new DistinguishedFolderIdType();
            inboxFolder.Id = DistinguishedFolderIdNameType.inbox;
            TargetFolderIdType meetingTargetFolder = new TargetFolderIdType();
            meetingTargetFolder.Item = inboxFolder;

            // Define the Calendar folder as the target folder for moving meeting request message, meeting response message and meeting cancellation message.
            DistinguishedFolderIdType calendarFolder = new DistinguishedFolderIdType();
            calendarFolder.Id = DistinguishedFolderIdNameType.calendar;
            TargetFolderIdType msgTargetFolder = new TargetFolderIdType();
            msgTargetFolder.Item = calendarFolder;
            #endregion

            #region Organizer creates a meeting with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            #region Define a meeting to be moved
            CalendarItemType meetingItem = new CalendarItemType();
            meetingItem.Subject = this.Subject;
            meetingItem.UID = Guid.NewGuid().ToString();
            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meetingItem.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            #endregion

            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            ItemIdType meetingId = item.Items.Items[0].ItemId;
            #endregion

            #region Organizer moves the meeting item to Inbox folder
            ItemInfoResponseMessageType movedItem = this.MoveSingleCalendarItem(Role.Organizer, meetingId, meetingTargetFolder);

            Site.Assert.AreEqual<ResponseClassType>(
                ResponseClassType.Success,
                movedItem.ResponseClass,
                "Server should return success for moving the meeting item.");

            ItemIdType movedMeetingItemId = movedItem.Items.Items[0].ItemId;
            #endregion

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

            #region Attendee finds the meeting request message in his Inbox folder
            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 exist in attendee's inbox folder.");
            #endregion

            #region Attendee moves the meeting request message to the Calendar folder
            movedItem = this.MoveSingleCalendarItem(Role.Attendee, request.ItemId, msgTargetFolder);

            Site.Assert.AreEqual<ResponseClassType>(
                ResponseClassType.Success,
                movedItem.ResponseClass,
                @"Server should return success for moving meeting request message.");
            #endregion

            #region Attendee calls FindItem to verify the meeting request message is moved to Calendar folder
            request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(request, "The meeting request message should exist in attendee's calendar folder.");
            #endregion

            #region Attendee calls CreateItem to accept the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            AcceptItemType acceptItem = new AcceptItemType();
            acceptItem.ReferenceItemId = request.ItemId;

            item = this.CreateSingleCalendarItem(Role.Attendee, acceptItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            #endregion

            #region Organizer finds the meeting response message in its Inbox folder
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The meeting response message should exist in organizer's inbox folder.");
            #endregion

            #region Organizer moves the meeting response message to his Calendar folder
            movedItem = this.MoveSingleCalendarItem(Role.Organizer, response.ItemId, msgTargetFolder);

            Site.Assert.AreEqual<ResponseClassType>(
                ResponseClassType.Success,
                movedItem.ResponseClass,
                "EWS should return success for moving the meeting response message.");
            #endregion

            #region Organizer calls FindItem to verify the meeting response message is moved to Calendar folder
            response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The meeting response message should be in organizer's calendar folder.");
            #endregion

            #region Organizer calls DeleteItem to delete the meeting with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            ResponseMessageType deletedItem = this.DeleteSingleCalendarItem(Role.Organizer, movedMeetingItemId, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(deletedItem, "Delete the meeting should be successful.");
            #endregion

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

            #region Attendee moves the meeting cancellation message to his Calendar folder
            movedItem = this.MoveSingleCalendarItem(Role.Attendee, canceledMeeting.ItemId, msgTargetFolder);

            Site.Assert.AreEqual<ResponseClassType>(
                ResponseClassType.Success,
                movedItem.ResponseClass,
                "EWS should return success for moving the meeting cancellation message.");
            #endregion

            #region Attendee calls FindItem to verify the meeting cancellation message is moved to Calendar folder
            canceledMeeting = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Schedule.Meeting.Canceled", meetingItem.UID) as MeetingCancellationMessageType;
            Site.Assert.IsNotNull(canceledMeeting, "The meeting cancellation message should be in attendee's calendar folder.");
            #endregion

            #region Attendee removes the meeting item
            RemoveItemType removeItem = new RemoveItemType();
            removeItem.ReferenceItemId = canceledMeeting.ItemId;
            item = this.CreateSingleCalendarItem(Role.Attendee, removeItem, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(item, "The meeting item should be removed.");
            #endregion

            #region Clean up organizer's calendar and deleteditems folders, and attendee's sentitems and deleteditems folders
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems });
            #endregion
        }
        public void MSOXWSMTGS_S03_TC02_CopySingleMeetingItem()
        {
            #region Organizer creates a single meeting getItem with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            CalendarItemType meetingItem = new CalendarItemType();
            meetingItem.Subject = this.Subject;
            meetingItem.UID = Guid.NewGuid().ToString();
            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meetingItem.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };

            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "Create single meeting item should be successful.");
            #endregion

            #region Organizer copies the created single meeting item to Drafts folder
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The created calendar should exist in organizer's calendar folder.");
            ItemIdType itemId = calendar.ItemId;

            DistinguishedFolderIdType folderId = new DistinguishedFolderIdType();
            folderId.Id = DistinguishedFolderIdNameType.drafts;
            TargetFolderIdType targetFolderId = new TargetFolderIdType();
            targetFolderId.Item = folderId;

            ItemInfoResponseMessageType copiedItem = this.CopySingleCalendarItem(Role.Organizer, itemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, @"Copy the single meeting item should be successful.");
            #endregion

            #region Organizer calls GetItem operation to verify whether the meeting item is really copied
            calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.drafts, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The copied calendar should exist in organizer's Drafts folder.");
            #endregion

            #region Attendee gets the meeting request message in the Inbox folder
            MeetingRequestMessageType request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, meetingItem.Subject, meetingItem.UID, UnindexedFieldURIType.itemSubject) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(request, "The meeting request message should exist in attendee's inbox folder.");
            #endregion

            #region Attendee copies the meeting request message to the Drafts folder
            copiedItem = this.CopySingleCalendarItem(Role.Attendee, request.ItemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, @"Copy the single meeting request message should be successful.");
            #endregion

            #region Attendee calls CreateItem to accept the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            AcceptItemType acceptItem = new AcceptItemType();
            acceptItem.ReferenceItemId = request.ItemId;

            Site.Assert.IsNotNull(
                this.CreateSingleCalendarItem(Role.Attendee, acceptItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll),
                "Attendee creates items for meeting request should succeed.");
            #endregion

            #region Organizer finds the meeting response message in his Inbox folder and copies it to the Drafts folder
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The response message from Attendee should be in organizer's Inbox folder.");

            copiedItem = this.CopySingleCalendarItem(Role.Organizer, response.ItemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, @"Copy the single meeting response message should be successful.");
            #endregion

            #region Organizer deletes the meeting item with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            ResponseMessageType deletedItem = this.DeleteSingleCalendarItem(Role.Organizer, itemId, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(deletedItem, @"Delete the single meeting item should be successful.");
            #endregion

            #region Attendee finds the meeting cancellation message in the Inbox folder and copies it to the Drafts folder
            int upperBound = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));
            int waitTime = int.Parse(Common.GetConfigurationPropertyValue("WaitTime", this.Site));
            int count = 1;

            MeetingCancellationMessageType canceledItem = null;

            while (canceledItem == null && count++ <= upperBound)
            {
                canceledItem = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Canceled", meetingItem.UID) as MeetingCancellationMessageType;
                System.Threading.Thread.Sleep(waitTime);
            }

            Site.Assert.IsNotNull(canceledItem, "The cancellation meeting message should be in attendee's Inbox folder.");

            ItemIdType canceledItemId = canceledItem.ItemId;
            copiedItem = this.CopySingleCalendarItem(Role.Attendee, canceledItemId, targetFolderId);
            Site.Assert.IsNotNull(copiedItem, "Attendee should copy the meeting cancellation message to the Drafts folder.");
            #endregion

            #region Clean up inbox, drafts and deleteditems folders of both organizer and attendee. Attendee's sentitems and calendar should also be cleaned up.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.drafts, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.drafts, DistinguishedFolderIdNameType.deleteditems });
            #endregion
        }
        public void MSOXWSMTGS_S01_TC23_CreateItemErrorMessageDispositionRequired()
        {
            #region Define a meeting to be created
            int timeInterval = this.TimeInterval;
            CalendarItemType meetingItem = new CalendarItemType();
            meetingItem.UID = Guid.NewGuid().ToString();
            meetingItem.Subject = this.Subject;
            meetingItem.Start = DateTime.Now.AddHours(timeInterval);
            meetingItem.StartSpecified = true;
            timeInterval++;
            meetingItem.End = DateTime.Now.AddHours(timeInterval);
            meetingItem.EndSpecified = true;
            meetingItem.Location = this.Location;
            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            #endregion

            #region Organizer creates a meeting with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "The meeting should be created successfully.");
            #endregion

            #region Attendee gets the meeting request message in the inbox
            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 calls CreateItem to accept the meeting request without setting MessageDisposition
            AcceptItemType acceptItem = new AcceptItemType();
            acceptItem.ReferenceItemId = new ItemIdType();
            acceptItem.ReferenceItemId.Id = request.ItemId.Id;
            NonEmptyArrayOfAllItemsType allItemArray = new NonEmptyArrayOfAllItemsType();
            allItemArray.Items = new ItemType[] { acceptItem };
            CreateItemType createItemRequest = new CreateItemType();
            createItemRequest.Items = allItemArray;
            createItemRequest.SendMeetingInvitationsSpecified = true;
            createItemRequest.SendMeetingInvitations = CalendarItemCreateOrDeleteOperationType.SendOnlyToAll;
            CreateItemResponseType createItemResponse = this.MTGSAdapter.CreateItem(createItemRequest);

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1342
            this.Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                ResponseCodeType.ErrorMessageDispositionRequired,
                createItemResponse.ResponseMessages.Items[0].ResponseCode,
                1342,
                @"[In Messages] ErrorMessageDispositionRequired:This error code MUST be returned under the following conditions: 
                  [When the item that is being created or updated is a MessageType object. ]
                  For the CancelCalendarItemType, AcceptItemType, DeclineItemType, or TentativelyAcceptItemType response objects.");
            #endregion

            #region Attendee calls CreateItem to tentatively accept the meeting request without setting MessageDisposition
            TentativelyAcceptItemType tentativelyAcceptItem = new TentativelyAcceptItemType();
            tentativelyAcceptItem.ReferenceItemId = new ItemIdType();
            tentativelyAcceptItem.ReferenceItemId.Id = request.ItemId.Id;
            allItemArray = new NonEmptyArrayOfAllItemsType();
            allItemArray.Items = new ItemType[] { tentativelyAcceptItem };
            createItemRequest = new CreateItemType();
            createItemRequest.Items = allItemArray;
            createItemRequest.SendMeetingInvitationsSpecified = true;
            createItemRequest.SendMeetingInvitations = CalendarItemCreateOrDeleteOperationType.SendOnlyToAll;
            createItemResponse = this.MTGSAdapter.CreateItem(createItemRequest);

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1342
            this.Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                ResponseCodeType.ErrorMessageDispositionRequired,
                createItemResponse.ResponseMessages.Items[0].ResponseCode,
                1342,
                @"[In Messages] ErrorMessageDispositionRequired:This error code MUST be returned under the following conditions: 
                  [When the item that is being created or updated is a MessageType object. ]
                  For the CancelCalendarItemType, AcceptItemType, DeclineItemType, or TentativelyAcceptItemType response objects.");
            #endregion

            #region Organizer cancels the meeting without setting MessageDisposition
            this.SwitchMTGSUser(Role.Organizer);
            CancelCalendarItemType cancelMeetingItem = new CancelCalendarItemType();
            cancelMeetingItem.ReferenceItemId = item.Items.Items[0].ItemId;
            allItemArray = new NonEmptyArrayOfAllItemsType();
            allItemArray.Items = new ItemType[] { cancelMeetingItem };
            createItemRequest = new CreateItemType();
            createItemRequest.Items = allItemArray;
            createItemRequest.SendMeetingInvitationsSpecified = true;
            createItemRequest.SendMeetingInvitations = CalendarItemCreateOrDeleteOperationType.SendOnlyToAll;
            createItemResponse = this.MTGSAdapter.CreateItem(createItemRequest);

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1342
            this.Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                ResponseCodeType.ErrorMessageDispositionRequired,
                createItemResponse.ResponseMessages.Items[0].ResponseCode,
                1342,
                @"[In Messages] ErrorMessageDispositionRequired:This error code MUST be returned under the following conditions: 
                  [When the item that is being created or updated is a MessageType object. ]
                  For the CancelCalendarItemType, AcceptItemType, DeclineItemType, or TentativelyAcceptItemType response objects.");
            #endregion

            #region Clean up organizer's calendar folder, and attendee's inbox and calendar folders
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.calendar });
            #endregion
        }
        public void MSOXWSMTGS_S01_TC02_CreateAndAcceptMeeting()
        {
            #region Define a meeting to be created
            int timeInterval = this.TimeInterval;
            CalendarItemType meetingItem = new CalendarItemType();
            meetingItem.UID = Guid.NewGuid().ToString();
            meetingItem.Subject = this.Subject;
            meetingItem.Start = DateTime.Now.AddHours(timeInterval);

            // Indicates the Start property is serialized in the SOAP message.
            meetingItem.StartSpecified = true;
            timeInterval++;
            meetingItem.End = DateTime.Now.AddHours(timeInterval);
            meetingItem.EndSpecified = true;
            meetingItem.Location = this.Location;
            meetingItem.When = string.Format("{0} to {1}", meetingItem.Start.ToString(), meetingItem.End.ToString());
            meetingItem.IsAllDayEvent = true;
            meetingItem.IsAllDayEventSpecified = true;
            meetingItem.IsResponseRequested = true;
            meetingItem.IsResponseRequestedSpecified = true;
            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            if (Common.IsRequirementEnabled(2301, this.Site))
            {
                meetingItem.IsOnlineMeeting = true;
                meetingItem.IsOnlineMeetingSpecified = true;
            }
			
            meetingItem.AllowNewTimeProposal = true;
            meetingItem.AllowNewTimeProposalSpecified = true;
            meetingItem.ConferenceType = 1;
            meetingItem.ConferenceTypeSpecified = true;
            meetingItem.MeetingWorkspaceUrl = this.MeetingWorkspace;
            meetingItem.NetShowUrl = this.NetShowLocation;
            meetingItem.LegacyFreeBusyStatus = LegacyFreeBusyType.Tentative;
            meetingItem.LegacyFreeBusyStatusSpecified = true;
            #endregion

            #region Organizer creates a meeting with CalendarItemCreateOrDeleteOperationType value set to SendToAllAndSaveCopy
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meetingItem, CalendarItemCreateOrDeleteOperationType.SendToAllAndSaveCopy);
            Site.Assert.IsNotNull(item, "The meeting should be created successfully.");

            Site.Assert.IsNotNull(
                this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.sentitems, "IPM.Schedule.Meeting.Request", meetingItem.UID),
                "The meeting request message should be saved to organizer's Sent Items folder after call CreateItem with CalendarItemCreateOrDeleteOperationType set to SendToAllAndSaveCopy.");

            ItemIdType meetingId = item.Items.Items[0].ItemId;

            CalendarItemType calendarInOrganizer = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendarInOrganizer, "The meeting should be found in organizer's Calendar folder after organizer calls CreateItem with CalendarItemCreateOrDeleteOperationType set to SendToAllAndSaveCopy.");

            if (Common.IsRequirementEnabled(1282, this.Site))
            {
                Site.Assert.IsTrue(calendarInOrganizer.RequiredAttendees[0].ResponseTypeSpecified, "Element ResponseType should be present.");

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R79
                this.Site.CaptureRequirementIfAreEqual<ResponseTypeType>(
                    ResponseTypeType.Unknown,
                    calendarInOrganizer.RequiredAttendees[0].ResponseType,
                    79,
                    @"[In t:ResponseTypeType Simple Type] Unknown: Indicates that the recipient's response to the meeting is unknown.");
            }
            #endregion

            #region Organizer gets the created meeting
            MeetingRequestMessageType meetingRequest = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.sentitems, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(meetingRequest, "The meeting request message should be found in organizer's Sent Items folder after organizer calls CreateItem with CalendarItemCreateOrDeleteOperationType set to SendToAllAndSaveCopy.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R317
            this.Site.CaptureRequirementIfAreEqual<string>(
                this.RoomEmailAddress.ToLower(),
                meetingRequest.OptionalAttendees[0].Mailbox.EmailAddress.ToLower(),
                317,
                @"[In t:MeetingRequestMessageType Complex Type] OptionalAttendees: Represents attendees who are not required to attend the meeting.");
            #endregion

            #region Attendee gets the meeting request message in the inbox and calendar folders respectively
            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 SendToAllAndSaveCopy.");

            #region Capture Code

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

            // Verify MS-OXWSCORE requirement: MS-OXWSMTGS_R299
            this.Site.CaptureRequirementIfIsNull(
                request.When,
                299,
                @"[In t:MeetingRequestMessageType Complex Type] When: Provides information about when the meeting occurs and is not populated to attendee's mailbox.");

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

            // Verify MS-OXWSCORE requirement: MS-OXWSMTGS_R319
            this.Site.CaptureRequirementIfIsNull(
                request.Resources,
                319,
                @"[In t:MeetingRequestMessageType Complex Type] Resources: Represents a scheduled resource for the meeting and is not populated to attendee's mailbox.");

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

                // Verify MS-OXWSCORE requirement: MS-OXWSMTGS_R1282
                this.Site.CaptureRequirementIfIsTrue(
                    request.ResponseTypeSpecified,
                    1282,
                    @"[In Appendix C: Product Behavior] Implementation does support ResponseType if the recipient has not yet responded to the meeting request. (Exchange 2007, Exchange 2013 and above follow this behavior.)");
            }

            if (Common.IsRequirementEnabled(1292, this.Site))
            {
                foreach (ResponseObjectType responseObject in request.ResponseObjects)
                {
                    if (responseObject.GetType() == typeof(ProposeNewTimeType))
                    {
                        // Add the debug information
                        this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R1292");

                        // Verify MS-OXWSCORE requirement: MS-OXWSMTGS_R1292
                        // Element ProposeNewTime is returned from server, this requirement can be captured directly.
                        this.Site.CaptureRequirement(
                            1292,
                            @"[In Appendix C: Product Behavior] Implementation does support the ProposeNewTimeType which specifies a response to a new time proposal. (This type was introduced in Exchange 2013 SP1.)");

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

                        // Verify MS-OXWSCORE requirement: MS-OXWSMTGS_R1107
                        // Element ProposeNewTime is returned from server and passes schema validation, this requirement can be captured directly.
                        this.Site.CaptureRequirement(
                            1107,
                            @"[In t:ProposeNewTimeType Complex Type] This type [ProposeNewTimeType] extends the ResponseObjectType complex type ([MS-OXWSCDATA] section 2.2.4.65).");

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

                        // Verify MS-OXWSCORE requirement: MS-OXWSMTGS_R1355
                        // Element ProposeNewTime is returned from server and passes schema validation, this requirement can be captured directly.
                        this.Site.CaptureRequirement(
                            1355,
                            @"[In t:ProposeNewTimeType Complex Type] [its schema is] <xs:complexType name=""ProposeNewTimeType"">
                          <xs:complexContent>
                              <xs:extension base=""t:ResponseObjectType""/>
                              </xs:complexContent>
                          </xs:complexType>");
                        break;
                    }
                }
            }

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R488
            this.Site.CaptureRequirementIfAreEqual<string>(
                "IPM.Schedule.Meeting.Request",
                request.ItemClass,
                488,
                "[In CreateItem Operation] This operation [CreateItem] can be used to create meeting request messages.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R28504
            this.Site.CaptureRequirementIfAreEqual<LegacyFreeBusyType>(
                LegacyFreeBusyType.Tentative,
                request.IntendedFreeBusyStatus,
                28504,
                @"[In t:MeetingRequestMessageType Complex Type] The IntendedFreeBusyStatus which value is ""Tentative"" specifies the status as tentative.");

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R35501
                this.Site.CaptureRequirementIfAreEqual<int>(
                    meetingItem.ConferenceType,
                    request.ConferenceType,
                    35501,
                    @"[In t:MeetingRequestMessageType Complex Type] The value of ""ConferenceType"" is ""1"" describes the type of conferencing is presentation");
            }
            #endregion

            AcceptItemType acceptItem = new AcceptItemType();
            acceptItem.ReferenceItemId = new ItemIdType();
            acceptItem.ReferenceItemId.Id = request.ItemId.Id;
            if (Common.IsRequirementEnabled(1284, this.Site))
            {
                acceptItem.ProposedStart = DateTime.Now;
                acceptItem.ProposedStartSpecified = true;
                acceptItem.ProposedEnd = DateTime.Now.AddHours(1);
                acceptItem.ProposedEndSpecified = true;
            }

            CalendarItemType 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 calls CreateItem with CalendarItemCreateOrDeleteOperationType set to SendToAllAndSaveCopy.");

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

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

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1047
            this.Site.CaptureRequirementIfIsNull(
                calendar.When,
                1047,
                @"[In t:CalendarItemType Complex Type] [When] is not populated to attendee's mailbox.");

            if (Common.IsRequirementEnabled(1282, this.Site))
            {
                Site.Assert.IsTrue(calendar.MyResponseTypeSpecified, "Element MyResponseType should be present.");

                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "VerifyMS-OXWSMTGS_R84");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R84
                this.Site.CaptureRequirementIfAreEqual<ResponseTypeType>(
                    ResponseTypeType.NoResponseReceived,
                    calendar.MyResponseType,
                    84,
                    @"[In t:ResponseTypeType Simple Type] NoResponseReceived: Indicates that the recipient has not yet responded to the meeting request.");
            }
            #endregion

            #region Attendee calls CreateItem to accept the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            item = this.CreateSingleCalendarItem(Role.Attendee, acceptItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "Accept the meeting request should be successful.");
            #endregion

            #region Organizer gets the meeting response message in the Inbox folder
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The meeting response from Attendee should be existed.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R489
            this.Site.CaptureRequirementIfAreEqual<string>(
                "IPM.Schedule.Meeting.Resp.Pos",
                response.ItemClass,
                489,
                "[In CreateItem Operation] This operation [CreateItem] can be used to create meeting response messages.");
            #endregion

            #region Organizer gets the calendar in the Calendar folder
            calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R139
            this.Site.CaptureRequirementIfAreEqual<ResponseTypeType>(
                ResponseTypeType.Accept,
                calendar.RequiredAttendees[0].ResponseType,
                139,
                "[In t:AttendeeType Complex Type]ResponseType: Specifies the meeting invitation response received for by the meeting organizer from a meeting attendee.");
            
            if (Common.IsRequirementEnabled(1334, this.Site))
            {
                this.Site.Assert.IsTrue(calendar.RequiredAttendees[0].ProposedStartSpecified, "ProposedStart element in AttendeeType should be returned.");

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1334
                this.Site.CaptureRequirementIfAreEqual<string>(
                    acceptItem.ProposedStart.ToString(),
                    calendar.RequiredAttendees[0].ProposedStart.ToString(),
                    1334,
                    "[In Appendix C: Product Behavior] Implementation does support the ProposedStart element which specifies the proposed start date and time of the meeting. (This type was introduced in Exchange 2013 SP1.)");
            }

            if (Common.IsRequirementEnabled(1336, this.Site))
            {
                this.Site.Assert.IsTrue(calendar.RequiredAttendees[0].ProposedEndSpecified, "ProposedEnd element in AttendeeType should be returned.");

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1336
                this.Site.CaptureRequirementIfAreEqual<string>(
                    acceptItem.ProposedEnd.ToString(),
                    calendar.RequiredAttendees[0].ProposedEnd.ToString(),
                    1336,
                    "[In Appendix C: Product Behavior] Implementation does support the ProposedEnd element which specifies the proposed end date and time of the meeting. (This type was introduced in Exchange 2013 SP1.)");
            }

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R1284
                // Elements in MeetingRegistrationResponseObjectType are set in request and the operation calls successfully,
                // so this requirement can be captured directly.
                this.Site.CaptureRequirement(
                    1284,
                    "[In Appendix C: Product Behavior] Implementation does support the MeetingRegistrationResponseObjectType complex type which specifies a response to a meeting registration request. (This type was introduced in Exchange 2013 SP1.)");
            }

            request = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.sentitems, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;
            Site.Assert.IsTrue(request.IsDelegatedSpecified, "Element IsDelegated should be present.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R749
            this.Site.CaptureRequirementIfIsFalse(
                request.IsDelegated,
                749,
                "[In t:MeetingMessageType Complex Type]otherwise [if a meeting was not handled by an account that has delegate access], [IsDelegated is] false.");
            #endregion

            #region Organizer deletes the meeting with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            ResponseMessageType deletedItem = this.DeleteSingleCalendarItem(Role.Organizer, meetingId, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(deletedItem, "Organizer should delete the calendar successfully.");
            #endregion

            #region Attendee finds the meeting cancellation message from his Inbox folder
            MeetingCancellationMessageType cancelledMessage = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Canceled", meetingItem.UID) as MeetingCancellationMessageType;
            Site.Assert.IsNotNull(cancelledMessage, "Attendee should receive a meeting cancellation message after organizer calls DeleteItem with CalendarItemCreateOrDeleteOperationType set to SendOnlyToAll.");

            ItemIdType removeItemId = cancelledMessage.ItemId;
            RemoveItemType removeItem = new RemoveItemType();
            removeItem.ReferenceItemId = removeItemId;

            item = this.CreateSingleCalendarItem(Role.Attendee, removeItem, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(item, "The canceled message should be removed successfully.");
            #endregion

            #region Organizer checks whether the meeting cancellation message is saved to organizer's Sent Items folder
            MeetingCancellationMessageType cancelledMeeting = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.sentitems, "IPM.Schedule.Meeting.Canceled", meetingItem.UID) as MeetingCancellationMessageType;
            Site.Assert.IsNull(cancelledMeeting, "The meeting cancellation message should not be saved to organizer's Sent Items folder.");
            #endregion

            #region Clean up organizer's inbox, sentitems and deleteditems folders, and attendee's 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.sentitems, DistinguishedFolderIdNameType.deleteditems });
            #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_S01_TC08_CreateAndAcceptSingleMeeting()
        {
            #region Organizer creates a meeting
            #region Set the properties of the meeting to create
            CalendarItemType meeting = new CalendarItemType();
            meeting.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meeting.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meeting.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };

            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.LegacyFreeBusyStatus = LegacyFreeBusyType.Busy;
            meeting.LegacyFreeBusyStatusSpecified = true;
            meeting.Location = this.Location;
            meeting.When = string.Format("{0} to {1}", meeting.Start.ToString(), meeting.End.ToString());
            meeting.IsAllDayEvent = false;
            meeting.IsAllDayEventSpecified = true;
            meeting.IsResponseRequested = true;
            meeting.IsResponseRequestedSpecified = true;
            if (Common.IsRequirementEnabled(2301, this.Site))
            {
                meeting.IsOnlineMeeting = true;
                meeting.IsOnlineMeetingSpecified = true;
            }
			
            meeting.ConferenceType = 2;
            meeting.ConferenceTypeSpecified = true;
            meeting.AllowNewTimeProposal = true;
            meeting.AllowNewTimeProposalSpecified = true;
            meeting.MeetingWorkspaceUrl = this.MeetingWorkspace;
            meeting.NetShowUrl = this.NetShowLocation;
            #endregion

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

            #region Get and verify the CalendarItemType of created meeting
            ItemInfoResponseMessageType getItem = this.GetSingleCalendarItem(Role.Organizer, item.Items.Items[0].ItemId);
            Site.Assert.IsNotNull(getItem, "The created calendar should exist.");

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

            #region Verify the child elements of CalendarItemType
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R151");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R151
            // The UID of the meeting item was created with System.Guid.NewGuid() method that can guarantee the uniqueness.
            this.Site.CaptureRequirementIfAreEqual<string>(
                meeting.UID,
                createdCalendarItem.UID,
                151,
                @"[In t:CalendarItemType Complex Type] UID: Contains the unique identifier for the calendar item.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R157
            this.Site.CaptureRequirementIfAreEqual<DateTime>(
                meeting.Start.Date,
                createdCalendarItem.Start.Date,
                157,
                @"[In t:CalendarItemType Complex Type] Start: Specifies the start date and time of a duration.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R159
            this.Site.CaptureRequirementIfAreEqual<DateTime>(
                meeting.End.Date,
                createdCalendarItem.End.Date,
                159,
                @"[In t:CalendarItemType Complex Type] End: Specifies the end date and time of a duration.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R721
            this.Site.CaptureRequirementIfIsFalse(
                createdCalendarItem.IsAllDayEvent,
                721,
                @"[In t:CalendarItemType Complex Type] otherwise [if calendar item or meeting request does not represent an all-day event], [IsAllDayEvent is] false.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R16500
            this.Site.CaptureRequirementIfAreEqual(
                LegacyFreeBusyType.Busy,
                createdCalendarItem.LegacyFreeBusyStatus,
                16500,
                @"[In t:CalendarItemType Complex Type] The LegacyFreeBusyStatus which value is ""Busy"" specifies the status as busy.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R167
            this.Site.CaptureRequirementIfAreEqual<string>(
                meeting.Location.ToLower(),
                createdCalendarItem.Location.ToLower(),
                167,
                @"[In t:CalendarItemType Complex Type] Location: Specifies the location of a meeting or appointment.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R169
            this.Site.CaptureRequirementIfAreEqual<string>(
                meeting.When,
                createdCalendarItem.When,
                169,
                @"[In t:CalendarItemType Complex Type] When: Provides information about when a calendar or meeting item occurs.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R728
            this.Site.CaptureRequirementIfIsTrue(
                createdCalendarItem.IsMeeting,
                728,
                @"[In t:CalendarItemType Complex Type] [IsMeeting is] True if the calendar item is a meeting or appointment.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R731
            this.Site.CaptureRequirementIfIsFalse(
                createdCalendarItem.IsCancelled,
                731,
                @"[In t:CalendarItemType Complex Type] otherwise [if a meeting has not been canceled], [IsCancelled is] false.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R733
            this.Site.CaptureRequirementIfIsFalse(
                createdCalendarItem.IsRecurring,
                733,
                @"[In t:CalendarItemType Complex Type] otherwise [if a calendar item is not part of a recurring item], [IsRecurring is] false.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R734
            this.Site.CaptureRequirementIfIsTrue(
                createdCalendarItem.MeetingRequestWasSent,
                734,
                @"[In t:CalendarItemType Complex Type] [MeetingRequestWasSent is] True, if meeting request has been sent to requested attendees, including required and optional attendees, and resources.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R736
            this.Site.CaptureRequirementIfIsTrue(
                createdCalendarItem.IsResponseRequested,
                736,
                @"[In t:CalendarItemType Complex Type] [IsResponseRequested is] True, if a response to an item is requested.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R512, "Organizer" specified that the recipient is the meeting organizer in this calendar item currently.
            this.Site.CaptureRequirementIfAreEqual<ResponseTypeType>(
                ResponseTypeType.Organizer,
                createdCalendarItem.MyResponseType,
                512,
                @"[In t:CalendarItemType Complex Type] MyResponseType: Specifies the status of the response to a calendar item.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R80
            this.Site.CaptureRequirementIfAreEqual<ResponseTypeType>(
                ResponseTypeType.Organizer,
                createdCalendarItem.MyResponseType,
                80,
                @"[In t:ResponseTypeType Simple Type] Organizer: Indicates that the recipient is the meeting organizer.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R181
            this.Site.CaptureRequirementIfAreEqual<CalendarItemTypeType>(
                CalendarItemTypeType.Single,
                createdCalendarItem.CalendarItemType1,
                181,
                @"[In t:CalendarItemType Complex Type] CalendarItemType: Specifies the occurrence type of a calendar item.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R185
            this.Site.CaptureRequirementIfAreEqual<string>(
                this.OrganizerEmailAddress.ToLower(),
                createdCalendarItem.Organizer.Item.EmailAddress.ToLower(),
                185,
                @"[In t:CalendarItemType Complex Type] Organizer: Specifies the organizer of a meeting.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R187
            this.Site.CaptureRequirementIfAreEqual<string>(
                this.AttendeeEmailAddress.ToLower(),
                createdCalendarItem.RequiredAttendees[0].Mailbox.EmailAddress.ToLower(),
                187,
                @"[In t:CalendarItemType Complex Type] RequiredAttendees: Specifies attendees that are required to attend a meeting.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R189
            this.Site.CaptureRequirementIfAreEqual<string>(
                this.OrganizerEmailAddress.ToLower(),
                createdCalendarItem.OptionalAttendees[0].Mailbox.EmailAddress.ToLower(),
                189,
                @"[In t:CalendarItemType Complex Type] OptionalAttendees: Specifies attendees who are not required to attend a meeting.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R191
            this.Site.CaptureRequirementIfAreEqual<string>(
                this.RoomEmailAddress.ToLower(),
                createdCalendarItem.Resources[0].Mailbox.EmailAddress.ToLower(),
                191,
                @"[In t:CalendarItemType Complex Type] Resources: Specifies a scheduled resource for a meeting and is not populated to attendee's mailbox.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R209, "1" specified the calendar item on the organizer's calendar represents a meeting
            this.Site.CaptureRequirementIfAreEqual<int>(
                1,
                createdCalendarItem.AppointmentState,
                209,
                @"[In t:CalendarItemType Complex Type] AppointmentState: Specifies the status of the appointment.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R738
            this.Site.CaptureRequirementIfAreEqual<int>(
                1,
                createdCalendarItem.AppointmentState,
                738,
                @"[In t:CalendarItemType Complex Type] [AppointmentState: Valid values include:] 1: the calendar item on the organizer's calendar represents a meeting");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R227
            this.Site.CaptureRequirementIfAreEqual<int>(
                meeting.ConferenceType,
                createdCalendarItem.ConferenceType,
                227,
                @"[In t:CalendarItemType Complex Type]ConferenceType: Specifies the type of conferencing that is performed with a calendar item.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R743
            this.Site.CaptureRequirementIfAreEqual<int>(
                2,
                createdCalendarItem.ConferenceType,
                743,
                @"[In t:CalendarItemType Complex Type] [ConferenceType: Valid values include:] 2: chat");

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R2301
                this.Site.CaptureRequirementIfIsNotNull(
                    createdCalendarItem.IsOnlineMeeting,
                    2301,
                    @"[In Appendix C: Product Behavior] Implementation does support the IsOnlineMeeting element. (Exchange 2007, Exchange 2010 and Exchange 2013 support the IsOnlineMeeting element.)");

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R746
                this.Site.CaptureRequirementIfIsTrue(
                    createdCalendarItem.IsOnlineMeeting,
                    746,
                    @"[In t:CalendarItemType Complex Type] [IsOnlineMeeting is] True, if the meeting is online.");
            }

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R233
            this.Site.CaptureRequirementIfAreEqual<string>(
                meeting.MeetingWorkspaceUrl.ToLower(),
                createdCalendarItem.MeetingWorkspaceUrl.ToLower(),
                233,
                @"[In t:CalendarItemType Complex Type] MeetingWorkspaceUrl: Contains the URL for the Meeting Workspace that is included in the calendar item.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R235
            this.Site.CaptureRequirementIfAreEqual<string>(
                meeting.NetShowUrl,
                createdCalendarItem.NetShowUrl,
                235,
                @"[In t:CalendarItemType Complex Type] NetShowUrl: Specifies the URL for an online meeting.");

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R699
                this.Site.CaptureRequirementIfAreEqual<DateTime>(
                    meeting.Start.Date,
                    createdCalendarItem.StartWallClock.Date,
                    699,
                    @"[In Appendix C: Product Behavior] Implementation does support complex type ""StartWallClock"" with type ""xs:dateTime"" which specifies the start time of the calendar item. (Exchange 2013 and above follow this behavior.)");
            }

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R700
                this.Site.CaptureRequirementIfAreEqual<DateTime>(
                    meeting.End.Date,
                    createdCalendarItem.EndWallClock.Date,
                    700,
                    @"[In Appendix C: Product Behavior] Implementation does support complex type ""EndWallClock"" with type ""xs:dateTime"" which specifies the ending time of the calendar item. (Exchange 2013 and above follow this behavior.)");
            }

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R80048
                this.Site.CaptureRequirementIfIsTrue(
                    createdCalendarItem.IsOrganizer && createdCalendarItem.IsOrganizerSpecified,
                    80048,
                    @"[In Appendix C: Product Behavior] Implementation does support complex type ""IsOrganizer"" with type ""xs:boolean"" which specifies whether the current user is the organizer and/or owner of the calendar item. (Exchange 2013 and above follow this behavior.)");
            }
            #endregion
            #endregion
            #endregion

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

            #region Verify the child elements of MeetingRequestMessageType and MeetingMessageType
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R756");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R756
            this.Site.CaptureRequirementIfIsTrue(
                receivedRequest.IsMeeting,
                756,
                @"[In t:MeetingRequestMessageType Complex Type] [IsMeeting is] True, if the calendar item is a meeting or an appointment.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R759
            this.Site.CaptureRequirementIfIsFalse(
                receivedRequest.IsCancelled,
                759,
                @"[In t:MeetingRequestMessageType Complex Type] otherwise [if the meeting has not been cancelled], [IsCancelled is] false.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R761
            this.Site.CaptureRequirementIfIsFalse(
                receivedRequest.IsRecurring,
                761,
                @"[In t:MeetingRequestMessageType Complex Type] otherwise [if the meeting is not part of a recurring series of meetings], [IsRecurring is] false.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R762
            this.Site.CaptureRequirementIfIsTrue(
                receivedRequest.MeetingRequestWasSent,
                762,
                @"[In t:MeetingRequestMessageType Complex Type] [MeetingRequestWasSent is] True, if a meeting request has been sent to requested attendees.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R763
            this.Site.CaptureRequirementIfIsTrue(
                receivedRequest.MeetingRequestWasSent,
                763,
                @"[In t:MeetingRequestMessageType Complex Type]This element [MeetingRequestWasSent] is always ""true"".");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R309, "Single" Specifies that the item is not associated with a recurring calendar item.
            this.Site.CaptureRequirementIfAreEqual<CalendarItemTypeType>(
                CalendarItemTypeType.Single,
                receivedRequest.CalendarItemType,
                309,
                @"[In t:MeetingRequestMessageType Complex Type] CalendarItemType: Represents the occurrence type of a meeting item.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R53
            this.Site.CaptureRequirementIfAreEqual<CalendarItemTypeType>(
                CalendarItemTypeType.Single,
                receivedRequest.CalendarItemType,
                53,
                @"[In t:CalendarItemTypeType Simple Type] Single: Specifies that the item is not associated with a recurring calendar item.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R313
            this.Site.CaptureRequirementIfAreEqual<string>(
                this.OrganizerEmailAddress.ToLower(),
                receivedRequest.Organizer.Item.EmailAddress.ToLower(),
                313,
                @"[In t:MeetingRequestMessageType Complex Type] Organizer: Represents the organizer of the meeting.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R337, "3" specified the organizer's meeting request has been sent; the attendee's meeting request has been received
            this.Site.CaptureRequirementIfAreEqual<int>(
                3,
                receivedRequest.AppointmentState,
                337,
                @"[In t:MeetingRequestMessageType Complex Type] AppointmentState: Specifies the status of the appointment.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R555
            this.Site.CaptureRequirementIfAreEqual<int>(
                3,
                receivedRequest.AppointmentState,
                555,
                @"[In t:MeetingRequestMessageType Complex Type] [AppointmentState's] Valid values include:
3: the organizer's meeting request has been sent; the attendee's meeting request has been received");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R283, NewMeetingRequest identifies the meeting request as a new meeting request.
            this.Site.CaptureRequirementIfAreEqual<MeetingRequestTypeType>(
                MeetingRequestTypeType.NewMeetingRequest,
                receivedRequest.MeetingRequestType,
                283,
                @"[In t:MeetingRequestMessageType Complex Type] MeetingRequestType: Specifies the type of meeting request.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R72
            this.Site.CaptureRequirementIfAreEqual<MeetingRequestTypeType>(
                MeetingRequestTypeType.NewMeetingRequest,
                receivedRequest.MeetingRequestType,
                72,
                @"[In t:MeetingRequestTypeType Simple Type] NewMeetingRequest: Identifies the meeting request as a new meeting request.");

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

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

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R500
            this.Site.CaptureRequirementIfAreEqual<DateTime>(
                meeting.Start.Date,
                receivedRequest.Start.Date,
                500,
                @"[In t:MeetingRequestMessageType Complex Type] Start: Represents the start time of the meeting.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R287
            this.Site.CaptureRequirementIfAreEqual<DateTime>(
                meeting.End.Date,
                receivedRequest.End.Date,
                287,
                @"[In t:MeetingRequestMessageType Complex Type] End: Specifies the end of the duration for a single occurrence of a meeting.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R297
            this.Site.CaptureRequirementIfAreEqual<string>(
                meeting.Location.ToLower(),
                receivedRequest.Location.ToLower(),
                297,
                @"[In t:MeetingRequestMessageType Complex Type] Location: Represents the location of the meeting.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R755
            this.Site.CaptureRequirementIfIsFalse(
                receivedRequest.IsAllDayEvent,
                755,
                @"[In t:MeetingRequestMessageType Complex Type] otherwise [if the meeting is not an all-day event], [IsAllDayEvent is] false.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R736
            this.Site.CaptureRequirementIfIsTrue(
                receivedRequest.IsResponseRequested,
                736,
                @"[In t:CalendarItemType Complex Type] [IsResponseRequested is] True, if a response to an item is requested.");

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R766
                this.Site.CaptureRequirementIfIsTrue(
                    receivedRequest.IsOnlineMeeting,
                    766,
                    @"[In t:MeetingRequestMessageType Complex Type] [IsOnlineMeeting is] True, if the meeting is online.");

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R363
                this.Site.CaptureRequirementIfAreEqual<string>(
                    meeting.NetShowUrl.ToLower(),
                    receivedRequest.NetShowUrl.ToLower(),
                    363,
                    @"[In t:MeetingRequestMessageType Complex Type] NetShowUrl: Specifies the URL for an online meeting.");
            }

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R3541
                this.Site.CaptureRequirementIfIsNotNull(
                    receivedRequest.ConferenceType,
                    3541,
                    @"[In Appendix C: Product Behavior] Implementation does support ConferenceType 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_R35502");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R35502
                this.Site.CaptureRequirementIfAreEqual<int>(
                    meeting.ConferenceType,
                    receivedRequest.ConferenceType,
                    35502,
                    @"[In t:MeetingRequestMessageType Complex Type] The value of ""ConferenceType"" is ""2"" describes the type of conferencing is chat");
            }

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R361
            this.Site.CaptureRequirementIfAreEqual<string>(
                meeting.MeetingWorkspaceUrl.ToLower(),
                receivedRequest.MeetingWorkspaceUrl.ToLower(),
                361,
                @"[In t:MeetingRequestMessageType Complex Type] MeetingWorkspaceUrl: Contains the URL for the Meeting Workspace that is included in the meeting item.");

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

            bool isVerifyMeetingRequiredAttendees = string.Equals(receivedRequest.RequiredAttendees[0].Mailbox.EmailAddress, this.OrganizerEmailAddress, StringComparison.OrdinalIgnoreCase)
                && string.Equals(receivedRequest.RequiredAttendees[1].Mailbox.EmailAddress, this.AttendeeEmailAddress, StringComparison.OrdinalIgnoreCase)
                && receivedRequest.RequiredAttendees.Length == 2;

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R315
            this.Site.CaptureRequirementIfIsTrue(
                isVerifyMeetingRequiredAttendees,
                315,
                @"[In t:MeetingRequestMessageType Complex Type] RequiredAttendees: Represents attendees that are required to attend the meeting.");

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R708
                this.Site.CaptureRequirementIfAreEqual<DateTime>(
                    meeting.Start.Date,
                    receivedRequest.StartWallClock.Date,
                    708,
                    @"[In Appendix C: Product Behavior] Implementation does support the complex type ""StartWallClock""with type ""xs:dateTime"" which specifies the start time of the calendar item. (Exchange 2013 and above follow this behavior.)");
            }

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R709
                this.Site.CaptureRequirementIfAreEqual<DateTime>(
                    meeting.End.Date,
                    receivedRequest.EndWallClock.Date,
                    709,
                    @"[In Appendix C: Product Behavior] Implementation does support the complex type ""EndWallClock"" with type ""xs:dateTime"" which specifies the ending time of the calendar item. (Exchange 2013 and above follow this behavior.)");
            }
            #endregion

            AcceptItemType acceptItem = new AcceptItemType();
            acceptItem.ReferenceItemId = new ItemIdType();
            acceptItem.ReferenceItemId.Id = receivedRequest.ItemId.Id;
            #endregion

            #region Attendee accepts the meeting request
            item = this.CreateSingleCalendarItem(Role.Attendee, acceptItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "The response to the meeting request should be successful.");

            CalendarItemType calendar = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meeting.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The accepted calendar should be found in attendee's calendar folder.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R205
            this.Site.CaptureRequirementIfIsNotNull(
                calendar.AppointmentReplyTime,
                205,
                @"[In t:CalendarItemType Complex Type] AppointmentReplyTime: Specifies the date and time that an attendee replied to a meeting request.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R191
            this.Site.CaptureRequirementIfIsNull(
                calendar.Resources,
                191,
                @"[In t:CalendarItemType Complex Type] Resources: Specifies a scheduled resource for a meeting and is not populated to attendee's mailbox.");
            #endregion

            #region Organizer gets and checks the meeting response from attendeeType
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meeting.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "The meeting response message from attendee should exist in organizer's inbox folder.");

            #region Verify the child elements of MeetingResponseMessageType
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R82");

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

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R906
                this.Site.CaptureRequirementIfAreEqual<DateTime>(
                    meeting.Start.Date,
                    response.Start.Date,
                    906,
                    @"[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(907, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R907");

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R907
                this.Site.CaptureRequirementIfAreEqual<DateTime>(
                    meeting.End.Date,
                    response.End.Date,
                    907,
                    @"[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(908, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R908");

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

            if (Common.IsRequirementEnabled(910, this.Site))
            {
                CalendarItemTypeType actual;
                Site.Assert.IsTrue(Enum.TryParse<CalendarItemTypeType>(response.CalendarItemType, out actual), "The current value of CalendarItemType property should be one of CalendarItemTypeType enum values.");

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

                // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R910
                this.Site.CaptureRequirementIfAreEqual<CalendarItemTypeType>(
                    CalendarItemTypeType.Single,
                    actual,
                    910,
                    @"[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

            calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meeting.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The accepted calendar should be found in organizer's calendar folder.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R141
            this.Site.CaptureRequirementIfIsNotNull(
                calendar.RequiredAttendees[0].LastResponseTime,
                141,
                @"[In t:AttendeeType Complex Type]LastResponseTime: Specifies the date and time that the latest meeting invitation response was received by the meeting organizer from the meeting attendee.");
            #endregion

            #region Clean up organizer's inbox, calendar and deleteditems folders, and attendee's sentitems, calendar and deleteditems folders
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.sentitems, DistinguishedFolderIdNameType.deleteditems });
            #endregion
        }
        /// <summary>
        /// Log on to a mailbox with a specified user account and find the specified meeting message in the Inbox folder, then accept it.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="userPassword">Password of the user.</param>
        /// <param name="userDomain">Domain of the user.</param>
        /// <param name="itemSubject">Subject of the meeting message which should be accepted.</param>
        /// <param name="itemType">Type of the item which should be accepted.</param>
        /// <returns>If the specified meeting message is accepted successfully, return true; otherwise, return false.</returns>
        public bool FindAndAcceptMeetingMessage(string userName, string userPassword, string userDomain, string itemSubject, string itemType)
        {
            // Define the Inbox folder as parent folder.
            DistinguishedFolderIdNameType parentFolderIdName = DistinguishedFolderIdNameType.inbox;

            // Switch to specified user mailbox.
            bool isSwitched = AdapterHelper.SwitchUser(userName, userPassword, userDomain, this.exchangeServiceBinding, this.Site);
            Site.Assert.IsTrue(
                isSwitched,
                string.Format("Log on mailbox with the UserName: {0}, Password: {1}, Domain: {2} should be successful.", userName, userPassword, userDomain));

            Item item = (Item)Enum.Parse(typeof(Item), itemType, true);

            // Loop to find the specified item in the specified folder.
            ItemType type = this.LoopToFindItem(parentFolderIdName, itemSubject, item);
            bool isAccepted = false;
            if (type != null)
            {
                MeetingRequestMessageType message = type as MeetingRequestMessageType;

                // Create a request for the CreateItem operation.
                CreateItemType createItemRequest = new CreateItemType();

                // Add the CalendarItemType item to the items to be created.
                createItemRequest.Items = new NonEmptyArrayOfAllItemsType();

                // Create an AcceptItemType item to reply to a meeting request.
                AcceptItemType acceptItem = new AcceptItemType();

                // Set the related meeting request.
                acceptItem.ReferenceItemId = message.ItemId;
                createItemRequest.Items.Items = new ItemType[] { acceptItem };

                // Set the MessageDisposition property to SendOnly.
                createItemRequest.MessageDisposition = MessageDispositionType.SendOnly;
                createItemRequest.MessageDispositionSpecified = true;

                // Invoke the CreateItem operation.
                CreateItemResponseType createItemResponse = this.exchangeServiceBinding.CreateItem(createItemRequest);

                if (createItemResponse != null && createItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Success)
                {
                    isAccepted = true;
                }
            }

            return isAccepted;
        }
        public void MSOXWSMTGS_S02_TC10_MeetingRequestTypeInformationalUpdate()
        {
            #region Organizer creates the meeting and sends it to attendee.
            CalendarItemType meeting = new CalendarItemType();
            meeting.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meeting.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meeting.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            meeting.Subject = this.Subject;
            meeting.UID = Guid.NewGuid().ToString();
            meeting.Location = this.Location;
            meeting.IsResponseRequested = true;
            meeting.IsResponseRequestedSpecified = true;
            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Organizer, meeting, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "The meeting should be created successfully.");
            #endregion

            #region Attendee accepts the meeting request.
            MeetingRequestMessageType request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meeting.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.");

            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 Organizer updates the meeting.
            CalendarItemType calendar = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meeting.UID) as CalendarItemType;
            Site.Assert.IsNotNull(calendar, "The calendar should be created successfully.");

            CalendarItemType calendarUpdate = new CalendarItemType();
            calendarUpdate.Location = this.LocationUpdate;
            AdapterHelper locationChangeInfo = new AdapterHelper();
            locationChangeInfo.FieldURI = UnindexedFieldURIType.calendarLocation;
            locationChangeInfo.Item = new CalendarItemType() { Location = this.LocationUpdate };
            locationChangeInfo.ItemId = calendar.ItemId;
            UpdateItemResponseMessageType itemOfLocationUpdate = this.UpdateSingleCalendarItem(Role.Organizer, locationChangeInfo, CalendarItemUpdateOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(itemOfLocationUpdate, "Update the meeting item should be successful.");
            #endregion

            #region Attendee gets the meeting request.
            MeetingRequestMessageType meetingRequest = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meeting.UID) as MeetingRequestMessageType;
            Site.Assert.IsNotNull(meetingRequest, "The meeting request should exist.");
            Site.Assert.AreEqual<string>(this.LocationUpdate, meetingRequest.Location, "Location in meeting request message should be updated.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R71
            this.Site.CaptureRequirementIfAreEqual<MeetingRequestTypeType>(
                MeetingRequestTypeType.InformationalUpdate,
                meetingRequest.MeetingRequestType,
                71,
                @"[In t:MeetingRequestTypeType Simple Type] InformationUpdate: Identifies the meeting request as an updated meeting request.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R587
            // Attendee has accepted the meeting and InformationalUpdate is returned, this requirement can be captured.
            this.Site.CaptureRequirementIfAreEqual<MeetingRequestTypeType>(
                MeetingRequestTypeType.InformationalUpdate,
                meetingRequest.MeetingRequestType,
                587,
                @"[In t:MeetingRequestTypeType Simple Type] This value [InformationUpdate] indicates that the attendee had previously accepted or tentatively accepted the original meeting request.");
            #endregion

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