public void MSOXWSMTGS_S01_TC04_CreateMeetingAndTentativelyAccept()
        {
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.inbox, DistinguishedFolderIdNameType.deleteditems });

            #region Define a meeting to be created by organizer
            DateTime meetingStart = DateTime.UtcNow.AddMonths(1);
            CalendarItemType meetingItem = new CalendarItemType();
            meetingItem.UID = Guid.NewGuid().ToString();
            meetingItem.Subject = this.Subject;
            meetingItem.Start = meetingStart;
            meetingItem.StartSpecified = true;
            meetingItem.End = meetingStart.AddHours(1);
            meetingItem.EndSpecified = true;
            meetingItem.RequiredAttendees = new AttendeeType[] { GetAttendeeOrResource(this.AttendeeEmailAddress) };
            meetingItem.OptionalAttendees = new AttendeeType[] { GetAttendeeOrResource(this.OrganizerEmailAddress) };
            meetingItem.Resources = new AttendeeType[] { GetAttendeeOrResource(this.RoomEmailAddress) };
            #endregion

            #region Attendee creates calendar items for triggering the adjacent/conflicting meeting
            int timeInterval = 1;
            CalendarItemType adjacentCalendar = new CalendarItemType();
            adjacentCalendar.Subject = Common.GenerateResourceName(this.Site, "AdjacentCalendar");
            adjacentCalendar.Start = meetingStart.AddHours(timeInterval);
            adjacentCalendar.StartSpecified = true;
            timeInterval++;
            adjacentCalendar.End = meetingStart.AddHours(timeInterval);
            adjacentCalendar.EndSpecified = true;

            CalendarItemType conflictCalendar = new CalendarItemType();
            conflictCalendar.Subject = Common.GenerateResourceName(this.Site, "ConflictCalendar");
            conflictCalendar.Start = meetingStart;
            conflictCalendar.StartSpecified = true;
            conflictCalendar.End = meetingStart.AddHours(this.TimeInterval);
            conflictCalendar.EndSpecified = true;

            ItemInfoResponseMessageType item = this.CreateSingleCalendarItem(Role.Attendee, conflictCalendar, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(item, "The conflict calendar should be created successfully.");
            item = this.CreateSingleCalendarItem(Role.Attendee, adjacentCalendar, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(item, "The adjacent calendar should be created successfully.");
            #endregion

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

            #region Attendee finds the meeting request message from his Inbox folder
            MeetingRequestMessageType request = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Request", meetingItem.UID) as MeetingRequestMessageType;

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R630
            this.Site.CaptureRequirementIfIsNotNull(
                request,
                630,
                @"[In Messages] GetItemSoapIn: For each item being retrieved that is not a recurring calendar item, the ItemIds element MUST contain an ItemId child element ([MS-OXWSCORE] section 2.2.4.11).");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R323
            // Because of Attendee only create one adjacent meeting in this case, therefore, excepted value '1'.
            this.Site.CaptureRequirementIfAreEqual<int>(
                1,
                request.AdjacentMeetingCount,
                323,
                @"[In t:MeetingRequestMessageType Complex Type] AdjacentMeetingCount: Represents the total number of calendar items that are adjacent to the meeting time.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R327
            this.Site.CaptureRequirementIfAreEqual<string>(
                adjacentCalendar.Subject,
                request.AdjacentMeetings.Items[0].Subject,
                327,
                @"[In t:MeetingRequestMessageType Complex Type] AdjacentMeetings: Identifies all calendar items that are adjacent to the meeting time.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R321
            // Because of Attendee only create one conflicting meeting in this case, therefore, excepted value '1'.
            this.Site.CaptureRequirementIfAreEqual<int>(
                1,
                request.ConflictingMeetingCount,
                321,
                @"[In t:MeetingRequestMessageType Complex Type] ConflictingMeetingCount: Represents the number of calendar items that conflict with the meeting item.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R325
            this.Site.CaptureRequirementIfAreEqual<string>(
                conflictCalendar.Subject,
                request.ConflictingMeetings.Items[0].Subject,
                325,
                @"[In t:MeetingRequestMessageType Complex Type] ConflictingMeetings: Identifies all calendar items that conflict with the meeting time.");
            #endregion

            #region Attendee tentatively accepts the meeting request with CalendarItemCreateOrDeleteOperationType value set to SendOnlyToAll
            TentativelyAcceptItemType tentativelyAcceptItem = new TentativelyAcceptItemType();
            tentativelyAcceptItem.ReferenceItemId = new ItemIdType();
            tentativelyAcceptItem.ReferenceItemId.Id = request.ItemId.Id;
            item = this.CreateSingleCalendarItem(Role.Attendee, tentativelyAcceptItem, CalendarItemCreateOrDeleteOperationType.SendOnlyToAll);
            Site.Assert.IsNotNull(item, "Tentatively accept the meeting should be successful.");
            #endregion

            #region Attendee gets the calendar items
            CalendarItemType calendarFromOrganizer = this.SearchSingleItem(Role.Attendee, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", meetingItem.UID) as CalendarItemType;
            ItemInfoResponseMessageType itemInfo = this.GetSingleCalendarItem(Role.Attendee, calendarFromOrganizer.ItemId);
            calendarFromOrganizer = itemInfo.Items.Items[0] as CalendarItemType;

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R193
            this.Site.CaptureRequirementIfAreEqual<int>(
                1,
                calendarFromOrganizer.ConflictingMeetingCount,
                193,
                @"[In t:CalendarItemType Complex Type] ConflictingMeetingCount: Specifies the number of meetings that conflict with the calendar item.");
            
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMTGS_R195");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R195
            this.Site.CaptureRequirementIfAreEqual<int>(
                1,
                calendarFromOrganizer.AdjacentMeetingCount,
                195,
                @"[In t:CalendarItemType Complex Type] AdjacentMeetingCount: Indicates the total number of calendar items that are adjacent to a meeting time.");

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

            Site.Assert.AreEqual<int>(1, calendarFromOrganizer.ConflictingMeetings.Items.Length, "There should be 1 conflict meeting.");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R197
            this.Site.CaptureRequirementIfAreEqual<string>(
                conflictCalendar.Subject,
                calendarFromOrganizer.ConflictingMeetings.Items[0].Subject,
                197,
                @"[In t:CalendarItemType Complex Type] ConflictingMeetings: Indicates all calendar items that conflict with a meeting time.");

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

            Site.Assert.AreEqual<int>(1, calendarFromOrganizer.AdjacentMeetings.Items.Length, "There should be 1 adjacent meeting.");

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R199
            this.Site.CaptureRequirementIfAreEqual<string>(
                adjacentCalendar.Subject,
                calendarFromOrganizer.AdjacentMeetings.Items[0].Subject,
                199,
                @"[In t:CalendarItemType Complex Type] AdjacentMeetings: Indicates all calendar items that are adjacent to a meeting time.");
            #endregion

            #region Organizer gets the meeting response message from his Inbox folder
            MeetingResponseMessageType response = this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Schedule.Meeting.Resp", meetingItem.UID) as MeetingResponseMessageType;
            Site.Assert.IsNotNull(response, "Organizer should receive the meeting response message after attendee tentatively accept the meeting.");

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

            // Verify MS-OXWSMTGS requirement: MS-OXWSMTGS_R81
            this.Site.CaptureRequirementIfAreEqual<ResponseTypeType>(
                ResponseTypeType.Tentative,
                response.ResponseType,
                81,
                @"[In t:ResponseTypeType Simple Type] Tentative: Indicates that the recipient has tentatively accepted the meeting.");
            #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.inbox, DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.deleteditems });
            this.CleanupFoldersByRole(Role.Attendee, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.calendar, DistinguishedFolderIdNameType.sentitems, 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
        }