Inheritance: BaseItemIdType
        /// <summary>
        /// Clean up the environment.
        /// </summary>
        protected override void TestCleanup()
        {
            ExchangeServiceBinding.ServiceResponseEvent -= new ExchangeServiceBinding.ServiceResponseDelegate(this.ExchangeServiceBinding_ResponseEvent);
            if (this.ExistContactItems != null && this.ExistContactItems.Count > 0)
            {
                // Get ItemIds.
                DeleteItemType deleteItemRequest = new DeleteItemType();
                ItemIdType[] itemArray = new ItemIdType[this.ExistContactItems.Count];
                this.ExistContactItems.CopyTo(itemArray, 0);
                deleteItemRequest.ItemIds = itemArray;

                // Configure an enumeration value that describes the item is to be deleted permanently.
                deleteItemRequest.DeleteType = DisposalType.HardDelete;

                DeleteItemResponseType deleteItemResponse = this.CONTAdapter.DeleteItem(deleteItemRequest);

                foreach (ResponseMessageType messageType in deleteItemResponse.ResponseMessages.Items)
                {
                    Site.Assert.AreEqual<ResponseCodeType>(
                        ResponseCodeType.NoError,
                        messageType.ResponseCode,
                        string.Format(
                            "Delete contact item should not fail! Expected response code: {0}, actual response code: {1}",
                            ResponseCodeType.NoError,
                            messageType.ResponseCode));
                }
            }

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

            base.TestCleanup();
        }
        public void MSOXWSCONT_S03_TC01_CopyContactItem()
        {
            #region Step 1:Create the contact item.
            // Create a contact item.
            ContactItemType item = this.BuildContactItemWithRequiredProperties();
            CreateItemResponseType createItemResponse = this.CallCreateItemOperation(item);

            // Check the response.
            Common.CheckOperationSuccess(createItemResponse, 1, this.Site);
            #endregion

            #region Step 2:Copy the contact item.
            CopyItemType copyItemRequest = new CopyItemType();
            CopyItemResponseType copyItemResponse = new CopyItemResponseType();

            // Configure ItemIds.
            copyItemRequest.ItemIds = new BaseItemIdType[1];
            copyItemRequest.ItemIds[0] = this.ExistContactItems[0];

            // Configure the copy Distinguished Folder.
            DistinguishedFolderIdType distinguishedFolderIdForCopyItem = new DistinguishedFolderIdType();
            distinguishedFolderIdForCopyItem.Id = DistinguishedFolderIdNameType.drafts;
            copyItemRequest.ToFolderId = new TargetFolderIdType();
            copyItemRequest.ToFolderId.Item = distinguishedFolderIdForCopyItem;

            copyItemResponse = this.CONTAdapter.CopyItem(copyItemRequest);

            // Check the response.
            Common.CheckOperationSuccess(copyItemResponse, 1, this.Site);
            #endregion

            #region Step 3:Get the contact item.
            // The contact item to get.
            ItemIdType[] itemArray = new ItemIdType[this.ExistContactItems.Count];
            this.ExistContactItems.CopyTo(itemArray, 0);

            GetItemResponseType getItemResponse = this.CallGetItemOperation(itemArray);

            // Check the response.
            Common.CheckOperationSuccess(getItemResponse, 2, this.Site);
            #endregion
        }
        public void MSOXWSMTGS_S05_TC01_GetMultipleCalendarItems()
        {
            #region Define multiple calendar items
            int timeInterval = this.TimeInterval;
            CalendarItemType calendarItem1 = new CalendarItemType();
            calendarItem1.UID = Guid.NewGuid().ToString();
            calendarItem1.Subject = Common.GenerateResourceName(this.Site, Common.GetConfigurationPropertyValue("MeetingSubject", this.Site));
            calendarItem1.Start = DateTime.Now.AddHours(timeInterval);

            // Indicate the Start property is serialized in the SOAP message.
            calendarItem1.StartSpecified = true;
            timeInterval++;
            calendarItem1.End = DateTime.Now.AddHours(timeInterval);
            calendarItem1.EndSpecified = true;
            calendarItem1.LegacyFreeBusyStatus = this.LegacyFreeBusy;
            calendarItem1.LegacyFreeBusyStatusSpecified = true;
            calendarItem1.Location = this.Location;
            calendarItem1.When = string.Format("{0} to {1}", calendarItem1.Start.ToString(), calendarItem1.End.ToString());

            CalendarItemType calendarItem2 = new CalendarItemType();
            calendarItem2.UID = Guid.NewGuid().ToString();
            calendarItem2.Subject = Common.GenerateResourceName(this.Site, Common.GetConfigurationPropertyValue("MeetingSubject", this.Site));
            timeInterval = this.TimeInterval;
            calendarItem2.Start = calendarItem1.End.AddHours(timeInterval);
            timeInterval++;
            calendarItem2.StartSpecified = true;
            calendarItem2.End = calendarItem1.End.AddHours(timeInterval);
            calendarItem2.EndSpecified = true;
            calendarItem2.LegacyFreeBusyStatus = this.LegacyFreeBusy;
            calendarItem2.LegacyFreeBusyStatusSpecified = true;
            calendarItem2.Location = this.Location;
            calendarItem2.When = string.Format("{0} to {1}", calendarItem1.Start.ToString(), calendarItem1.End.ToString());
            #endregion

            #region Create multiple calendar items
            ItemInfoResponseMessageType[] calendars = this.CreateMultipleCalendarItems(Role.Organizer, new ItemType[] { calendarItem1, calendarItem2 }, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(calendars, "The calendars should be created successfully.");
            Site.Assert.IsTrue(calendars.Length == 2, "There should be only two calendars created.");

            ItemIdType[] calendarIds = new ItemIdType[] { calendars[0].Items.Items[0].ItemId, calendars[1].Items.Items[0].ItemId };
            #endregion

            #region Get multiple calendar items
            ItemInfoResponseMessageType[] getItems = this.GetMultipleCalendarItems(Role.Organizer, calendarIds);
            Site.Assert.IsNotNull(getItems, "The calendars should be gotten successfully.");
            Site.Assert.IsTrue(getItems.Length == 2, "There should be only two calendars returned by GetItem.");
            #endregion

            #region Delete multiple calendar items
            Site.Assert.IsNotNull(
                this.DeleteMultipleCalendarItems(Role.Organizer, calendarIds, CalendarItemCreateOrDeleteOperationType.SendToNone),
                "Organizer should delete multiple calendar items successfully.");

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

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1207
            // This requirement can be captured after above assert.
            Site.CaptureRequirement(
                1207,
                @"[In Messages] A successful DeleteItem operation returns a DeleteItemResponse element, as specified in [MS-OXWSCORE] section 3.1.4.3.2.2, with the ResponseClass attribute of the DeleteItemResponseMessage element, as specified in [MS-OXWSCDATA] section 2.2.4.12, set to ""Success"".");

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

            // Verify MS-OXWSMSG requirement: MS-OXWSMTGS_R1208
            // This requirement can be captured after above assert.
            Site.CaptureRequirement(
                1208,
                @"[In Messages] The ResponseCode element, as specified in [MS-OXWSCDATA] section 2.2.4.43, of the DeleteItemResponseMessage element is set to ""NoError"".");
            #endregion
        }
        public void MSOXWSSYNC_S02_TC03_SyncFolderItems_MeetingResponseMessageType()
        {
            #region Step 1. Client invokes SyncFolderItems operation to get the initial syncState of inbox folder.
            DistinguishedFolderIdNameType inboxFolder = DistinguishedFolderIdNameType.inbox;
            SyncFolderItemsType request = this.CreateSyncFolderItemsRequestWithoutOptionalElements(inboxFolder, DefaultShapeNamesType.IdOnly);
            SyncFolderItemsResponseType response = this.SYNCAdapter.SyncFolderItems(request);
            SyncFolderItemsResponseMessageType responseMessage = TestSuiteHelper.EnsureResponse<SyncFolderItemsResponseMessageType>(response);

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

            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R3832
            Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                ResponseCodeType.NoError,
                responseMessage.ResponseCode,
                3832,
                @"[In m:SyncFolderItemsType Complex Type] This element [SyncState] not present, server responses NO_ERROR.");
            #endregion

            #region Step 2. Client invokes CreateMeetingResponse operation to create a MeetingResponseMessageType item.
            // Generate the item subject
            string itemSubject = Common.GenerateResourceName(this.Site, inboxFolder + "ItemSubject");
            this.CreateMeetingResponse(itemSubject);
            #endregion

            #region Step 3. Client invokes SyncFolderItems operation with previous SyncState to get the operation result in Step 2 and verify related requirements.
            responseMessage = this.GetResponseMessage(inboxFolder, responseMessage, DefaultShapeNamesType.IdOnly);

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

            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R3831
            Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                ResponseCodeType.NoError,
                responseMessage.ResponseCode,
                3831,
                @"[In m:SyncFolderItemsType Complex Type] This element [SyncState] is present, server responses NO_ERROR.");

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item created on server, so the changes between server and client should not be null");
            SyncFolderItemsChangesType changes = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changes.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item created on server.");
            Site.Assert.IsNotNull(changes.Items, "There should be item information returned in SyncFolderItems response since there is one item created on server.");

            Site.Assert.AreEqual<int>(1, changes.Items.Length, "Just one MeetingResponseMessageType item was created in previous step, so the count of Items array in responseMessage.Changes should be 1.");

            // If the type of item in SyncFolderItems response is MeetingResponseMessageType, then requirement MS-OXWSSYNC_R168 can be captured.
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSSYNC_R168");

            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R168
            Site.CaptureRequirementIfIsInstanceOfType(
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item,
                typeof(MeetingResponseMessageType),
                168,
                @"[In t:SyncFolderItemsCreateOrUpdateType Complex Type] The type of MeetingResponse is t:MeetingResponseMessageType ([MS-OXWSMTGS] section 2.2.4.23).");

            Site.Assert.AreEqual<int>(1, changes.ItemsElementName.Length, "Just one MeetingResponseMessageType item was created in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");
            bool isMeetingResponseCreated = changes.ItemsElementName[0] == ItemsChoiceType1.Create &&
                    (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType() == typeof(MeetingResponseMessageType);

            // Add the debug information
            Site.Log.Add(
                LogEntryKind.Debug,
                "Verify MS-OXWSSYNC_R1691. Expected value: ItemsElementName: {0}, item type: {1}; actual value: ItemsElementName: {2}, item type: {3}",
                ItemsChoiceType1.Create,
                typeof(MeetingResponseMessageType),
                changes.ItemsElementName[0],
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType());

            // If the ItemsElementName of Changes is Create and the type of Item is MeetingResponseMessageType, it indicates a meeting 
            // response has been created on server and synced on client, then requirement MS-OXWSSYNC_R1691 can be captured.
            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R1691
            Site.CaptureRequirementIfIsTrue(
                isMeetingResponseCreated,
                1691,
                @"[In t:SyncFolderItemsCreateOrUpdateType Complex Type] [The element MeetingResponse] specifies a meeting response message to create in the client message store.");
            #endregion

            #region Step 4. Client invokes UpdateItem operation to update the item which created in Step 2.
            // Generate a new item subject
            string newItemSubject = Common.GenerateResourceName(this.Site, inboxFolder + "NewItemSubject");
            ItemIdType[] itemId = new ItemIdType[1] { (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.ItemId };
            this.UpdateItemSubject(itemId, newItemSubject);
            #endregion

            #region Step 5. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 4 and verify related requirements.
            responseMessage = this.GetResponseMessage(inboxFolder, responseMessage, DefaultShapeNamesType.IdOnly);

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item updated on server, so the changes between server and client should not be null");
            changes = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changes.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item updated on server.");
            Site.Assert.IsNotNull(changes.Items, "There should be item information returned in SyncFolderItems response since there is one item updated on server.");

            Site.Assert.AreEqual<int>(1, changes.ItemsElementName.Length, "Just one MeetingResponseMessageType item was updated in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");
            Site.Assert.AreEqual<int>(1, changes.Items.Length, "Just one MeetingResponseMessageType item was updated in previous step, so the count of Items array in responseMessage.Changes should be 1.");

            bool isMeetingResponseUpdated = changes.ItemsElementName[0] == ItemsChoiceType1.Update &&
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType() == typeof(MeetingResponseMessageType);

            // Add the debug information
            Site.Log.Add(
                LogEntryKind.Debug,
                "Verify MS-OXWSSYNC_R1692. Expected value: ItemsElementName: {0}, item type: {1}; actual value: ItemsElementName: {2}, item type: {3}",
                ItemsChoiceType1.Update,
                typeof(MeetingResponseMessageType),
                changes.ItemsElementName[0],
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType());

            // If the ItemsElementName of Changes is Update and the type of Item is MeetingResponseMessageType, it indicates a meeting 
            // response has been updated on server and synced on client, then requirement MS-OXWSSYNC_R1692 can be captured.
            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R1692
            Site.CaptureRequirementIfIsTrue(
                isMeetingResponseUpdated,
                1692,
                @"[In t:SyncFolderItemsCreateOrUpdateType Complex Type] [The element MeetingResponse] specifies a meeting response message to update in the client message store.");

            bool isIdOnly = Common.IsIdOnly((XmlElement)this.SYNCAdapter.LastRawResponseXml, "t:MeetingResponse", "t:ItemId");

            // If there is only a ItemId element in the item of changes, then requirement MS-OXWSSYNC_R3783 can be captured.
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSSYNC_R3783");

            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R3783
            Site.CaptureRequirementIfIsTrue(
                isIdOnly,
                3783,
                @"[In m:SyncFolderItemsType Complex Type] ItemShape element BaseShape, value=IdOnly, specifies only the item or folder ID.");
            #endregion

            #region Step 6. Client invokes UpdateItem operation to change the IsRead property of the item which updated in Step 4.
            itemId = new ItemIdType[1] { (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.ItemId };
            this.UpdateReadFlag(itemId, this.ConvertReadFlag(itemId));
            #endregion

            #region Step 7. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 6.
            responseMessage = this.GetResponseMessage(inboxFolder, responseMessage, DefaultShapeNamesType.IdOnly);

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item updated on server, so the changes between server and client should not be null");
            changes = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changes.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item updated on server.");
            Site.Assert.IsNotNull(changes.Items, "There should be item information returned in SyncFolderItems response since there is one item updated on server.");

            Site.Assert.AreEqual<int>(1, changes.ItemsElementName.Length, "Just one MeetingResponseMessageType item was updated in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");
            Site.Assert.AreEqual<int>(1, changes.Items.Length, "Just one MeetingResponseMessageType item was updated in previous step, so the count of Items array in responseMessage.Changes should be 1.");
            #endregion

            #region Step 8. Invokes DeleteItem operation to delete the item which updated in Step 6.
            bool isDeleted = this.SYNCSUTControlAdapter.FindAndDeleteItem(
                Common.GetConfigurationPropertyValue("User1Name", this.Site),
                Common.GetConfigurationPropertyValue("User1Password", this.Site),
                Common.GetConfigurationPropertyValue("Domain", this.Site),
                inboxFolder.ToString(),
                newItemSubject,
                Item.MeetingResponse.ToString());
            Site.Assert.IsTrue(isDeleted, string.Format("The item named '{0}' should be deleted from folder '{1}' successfully.", newItemSubject, inboxFolder));
            #endregion

            #region Step 9. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 8 and verify related requirements.
            responseMessage = this.GetResponseMessage(inboxFolder, responseMessage, DefaultShapeNamesType.IdOnly);

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item deleted on server, so the changes between server and client should not be null");
            changes = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changes.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item deleted on server.");
            Site.Assert.IsNotNull(changes.Items, "There should be item information returned in SyncFolderItems response since there is one item deleted on server.");

            Site.Assert.AreEqual<int>(1, changes.ItemsElementName.Length, "Just one MeetingResponseMessageType item was deleted in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");
            Site.Assert.AreEqual<int>(1, changes.Items.Length, "Just one MeetingResponseMessageType item was deleted in previous step, so the count of Items array in responseMessage.Changes should be 1.");

            // Assert the SyncState is not null
            Site.Assert.IsNotNull(responseMessage.SyncState, "The SyncState in response should not be null.");

            // If the SyncState element in SyncFolderItems response is not null, it indicates the synchronization state is returned in response.
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSSYNC_R65");

            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R65
            Site.CaptureRequirement(
                65,
                @"[In m:SyncFolderItemsResponseMessageType Complex Type] [The element SyncState] specifies a form of the synchronization data, which is encoded with base64 encoding, that is used to identify the synchronization state.");
            #endregion

            #region Step 10 Clean up the mailbox of attendee.
            this.CleanupAttendeeMailbox();
            #endregion
        }
        public void MSOXWSCONT_S01_TC01_VerifyContactItemWithRequiredElement()
        {
            #region Step 1:Create the contact item.
            // Call CreateItem operation.
            ContactItemType item = this.BuildContactItemWithRequiredProperties();
            CreateItemResponseType createItemResponse = this.CallCreateItemOperation(item);

            // Check the response.
            Common.CheckOperationSuccess(createItemResponse, 1, this.Site);
            #endregion

            #region Step 2:Get the contact item.
            // The contact item to get.
            ItemIdType[] itemArray = new ItemIdType[this.ExistContactItems.Count];
            this.ExistContactItems.CopyTo(itemArray, 0);

            GetItemResponseType getItemResponse = this.CallGetItemOperation(itemArray);

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

            // Get the item ids from response.
            ItemIdType[] getItemIds = Common.GetItemIdsFromInfoResponse(getItemResponse);

            Site.Assert.AreEqual<int>(
                1,
                getItemIds.GetLength(0),
                "One contact item should be returned!");
            #endregion

            #region Step 3:Delete the contact item.
            DeleteItemType deleteItemRequest = new DeleteItemType();
            deleteItemRequest.ItemIds = getItemIds;

            // Configure the enumeration value that specifies how an contact item is to be deleted.
            deleteItemRequest.DeleteType = DisposalType.HardDelete;

            DeleteItemResponseType deleteItemResponse = this.CONTAdapter.DeleteItem(deleteItemRequest);

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

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

            #region Step 4:Get the deleted contact item
            // Call GetItem operation.
            getItemResponse = this.CallGetItemOperation(getItemIds);

            Site.Assert.AreEqual<int>(
                 1,
                 getItemResponse.ResponseMessages.Items.GetLength(0),
                 "Expected Item Count: {0}, Actual Item Count: {1}",
                 1,
                 getItemResponse.ResponseMessages.Items.GetLength(0));

            Site.Assert.AreEqual<ResponseCodeType>(
                ResponseCodeType.ErrorItemNotFound,
                getItemResponse.ResponseMessages.Items[0].ResponseCode,
                string.Format(
                    "Get deleted item should fail! Expected response code: {0}, actual response code: {1}",
                    ResponseCodeType.ErrorItemNotFound,
                    getItemResponse.ResponseMessages.Items[0].ResponseCode));
            #endregion
        }
        public void MSOXWSMSG_S06_TC01_OperateMultipleMessages()
        {
            #region Create multiple message
            string subject = Common.GenerateResourceName(this.Site, Common.GetConfigurationPropertyValue("Subject", Site), 0);
            string anotherSubject = Common.GenerateResourceName(this.Site, Common.GetConfigurationPropertyValue("Subject", Site), 1);

            CreateItemType createItemRequest = new CreateItemType
            {
                MessageDisposition = MessageDispositionType.SaveOnly,

                // MessageDispositionSpecified value needs to be set.
                MessageDispositionSpecified = true,

                SavedItemFolderId = new TargetFolderIdType
                {
                    Item = new DistinguishedFolderIdType
                    {
                        Id = DistinguishedFolderIdNameType.drafts
                    }
                },

                Items = new NonEmptyArrayOfAllItemsType
                {
                    // Create an responseMessageItem with two MessageType instances.
                    Items = new MessageType[]
                    {
                        new MessageType
                        {
                            Sender = new SingleRecipientType
                            {
                                Item = new EmailAddressType
                                {
                                    EmailAddress = this.Sender
                                }                                
                            },

                            ToRecipients = new EmailAddressType[]
                            {
                                new EmailAddressType
                                {
                                     EmailAddress = this.Recipient1                              
                                }
                            },

                            Subject = subject,                                          
                        },

                        new MessageType
                        {
                             Sender = new SingleRecipientType
                            {
                                Item = new EmailAddressType
                                {
                                    EmailAddress = this.Sender
                                }                                
                            },

                            ToRecipients = new EmailAddressType[]
                            {
                                new EmailAddressType
                                {
                                     EmailAddress = this.Recipient2                               
                                }
                            },

                            Subject = anotherSubject,
                        }
                    }
                },
            };

            CreateItemResponseType createItemResponse = this.MSGAdapter.CreateItem(createItemRequest);
            Site.Assert.IsTrue(this.VerifyMultipleResponse(createItemResponse), @"Server should return success for creating the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(createItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);
            Site.Assert.IsNotNull(this.infoItems, @"InfoItems in the returned response should not be null.");
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem, @"The first item of the array of ItemType type returned from server response should not be null.");

            // Save the first ItemId of message responseMessageItem got from the createItem response.
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            ItemIdType itemIdType1 = new ItemIdType();            
            itemIdType1.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            itemIdType1.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;

            // Save the second ItemId.
            this.firstItemOfSecondInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 1, 0);
            Site.Assert.IsNotNull(this.firstItemOfSecondInfoItem, @"The second item of the array of ItemType type returned from server response should not be null.");
            Site.Assert.IsNotNull(this.firstItemOfSecondInfoItem.ItemId, @"The ItemId property of the second item should not be null.");
            ItemIdType itemIdType2 = new ItemIdType();
            itemIdType2.Id = this.firstItemOfSecondInfoItem.ItemId.Id;
            itemIdType2.ChangeKey = this.firstItemOfSecondInfoItem.ItemId.ChangeKey;
            #endregion

            #region Get the multiple messages which created
            GetItemType getItemRequest = new GetItemType
            {
                // Set the two ItemIds got from CreateItem response.
                ItemIds = new ItemIdType[]
                {
                    itemIdType1,
                    itemIdType2
                },

                ItemShape = new ItemResponseShapeType
                {
                    BaseShape = DefaultShapeNamesType.AllProperties,
                }
            };

            GetItemResponseType getItemResponse = this.MSGAdapter.GetItem(getItemRequest);
            Site.Assert.IsTrue(this.VerifyMultipleResponse(getItemResponse), @"Server should return success for creating the email messages.");
            #endregion

            #region Update the multiple messages which created
            UpdateItemType updateItemRequest = new UpdateItemType
            {
                MessageDisposition = MessageDispositionType.SaveOnly,

                // MessageDispositionSpecified value needs to be set.
                MessageDispositionSpecified = true,

                // Create two ItemChangeType instances.
                ItemChanges = new ItemChangeType[]
                {
                    new ItemChangeType
                    {
                        Item = itemIdType1,                        

                        Updates = new ItemChangeDescriptionType[]
                        {
                            new SetItemFieldType
                            {
                                Item = new PathToUnindexedFieldType
                                {
                                    FieldURI = UnindexedFieldURIType.messageToRecipients
                                },

                                // Update ToRecipients property of the first message.
                                Item1 = new MessageType
                                {
                                    ToRecipients = new EmailAddressType[]
                                    {
                                        new EmailAddressType
                                        {
                                            EmailAddress = this.Recipient2
                                        }
                                    }
                                }
                            },                           
                        }                   
                    },

                    new ItemChangeType
                    {
                        Item = itemIdType2,                        

                        Updates = new ItemChangeDescriptionType[]
                        {
                            new SetItemFieldType
                            {
                                Item = new PathToUnindexedFieldType
                                {
                                    FieldURI = UnindexedFieldURIType.messageToRecipients
                                },

                                // Update ToRecipients property of the second message.
                                Item1 = new MessageType
                                {
                                    ToRecipients = new EmailAddressType[]
                                    {
                                        new EmailAddressType
                                        {
                                            EmailAddress = this.Recipient1
                                        }
                                    }
                                }
                            },                           
                        }                   
                    }
                }
            };

            UpdateItemResponseType updateItemResponse = this.MSGAdapter.UpdateItem(updateItemRequest);
            Site.Assert.IsTrue(this.VerifyMultipleResponse(updateItemResponse), @"Server should return success for updating the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(updateItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);
            Site.Assert.IsNotNull(this.infoItems, @"InfoItems in the returned response should not be null.");
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem, @"The first item of the array of ItemType type returned from server response should not be null.");

            // Save the ItemId of the first message responseMessageItem got from the UpdateItem response.
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            itemIdType1.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            itemIdType1.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;

            // Save the ItemId of the second message responseMessageItem got from the UpdateItem response.
            this.firstItemOfSecondInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 1, 0);
            Site.Assert.IsNotNull(this.firstItemOfSecondInfoItem, @"The second item of the array of ItemType type returned from server response should not be null.");
            Site.Assert.IsNotNull(this.firstItemOfSecondInfoItem.ItemId, @"The ItemId property of the second item should not be null.");
            itemIdType2.Id = this.firstItemOfSecondInfoItem.ItemId.Id;
            itemIdType2.ChangeKey = this.firstItemOfSecondInfoItem.ItemId.ChangeKey;
            #endregion

            #region Copy the updated multiple message to junkemail
            CopyItemType copyItemRequest = new CopyItemType
            {
                ItemIds = new ItemIdType[]
                {
                    itemIdType1,
                    itemIdType2,
                },

                // Copy the message to junk email folder.
                ToFolderId = new TargetFolderIdType
                {
                    Item = new DistinguishedFolderIdType
                    {
                        Id = DistinguishedFolderIdNameType.junkemail
                    }
                }
            };

            CopyItemResponseType copyItemResponse = this.MSGAdapter.CopyItem(copyItemRequest);
            Site.Assert.IsTrue(this.VerifyMultipleResponse(copyItemResponse), @"Server should return success for copying the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(copyItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);
            Site.Assert.IsNotNull(this.infoItems, @"InfoItems in the returned response should not be null.");
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem, @"The first item of the array of ItemType type returned from server response should not be null.");

            // Save the ItemId of the first message responseMessageItem got from the CopyItem response.
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            ItemIdType copyItemIdType1 = new ItemIdType();
            copyItemIdType1.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            copyItemIdType1.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;

            // Save the ItemId of the second message responseMessageItem got from the CopyItem response.
            this.firstItemOfSecondInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 1, 0);
            Site.Assert.IsNotNull(this.firstItemOfSecondInfoItem, @"The second item of the array of ItemType type returned from server response should not be null.");
            Site.Assert.IsNotNull(this.firstItemOfSecondInfoItem.ItemId, @"The ItemId property of the second item should not be null.");
            ItemIdType copyItemIdType2 = new ItemIdType();
            copyItemIdType2.Id = this.firstItemOfSecondInfoItem.ItemId.Id;
            copyItemIdType2.ChangeKey = this.firstItemOfSecondInfoItem.ItemId.ChangeKey;
            #endregion

            #region Move the copied multiple message from junkemail to deleteditems
            MoveItemType moveItemRequest = new MoveItemType
            {
                // Set to copied message responseMessageItem id.
                ItemIds = new ItemIdType[]
                {
                    copyItemIdType1,
                    copyItemIdType2
                },

                // Move the copied messages to deleted items folder.
                ToFolderId = new TargetFolderIdType
                {
                    Item = new DistinguishedFolderIdType
                    {
                        Id = DistinguishedFolderIdNameType.deleteditems
                    }
                }
            };

            MoveItemResponseType moveItemResponse = this.MSGAdapter.MoveItem(moveItemRequest);
            Site.Assert.IsTrue(this.VerifyMultipleResponse(moveItemResponse), @"Server should return success for moving the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(moveItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);
            Site.Assert.IsNotNull(this.infoItems, @"InfoItems in the returned response should not be null.");
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem, @"The first item of the array of ItemType type returned from server response should not be null.");

            // Save the ItemId of the first message responseMessageItem got from the MoveItem response.
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            copyItemIdType1.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            copyItemIdType1.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;

            // Save the ItemId of the second message responseMessageItem got from the MoveItem response.
            this.firstItemOfSecondInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 1, 0);
            Site.Assert.IsNotNull(this.firstItemOfSecondInfoItem, @"The second item of the array of ItemType type returned from server response should not be null.");
            Site.Assert.IsNotNull(this.firstItemOfSecondInfoItem.ItemId, @"The ItemId property of the second item should not be null.");
            copyItemIdType2.Id = this.firstItemOfSecondInfoItem.ItemId.Id;
            copyItemIdType2.ChangeKey = this.firstItemOfSecondInfoItem.ItemId.ChangeKey;
            #endregion

            #region Send multiple messages
            SendItemType sendItemRequest = new SendItemType
            {
                // Set to the two updated messages' ItemIds.
                ItemIds = new ItemIdType[]
                {
                    itemIdType1,
                    itemIdType2
                },

                // Do not save copy.
                SaveItemToFolder = false,
            };

            SendItemResponseType sendItemResponse = this.MSGAdapter.SendItem(sendItemRequest);
            Site.Assert.IsTrue(this.VerifyMultipleResponse(sendItemResponse), @"Server should return success for sending the email messages.");
            #endregion

            #region Delete the copied messages
            DeleteItemType deleteItemRequest = new DeleteItemType
            {
                // Set to the two copied messages' ItemIds.
                ItemIds = new ItemIdType[]
                {
                   copyItemIdType1,
                   copyItemIdType2
                }
            };

            DeleteItemResponseType deleteItemResponse = this.MSGAdapter.DeleteItem(deleteItemRequest);
            Site.Assert.IsTrue(this.VerifyMultipleResponse(deleteItemResponse), @"Server should return success for deleting the email messages.");
            #endregion

            #region Clean up Recipient1's and Recipient2's inbox folders
            bool isClear = this.MSGSUTControlAdapter.CleanupFolders(
                Common.GetConfigurationPropertyValue("Recipient2", this.Site), 
                Common.GetConfigurationPropertyValue("Recipient2Password", this.Site), 
                this.Domain, 
                subject, 
                "inbox");
            Site.Assert.IsTrue(isClear, "Recipient2's inbox folder should be cleaned up.");

            isClear = this.MSGSUTControlAdapter.CleanupFolders(
                Common.GetConfigurationPropertyValue("Recipient1", this.Site), 
                Common.GetConfigurationPropertyValue("Recipient1Password", this.Site), 
                this.Domain, 
                anotherSubject, 
                "inbox");
            Site.Assert.IsTrue(isClear, "Recipient1's inbox folder should be cleaned up.");
            #endregion
        }
        /// <summary>
        /// Verify ItemId Defined in MS-OXWSITEMID.
        /// </summary>
        /// <param name="itemId">A ItemIdType instance.</param>
        private void VerifyItemIdType(ItemIdType itemId)
        {
            ItemIdId itemIdId = this.itemAdapter.ParseItemId(itemId);
            if (itemIdId.StorageType == IdStorageType.MailboxItemMailboxGuidBased || itemIdId.StorageType == IdStorageType.ConversationIdMailboxGuidBased)
            {
                bool isR37Verified = itemIdId.MonikerLength != 0 && itemIdId.MonikerGuid != null;

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

                // Verify MS-OXWSITEMID requirement: MS-OXWSITEMID_R37
                Site.CaptureRequirementIfIsTrue(
                    isR37Verified,
                    "MS-OXWSITEMID",
                    37,
                    @"[In MailboxItemMailboxGuidBased or ConversationIdMailboxGuidBased] Read the mailbox guid by doing the following.
                        Read Int16 from stream for the length.
                        Read 'length' number of bytes from the stream as byte[].
                        Return new Guid(Encoding.UTF8.GetString(moniker, 0, moniker.Length));");

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

                // Verify MS-OXWSITEMID requirement: MS-OXWSITEMID_R38
                // Id processing instrctuion is gotten in ParseItemId method, so this requirement can be captured directly.
                Site.CaptureRequirement(
                    "MS-OXWSITEMID",
                    38,
                    @"[In MailboxItemMailboxGuidBased or ConversationIdMailboxGuidBased] Read the Id processing instruction by doing the following.
                        Read byte from stream.
                        Cast value as IdProcessingInstruction enum value and return.");

                bool isR39Verified = itemIdId.StoreId != null && itemIdId.StoreIdLength != 0;

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

                // Verify MS-OXWSITEMID requirement: MS-OXWSITEMID_R39
                Site.CaptureRequirementIfIsTrue(
                    isR39Verified,
                    "MS-OXWSITEMID",
                    39,
                    @"[In MailboxItemMailboxGuidBased or ConversationIdMailboxGuidBased] Read store Id bytes (for conversationId or item id) by doing the following.
                        Read Int16 from stream for length.
                        Read 'length' number of bytes from stream.
                        Return as byte[].");

                if (itemIdId.StorageType == IdStorageType.MailboxItemMailboxGuidBased && Common.IsRequirementEnabled(74, this.Site))
                {
                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSITEMID_R74");

                    // Verify MS-OXWSITEMID requirement: MS-OXWSITEMID_R74
                    // According above capture, the format of the ItemId has been verified to follow that is defined in R74.
                    // So if the Id storage type is MailboxItemMailboxGuidBased, then R74 has been verified.
                    Site.CaptureRequirement(
                        "MS-OXWSITEMID",
                        74,
                        @"[In Appendix A: Product Behavior] Implementation does support this value [MailboxItemMailboxGuidBased]. (Exchange 2007 Service Pack 1 (SP1) and above follow this behavior).");
                }

                if (itemIdId.StorageType == IdStorageType.ConversationIdMailboxGuidBased)
                {
                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSITEMID_R75");

                    // Verify MS-OXWSITEMID requirement: MS-OXWSITEMID_R75
                    // According above capture, the format of the ItemId has been verified to follow that is defined in R75.
                    // So if the Id storage type is ConversationIdMailboxGuidBased, then R75 has been verified.
                    Site.CaptureRequirement(
                        "MS-OXWSITEMID",
                        75,
                        @"[In MailboxItemMailboxGuidBased or ConversationIdMailboxGuidBased] If the Id storage type is ConversationIdMailboxGuidBased, the format of the remaining bytes is
                            [Short] Moniker Length
                            [Variable] Moniker Bytes
                            [Byte] Id Processing Instruction (Normal = 0, Recurrence = 1)
                            [Short] Store Id Bytes Length
                            [Variable] Store Id Bytes");
                }
            }

            if (itemIdId.StorageType == IdStorageType.PublicFolderItem)
            {
                bool isR44Verified = itemIdId.StoreId != null && itemIdId.StoreIdLength != 0 && itemIdId.FolderId != null && itemIdId.FolderIdLength != 0;

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

                // Verify MS-OXWSITEMID requirement: MS-OXWSITEMID_R44
                Site.CaptureRequirementIfIsTrue(
                    isR44Verified,
                    "MS-OXWSITEMID",
                    44,
                    @"[In PublicFolderItem] If the Id storage type is PublicFolderItem the format of the remaining bytes is:
                        [Byte] Id Processing Instruction
                        [Short] Store Id Bytes Length
                        [Variable] Store Id Bytes
                        [Short] Folder Id Bytes Length
                        [Variable] Folder Id Bytes
                        ");

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

                // Verify MS-OXWSITEMID requirement: MS-OXWSITEMID_R46
                // Id processing instrctuion is gotten in ParseItemId method, so this requirement can be captured directly.
                Site.CaptureRequirement(
                    "MS-OXWSITEMID",
                    46,
                    @"[In PublicFolderItem] Read the Id processing instruction by doing the following:
                        Read byte from stream.
                        Cast value as IdProcessingInstruction enum value.");

                bool isR47Verified = itemIdId.StoreIdLength != 0;

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

                // Verify MS-OXWSITEMID requirement: MS-OXWSITEMID_R47
                Site.CaptureRequirementIfIsTrue(
                    isR47Verified,
                    "MS-OXWSITEMID",
                    47,
                    @"[In PublicFolderItem] Read the store Id bytes for the item Id by doing the following steps. 
                        Read Int16 from stream for length.
                        Read 'length' number of bytes from stream as byte[].");

                bool isR48Verified = itemIdId.FolderId != null;

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

                // Verify MS-OXWSITEMID requirement: MS-OXWSITEMID_R48
                Site.CaptureRequirementIfIsTrue(
                    isR48Verified,
                    "MS-OXWSITEMID",
                    48,
                    @"[In PublicFolderItem] Read the store Id bytes for parent folder Id by doing the following.
                        Read Int16 from stream for length.
                        Read 'length' number of bytes from stream as byte[].");
            }
        }
        public void MSOXWSMSG_S03_TC02_CopyMessageUnsuccessful()
        {
            #region Create message
            CreateItemType createItemRequest = GetCreateItemType(MessageDispositionType.SaveOnly, DistinguishedFolderIdNameType.drafts);
            CreateItemResponseType createItemResponse = this.MSGAdapter.CreateItem(createItemRequest);
            Site.Assert.IsTrue(this.VerifyCreateItemResponse(createItemResponse, MessageDispositionType.SaveOnly), @"Server should return success for creating the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(createItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);

            // Save the ItemId of message responseMessageItem got from the createItem response.
            ItemIdType itemIdType = new ItemIdType();
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            itemIdType.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            itemIdType.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;
            #endregion

            #region Delete the message created
            DeleteItemType deleteItemRequest = new DeleteItemType
            {
                ItemIds = new ItemIdType[]
                {
                   this.firstItemOfFirstInfoItem.ItemId
                }
            };

            DeleteItemResponseType deleteItemResponse = this.MSGAdapter.DeleteItem(deleteItemRequest);
            Site.Assert.IsTrue(this.VerifyResponse(deleteItemResponse), @"Server should return success for deleting the email messages.");
            #endregion

            #region Copy message deleted
            CopyItemType copyItemRequest = new CopyItemType
            {
                ItemIds = new ItemIdType[]
                {
                    itemIdType
                },

                // Save the copy message to inbox folder.
                ToFolderId = new TargetFolderIdType
                {
                    Item = new DistinguishedFolderIdType
                    {
                        Id = DistinguishedFolderIdNameType.inbox
                    }
                }
            };

            CopyItemResponseType copyItemResponse = this.MSGAdapter.CopyItem(copyItemRequest);

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

            this.Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                ResponseClassType.Error,
                copyItemResponse.ResponseMessages.Items[0].ResponseClass,
                170001,
                @"[In CopyItem] If the CreateItem WSDL operation is not successful, it returns a CreateItemResponse element with the ResponseClass attribute of the CreateItemResponseMessage element set to ""Error"". ");

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

            this.Site.CaptureRequirementIfIsTrue(
                System.Enum.IsDefined(typeof(ResponseCodeType), copyItemResponse.ResponseMessages.Items[0].ResponseCode),
                170002,
                @"[In CopyItem] [A unsuccessful CopyItem operation request returns a CopyItemResponse element] The ResponseCode element of the CreateItemResponseMessage element is set to one of the common errors defined in [MS-OXWSCDATA] section 2.2.5.24.");
            #endregion
        }
        public void MSOXWSMSG_S02_TC01_UpdateMessage()
        {
            #region Create message
            CreateItemType createItemRequest = GetCreateItemType(MessageDispositionType.SaveOnly, DistinguishedFolderIdNameType.drafts);
            CreateItemResponseType createItemResponse = this.MSGAdapter.CreateItem(createItemRequest);
            Site.Assert.IsTrue(this.VerifyCreateItemResponse(createItemResponse, MessageDispositionType.SaveOnly), @"Server should return success for creating the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(createItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);

            // Save the ItemId of message responseMessageItem returned from the createItem response.
            ItemIdType itemIdType = new ItemIdType();
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            itemIdType.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            itemIdType.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;
            #endregion

            #region update ToRecipients property of the original message
            UpdateItemType updateItemRequest = new UpdateItemType
            {
                MessageDisposition = MessageDispositionType.SaveOnly,
                MessageDispositionSpecified = true,

                ItemChanges = new ItemChangeType[]
                {
                    new ItemChangeType
                    {
                        Item = itemIdType,                        

                        Updates = new ItemChangeDescriptionType[]
                        {
                            new SetItemFieldType
                            {
                                Item = new PathToUnindexedFieldType
                                {
                                    FieldURI = UnindexedFieldURIType.messageToRecipients
                                },

                                // Update the ToRecipients of message from Recipient1 to Recipient2.
                                Item1 = new MessageType
                                {
                                    ToRecipients = new EmailAddressType[]
                                    {
                                        new EmailAddressType
                                        {
                                            EmailAddress = this.Recipient2
                                        }
                                    }
                                }
                            }
                        }                   
                    }
                }
            };

            UpdateItemResponseType updateItemResponse = this.MSGAdapter.UpdateItem(updateItemRequest);
            Site.Assert.IsTrue(this.VerifyResponse(updateItemResponse), @"Server should return success for creating the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(createItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);
            Site.Assert.IsNotNull(this.infoItems, @"InfoItems in the returned response should not be null.");
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem, @"The first item of the array of ItemType type returned from server response should not be null.");

            // Save the ItemId of message responseMessageItem got from the UpdateItem response.
            if (this.firstItemOfFirstInfoItem != null)
            {
                Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
                itemIdType.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
                itemIdType.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;
            }

            #region Verify the requirements about UpdateItem
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMSG_R143");
        
            // Verify MS-OXWSMSG requirement: MS-OXWSMSG_R143
            Site.CaptureRequirementIfIsNotNull(
                updateItemResponse,
                143,
                @"[In UpdateItem] The protocol client sends an UpdateItemSoapIn request WSDL message, and the protocol server responds with an UpdateItemSoapOut response WSDL message.");

            Site.Assert.IsNotNull(this.infoItems[0].ResponseClass, @"The ResponseClass property of the first item of infoItems instance should not be null.");
            
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMSG_R144");
        
            // Verify MS-OXWSMSG requirement: MS-OXWSMSG_R144
            Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                ResponseClassType.Success,
                this.infoItems[0].ResponseClass,
                144,
                @"[In UpdateItem] If the UpdateItem WSDL operation request is successful, the server returns an UpdateItemResponse element, as specified in [MS-OXWSCORE] section 3.1.4.9.2.2, with the ResponseClass attribute, as specified in [MS-OXWSCDATA] section 2.2.4.67, of the UpdateItemResponseMessage element, as specified in [MS-OXWSCDATA] section 2.2.4.12, set to ""Success"". ");

            Site.Assert.IsNotNull(this.infoItems[0].ResponseCode, @"The ResponseCode property of the first item of infoItems instance should not be null.");
            
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMSG_R145");
        
            // Verify MS-OXWSMSG requirement: MS-OXWSMSG_R145
            Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                ResponseCodeType.NoError,
                this.infoItems[0].ResponseCode,
                145,
                @"[In UpdateItem] [A successful UpdateItem operation request returns an UpdateItemResponse element] The ResponseCode element, as specified in [MS-OXWSCDATA] section 2.2.4.67, of the UpdateItemResponseMessage element is set to ""NoError"". ");
            #endregion
            #endregion

            #region Get the updated message
            GetItemType getItemRequest = DefineGeneralGetItemRequestMessage(itemIdType, DefaultShapeNamesType.AllProperties);
            GetItemResponseType getItemResponse = this.MSGAdapter.GetItem(getItemRequest);
            Site.Assert.IsTrue(this.VerifyResponse(getItemResponse), @"Server should return success for getting the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(getItemResponse);
            Site.Assert.IsNotNull(this.infoItems, @"The GetItem response should contain one or more items of ItemInfoResponseMessageType.");
            ItemType updatedItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);
            Site.Assert.IsNotNull(updatedItem, @"The updated message should exist");

            string expectedValue = Common.GetConfigurationPropertyValue("Recipient2", this.Site);
            Site.Assert.AreEqual<string>(
                expectedValue.ToLower(),
                updatedItem.DisplayTo.ToLower(),
                string.Format("The expected value of the DisplayTo property is {0}. The actual value is {1}.", expectedValue, updatedItem.DisplayTo));
            #endregion

            #region Clean up Sender's drafts folder
            bool isClear = this.MSGSUTControlAdapter.CleanupFolders(
                Common.GetConfigurationPropertyValue("Sender", this.Site), 
                Common.GetConfigurationPropertyValue("SenderPassword", this.Site), 
                this.Domain, 
                this.Subject, 
                "drafts");
            Site.Assert.IsTrue(isClear, "Sender's drafts folder should be cleaned up.");
            #endregion
        }
        /// <summary>
        /// Parse an ItemId's Id from a base64 string to a ItemIdId object according to the defined format
        /// </summary>
        /// <param name="itemId">An ItemIdType object</param>
        /// <returns>An ItemIdId object as the result of parsing</returns>
        public ItemIdId ParseItemId(ItemIdType itemId)
        {
            Site.Assert.IsNotNull(itemId, "The input itemId should not be null.");
            ItemIdId parsedId = new ItemIdId();
            byte[] id = Convert.FromBase64String(itemId.Id);
            int currentIndex = 0;

            // [Byte] Compression Type
            parsedId.CompressionByte = id[currentIndex];
            if (parsedId.CompressionByte == 1)
            {
                // The max length of Base64-encoded Id is 512, which is 512*3/4=384 after decoding
                // Then minus 1 (Compress Byte),which is 383
                id = this.Decompress(id, 383).ToArray();
            }
            else
            {
                currentIndex++;
            }

            // [Byte] Id Storage Type
            Site.Assert.IsTrue(
                Enum.IsDefined(typeof(IdStorageType), id[currentIndex]),
               "The id storage type should be valid. Actually the value is '{0}'.",
               id[currentIndex]);
            parsedId.StorageType = (IdStorageType)id[currentIndex];
            currentIndex++;
            switch (parsedId.StorageType)
            {
                case IdStorageType.MailboxItemSmtpAddressBased:
                case IdStorageType.MailboxItemMailboxGuidBased:
                case IdStorageType.ConversationIdMailboxGuidBased:
                    {
                        parsedId.MonikerLength = BitConverter.ToInt16(id, currentIndex);
                        currentIndex += 2;

                        parsedId.MonikerBytes = new byte[(int)parsedId.MonikerLength];
                        Array.Copy(id, currentIndex, parsedId.MonikerBytes, 0, (int)parsedId.MonikerLength);
                        currentIndex += (int)parsedId.MonikerLength;

                        if (Enum.IsDefined(typeof(IdProcessingInstructionType), id[currentIndex]))
                        {
                            parsedId.IdProcessingInstruction = (IdProcessingInstructionType)id[currentIndex];
                            currentIndex++;
                        }
                        else 
                        {
                            Site.Assert.Fail("Undefined Id Processing Instruction Type value {0}", id[currentIndex]);
                        }

                        parsedId.StoreIdLength = BitConverter.ToInt16(id, currentIndex);
                        currentIndex += 2;
                        parsedId.StoreId = new byte[parsedId.StoreIdLength];
                        Array.Copy(id, currentIndex, parsedId.StoreId, 0, parsedId.StoreIdLength);
                        currentIndex += parsedId.StoreIdLength;

                        break;
                    }

                case IdStorageType.PublicFolder:
                case IdStorageType.ActiveDirectoryObject:
                    {
                        parsedId.StoreIdLength = BitConverter.ToInt16(id, currentIndex);
                        currentIndex += 2;

                        parsedId.StoreId = new byte[parsedId.StoreIdLength];
                        Array.Copy(id, currentIndex, parsedId.StoreId, 0, parsedId.StoreIdLength);
                        currentIndex += parsedId.StoreIdLength;

                        break;
                    }

                case IdStorageType.PublicFolderItem:
                    {
                        if (Enum.IsDefined(typeof(IdProcessingInstructionType), id[currentIndex]))
                        {
                            parsedId.IdProcessingInstruction = (IdProcessingInstructionType)id[currentIndex];
                            currentIndex++;
                        }
                        else
                        {
                            Site.Assert.Fail("Undefined Id Processing Instruction Type value {0}", id[currentIndex]);
                        }

                        parsedId.StoreIdLength = BitConverter.ToInt16(id, currentIndex);
                        currentIndex += 2;

                        parsedId.StoreId = new byte[parsedId.StoreIdLength];
                        Array.Copy(id, currentIndex, parsedId.StoreId, 0, parsedId.StoreIdLength);
                        currentIndex += parsedId.StoreIdLength;

                        parsedId.FolderIdLength = BitConverter.ToInt16(id, currentIndex);
                        currentIndex += 2;

                        parsedId.FolderId = new byte[(int)parsedId.FolderIdLength];
                        Array.Copy(id, currentIndex, parsedId.FolderId, 0, (int)parsedId.FolderIdLength);
                        currentIndex += (int)parsedId.FolderIdLength;

                        break;
                    }

                default:
                    {
                        Site.Assert.Fail("No format defined for Id Storage Type {0}", parsedId.StorageType.ToString("g"));
                        break;
                    }
            }

            if (currentIndex < id.Length)
            {
                parsedId.AttachmentIdCount = id[currentIndex];
                currentIndex++;

                short attachmentIdCount = Convert.ToInt16(parsedId.AttachmentIdCount);
                parsedId.AttachmentIds = new AttachmentId[attachmentIdCount];

                for (int i = 0; i < attachmentIdCount; i++)
                {
                    parsedId.AttachmentIds[i].AttachmentIdLength = BitConverter.ToInt16(id, currentIndex);
                    currentIndex += 2;

                    parsedId.AttachmentIds[i].Id = new byte[parsedId.AttachmentIds[i].AttachmentIdLength];
                    Array.Copy(id, currentIndex, parsedId.AttachmentIds[i].Id, 0, parsedId.AttachmentIds[i].AttachmentIdLength);
                    currentIndex += parsedId.AttachmentIds[i].AttachmentIdLength;
                }
            }

            Site.Assert.AreEqual<int>(id.Length, currentIndex, "There should be no bytes left after parsing item id!");
            return parsedId;
        }
        /// <summary>
        /// Define general GetItem request message
        /// </summary>
        /// <param name="itemId">The item identifier of the item.</param>
        /// <param name="baseShape">The basic configuration of properties to be returned in an item response.</param>
        /// <returns>A request to get an item from a mailbox</returns>
        protected GetItemType DefineGeneralGetItemRequestMessage(ItemIdType itemId, DefaultShapeNamesType baseShape)
        {
            GetItemType getItemRequest = new GetItemType
            {
                ItemIds = new ItemIdType[]
                {
                    itemId
                },

                ItemShape = new ItemResponseShapeType
                {
                    BaseShape = baseShape,
                }
            };

            return getItemRequest;
        }
        /// <summary>
        /// Delete an occurrence of a recurring meeting.
        /// </summary>
        /// <param name="occurrenceId">The Id of the occurrence to be deleted.</param>
        /// <returns>If delete operation succeeds, return true; otherwise, false.</returns>
        private bool DeleteOccurrenceItem(ItemIdType occurrenceId)
        {
            if (occurrenceId != null)
            {
                ResponseMessageType deletedItem = this.DeleteSingleCalendarItem(Role.Organizer, occurrenceId, CalendarItemCreateOrDeleteOperationType.SendToAllAndSaveCopy);
                if (deletedItem != null)
                {
                    return true;
                }
            }

            return false;
        }
        public void MSOXWSMSG_S07_TC07_VerifyReceivedRepresentingIsReadOnly()
        {
            #region Create a message which include the ReceivedRepresenting element.
            CreateItemType createItemRequest = new CreateItemType
            {
                MessageDisposition = MessageDispositionType.SaveOnly,

                // MessageDispositionSpecified value needs to be set.
                MessageDispositionSpecified = true,

                SavedItemFolderId = new TargetFolderIdType
                {
                    Item = new DistinguishedFolderIdType
                    {
                        Id = DistinguishedFolderIdNameType.drafts
                    }
                },

                Items = new NonEmptyArrayOfAllItemsType
                {
                    Items = new MessageType[]
                    {
                        // Create a MessageType instance with all element.
                        new MessageType
                        {
                            // Specify the sender of the message.
                            Sender = new SingleRecipientType
                            {
                                Item = new EmailAddressType
                                {
                                    EmailAddress = this.Sender
                                }                                
                            },

                            // Specify the recipient of the message.
                            ToRecipients = new EmailAddressType[]
                            {
                                new EmailAddressType
                                {
                                     EmailAddress = this.Recipient1                               
                                }
                            },
                           ReceivedRepresenting = new SingleRecipientType()
                           {
                                Item = new EmailAddressType
                                {
                                    EmailAddress = this.Recipient1
                                }
                           }
                        }
                    }
                },
            };

            CreateItemResponseType createItemResponse = this.MSGAdapter.CreateItem(createItemRequest);

            Site.Assert.AreEqual<ResponseCodeType>(ResponseCodeType.ErrorInvalidPropertySet, createItemResponse.ResponseMessages.Items[0].ResponseCode, "Since ReceivedRepresenting is read-only, then the The ErrorInvalidPropertySet should be returned by server.");
            #endregion

            #region Create message
            createItemRequest = this.GetCreateItemType(MessageDispositionType.SaveOnly, DistinguishedFolderIdNameType.drafts);
            createItemResponse = this.MSGAdapter.CreateItem(createItemRequest);
            Site.Assert.IsTrue(this.VerifyCreateItemResponse(createItemResponse, MessageDispositionType.SaveOnly), @"Server should return success for creating the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(createItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);

            // Save the ItemId of message responseMessageItem returned from the createItem response.
            ItemIdType itemIdType = new ItemIdType();
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            itemIdType.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            itemIdType.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;
            #endregion

            #region update ReceivedRepresenting property of the original message
            UpdateItemType updateItemRequest = new UpdateItemType
            {
                MessageDisposition = MessageDispositionType.SaveOnly,
                MessageDispositionSpecified = true,

                ItemChanges = new ItemChangeType[]
                {
                    new ItemChangeType
                    {
                        Item = itemIdType,                        

                        Updates = new ItemChangeDescriptionType[]
                        {
                            new SetItemFieldType
                            {
                                Item = new PathToUnindexedFieldType
                                {
                                    FieldURI = UnindexedFieldURIType.messageReceivedRepresenting
                                },
                                Item1 = new MessageType
                                {
                                     ReceivedRepresenting = new SingleRecipientType()
                                     {
                                         Item = new EmailAddressType()
                                         {
                                             EmailAddress = this.Recipient1
                                         }
                                     }
                                }
                            }
                        }                   
                    }
                }
            };

            UpdateItemResponseType updateItemResponse = this.MSGAdapter.UpdateItem(updateItemRequest);
            Site.Assert.AreEqual<ResponseCodeType>(ResponseCodeType.ErrorInvalidPropertySet, updateItemResponse.ResponseMessages.Items[0].ResponseCode, "Since ReceivedRepresenting is read-only, then the The ErrorInvalidPropertySet should be returned by server.");
            #endregion

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

            // If the above steps are pass, the R73001 will be verified.
            this.Site.CaptureRequirement(
                73001,
                @"[In t:MessageType Complex Type] [ReceivedRepresenting element] This element is read-only.");

            #region Clean up Sender's drafts folder
            bool isClear = this.MSGSUTControlAdapter.CleanupFolders(
                Common.GetConfigurationPropertyValue("Sender", this.Site),
                Common.GetConfigurationPropertyValue("SenderPassword", this.Site),
                this.Domain,
                this.Subject,
                "drafts");
            Site.Assert.IsTrue(isClear, "Sender's drafts folder should be cleaned up.");
            #endregion
        }
        public void MSOXWSMSG_S07_TC05_VerifyInternetMessageIdIsReadOnly()
        {
            #region Create message
            CreateItemType createItemRequest = GetCreateItemType(MessageDispositionType.SaveOnly, DistinguishedFolderIdNameType.drafts);
            CreateItemResponseType createItemResponse = this.MSGAdapter.CreateItem(createItemRequest);
            Site.Assert.IsTrue(this.VerifyCreateItemResponse(createItemResponse, MessageDispositionType.SaveOnly), @"Server should return success for creating the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(createItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);

            // Save the ItemId of message responseMessageItem returned from the createItem response.
            ItemIdType itemIdType = new ItemIdType();
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            itemIdType.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            itemIdType.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;
            #endregion

            #region update InternetMessageId property of the original message
            UpdateItemType updateItemRequest = new UpdateItemType
            {
                MessageDisposition = MessageDispositionType.SaveOnly,
                MessageDispositionSpecified = true,

                ItemChanges = new ItemChangeType[]
                {
                    new ItemChangeType
                    {
                        Item = itemIdType,                        

                        Updates = new ItemChangeDescriptionType[]
                        {
                            new SetItemFieldType
                            {
                                Item = new PathToUnindexedFieldType
                                {
                                    FieldURI = UnindexedFieldURIType.messageInternetMessageId
                                },
                                Item1 = new MessageType
                                {
                                     InternetMessageId = "InternetMessageId"     
                                }
                            }
                        }                   
                    }
                }
            };

            UpdateItemResponseType updateItemResponse = this.MSGAdapter.UpdateItem(updateItemRequest);
            Site.Assert.AreEqual<ResponseCodeType>(ResponseCodeType.ErrorInvalidPropertySet, updateItemResponse.ResponseMessages.Items[0].ResponseCode, "Since InternetMessageId is read-only, then the The ErrorInvalidPropertySet should be returned by server.");

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

            // If the above steps are pass, the R58 will be verified.
            this.Site.CaptureRequirement(
                58,
                @"[In t:MessageType Complex Type] [InternetMessageId element] This element is read-only.");
            #endregion

            #region Clean up Sender's drafts folder
            bool isClear = this.MSGSUTControlAdapter.CleanupFolders(
                Common.GetConfigurationPropertyValue("Sender", this.Site),
                Common.GetConfigurationPropertyValue("SenderPassword", this.Site),
                this.Domain,
                this.Subject,
                "drafts");
            Site.Assert.IsTrue(isClear, "Sender's drafts folder should be cleaned up.");
            #endregion
        }
        public void MSOXWSMSG_S07_TC03_VerifyConversationIndexIsReadOnly()
        {
            #region Create a message which include the ConversationIndex element.
            CreateItemType createItemRequest = new CreateItemType
            {
                MessageDisposition = MessageDispositionType.SaveOnly,

                // MessageDispositionSpecified value needs to be set.
                MessageDispositionSpecified = true,

                SavedItemFolderId = new TargetFolderIdType
                {
                    Item = new DistinguishedFolderIdType
                    {
                        Id = DistinguishedFolderIdNameType.drafts
                    }
                },
                Items = new NonEmptyArrayOfAllItemsType
                {
                    Items = new MessageType[]
                    {
                        // Create a MessageType instance with all element.
                        new MessageType
                        {
                            // Specify the sender of the message.
                            Sender = new SingleRecipientType
                            {
                                Item = new EmailAddressType
                                {
                                    EmailAddress = this.Sender
                                }                                
                            },

                            // Specify the recipient of the message.
                            ToRecipients = new EmailAddressType[]
                            {
                                new EmailAddressType
                                {
                                     EmailAddress = this.Recipient1                               
                                }
                            },
                            ConversationIndex = new byte[] { },                                                                 
                        }
                    }
                },
            };

            CreateItemResponseType createItemResponse = this.MSGAdapter.CreateItem(createItemRequest);

            Site.Assert.AreEqual<ResponseCodeType>(ResponseCodeType.ErrorInvalidPropertySet, createItemResponse.ResponseMessages.Items[0].ResponseCode, "Since ConversationIndex is read-only, then the The ErrorInvalidPropertySet should be returned by server.");
           
            this.Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                ResponseClassType.Error,
                createItemResponse.ResponseMessages.Items[0].ResponseClass,
                113001,
                @"[In CreateItem] If the CreateItem WSDL operation is not successful, it returns a CreateItemResponse element with the ResponseClass attribute of the CreateItemResponseMessage element set to ""Error"". ");

            this.Site.CaptureRequirementIfIsTrue(
                System.Enum.IsDefined(typeof(ResponseCodeType), createItemResponse.ResponseMessages.Items[0].ResponseCode),
                113002,
                @"[In CreateItem] [A unsuccessful CreateItem operation request returns a CreateItemResponse element] The ResponseCode element of the CreateItemResponseMessage element is set to one of the common errors defined in [MS-OXWSCDATA] section 2.2.5.24.");
            #endregion

            #region Create message
            createItemRequest = this.GetCreateItemType(MessageDispositionType.SaveOnly, DistinguishedFolderIdNameType.drafts);
            createItemResponse = this.MSGAdapter.CreateItem(createItemRequest);
            Site.Assert.IsTrue(this.VerifyCreateItemResponse(createItemResponse, MessageDispositionType.SaveOnly), @"Server should return success for creating the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(createItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);

            // Save the ItemId of message responseMessageItem returned from the createItem response.
            ItemIdType itemIdType = new ItemIdType();
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            itemIdType.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            itemIdType.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;
            #endregion

            #region update ConversationIndex property of the original message
            UpdateItemType updateItemRequest = new UpdateItemType
            {
                MessageDisposition = MessageDispositionType.SaveOnly,
                MessageDispositionSpecified = true,

                ItemChanges = new ItemChangeType[]
                {
                    new ItemChangeType
                    {
                        Item = itemIdType,                        

                        Updates = new ItemChangeDescriptionType[]
                        {
                            new SetItemFieldType
                            {
                                Item = new PathToUnindexedFieldType
                                {
                                    FieldURI = UnindexedFieldURIType.messageConversationIndex
                                },
                                Item1 = new MessageType
                                {
                                    ConversationIndex = new byte[] { }
                                }
                            }
                        }                   
                    }
                }
            };
  
            UpdateItemResponseType updateItemResponse = this.MSGAdapter.UpdateItem(updateItemRequest);
            Site.Assert.AreEqual<ResponseCodeType>(ResponseCodeType.ErrorInvalidPropertySet, updateItemResponse.ResponseMessages.Items[0].ResponseCode, "Since ConversationIndex is read-only, then the The ErrorInvalidPropertySet should be returned by server.");

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

            this.Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                ResponseClassType.Error,
                updateItemResponse.ResponseMessages.Items[0].ResponseClass,
                145001,
                @"[In UpdateItem] If the UpdateItem WSDL operation request is not successful, it returns an UpdateItemResponse element with the ResponseClass attribute of the UpdateItemResponseMessage element set to ""Error"". ");

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

            this.Site.CaptureRequirementIfIsTrue(
                System.Enum.IsDefined(typeof(ResponseCodeType), updateItemResponse.ResponseMessages.Items[0].ResponseCode),
                145002,
                @"[In UpdateItem] [A unsuccessful UpdateItem operation request returns an UpdateItemResponse element] The ResponseCode element of the UpdateItemResponseMessage element is set to one of the common errors defined in [MS-OXWSCDATA] section 2.2.5.24.");

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

            // If the above steps are pass, the R49 will be verified.
            this.Site.CaptureRequirement(
                49,
                @"[In t:MessageType Complex Type] [ConversationIndex element] This element is read-only.");
            #endregion

            #region Clean up Sender's drafts folder
            bool isClear = this.MSGSUTControlAdapter.CleanupFolders(
                Common.GetConfigurationPropertyValue("Sender", this.Site),
                Common.GetConfigurationPropertyValue("SenderPassword", this.Site),
                this.Domain,
                this.Subject,
                "drafts");
            Site.Assert.IsTrue(isClear, "Sender's drafts folder should be cleaned up.");
            #endregion
        }
        public void MSOXWSMSG_S04_TC01_MoveMessage()
        {
            #region Create message
            CreateItemType createItemRequest = GetCreateItemType(MessageDispositionType.SaveOnly, DistinguishedFolderIdNameType.drafts);
            CreateItemResponseType createItemResponse = this.MSGAdapter.CreateItem(createItemRequest);
            Site.Assert.IsTrue(this.VerifyCreateItemResponse(createItemResponse, MessageDispositionType.SaveOnly), @"Server should return success for creating the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(createItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);

            // Save the ItemId of message responseMessageItem got from the createItem response.
            ItemIdType itemIdType = new ItemIdType();
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            itemIdType.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            itemIdType.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;
            #endregion

            #region Move message
            MoveItemType moveItemRequest = new MoveItemType
            {
                ItemIds = new ItemIdType[]
                {
                    itemIdType
                },

                // Set target folder to junk email folder.
                ToFolderId = new TargetFolderIdType
                {
                    Item = new DistinguishedFolderIdType
                    {
                        Id = DistinguishedFolderIdNameType.junkemail
                    }
                }
            };

            MoveItemResponseType moveItemResponse = this.MSGAdapter.MoveItem(moveItemRequest);
            Site.Assert.IsTrue(this.VerifyResponse(moveItemResponse), @"Server should return success for moving the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(moveItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);
            Site.Assert.IsNotNull(this.infoItems, @"InfoItems in the returned response should not be null.");
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem, @"The first item of the array of ItemType type returned from server response should not be null.");

            // Save the ItemId of message responseMessageItem got from the moveItem response.
            ItemIdType moveItemIdType = new ItemIdType();
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            moveItemIdType.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            moveItemIdType.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;

            // Verify whether the message is moved to junkemail folder.
            string userName = Common.GetConfigurationPropertyValue("Sender", this.Site);
            string password = Common.GetConfigurationPropertyValue("SenderPassword", this.Site);
            string domain = Common.GetConfigurationPropertyValue("Domain", this.Site);
            bool findItemInDrafts = this.IsItemAvailableAfterMoveOrDelete(userName, password, domain, "drafts", this.Subject, "itemSubject");
            Site.Assert.IsFalse(findItemInDrafts, "The item should not be found in the drafts folder of Sender.");
            
            bool findItemInJunkemail = this.SearchItems(Role.Sender, "junkemail", this.Subject, "itemSubject");
            Site.Assert.IsTrue(findItemInJunkemail, "The item should be found in the junkemail folder of Sender.");

            #region Verify the requirements about MoveItem
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMSG_R161");
        
            // Verify MS-OXWSMSG requirement: MS-OXWSMSG_R161            
            Site.CaptureRequirementIfIsNotNull(
                moveItemResponse,
                161,
                @"[In MoveItem] The protocol client sends a MoveItemSoapIn request WSDL message, and the protocol server responds with a MoveItemSoapOut response WSDL message.");

            Site.Assert.IsNotNull(this.infoItems[0].ResponseClass, @"The ResponseClass property of the first item of infoItems instance should not be null.");
            
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMSG_R162");
        
            // Verify MS-OXWSMSG requirement: MS-OXWSMSG_R162
            Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                ResponseClassType.Success,
                this.infoItems[0].ResponseClass,
                162,
                @"[In MoveItem] If the MoveItem WSDL operation request is successful, the server returns a MoveItemResponse element, as specified in [MS-OXWSCORE] section 3.1.4.7.2.2, with the ResponseClass attribute, as specified in [MS-OXWSCDATA] section 2.2.4.67, of the MoveItemResponseMessage element, as specified in [MS-OXWSCDATA] section 2.2.4.12, set to ""Success"". ");

            Site.Assert.IsNotNull(this.infoItems[0].ResponseCode, @"The ResponseCode property of the first item of infoItems instance should not be null.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMSG_R163");
        
            // Verify MS-OXWSMSG requirement: MS-OXWSMSG_R163
            Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                ResponseCodeType.NoError,
                this.infoItems[0].ResponseCode,
                163,
                @"[In MoveItem] [A successful MoveItem operation request returns a MoveItemResponse element] The ResponseCode element, as specified in [MS-OXWSCDATA] section 2.2.4.67, of the MoveItemResponseMessage element is set to ""NoError"". ");
            #endregion
            #endregion

            #region Delete the moved message
            DeleteItemType deleteItemRequest = new DeleteItemType
            {
                ItemIds = new ItemIdType[]
                {
                   moveItemIdType
                }
            };

            DeleteItemResponseType deleteItemResponse = this.MSGAdapter.DeleteItem(deleteItemRequest);
            Site.Assert.IsTrue(this.VerifyResponse(deleteItemResponse), @"Server should return success for deleting the email messages.");
            #endregion
        }
        public void MSOXWSTASK_S05_TC01_OperateMultipleTaskItems()
        {
            #region Client calls CreateItem to create two task items on server.
            string firstSubject = Common.GenerateResourceName(this.Site, "This is a task", 1);
            string secondSubject = Common.GenerateResourceName(this.Site, "This is a task", 2);
            ItemIdType[] createItemIds = this.CreateTasks(TestSuiteHelper.DefineTaskItem(firstSubject), TestSuiteHelper.DefineTaskItem(secondSubject));
            Site.Assert.IsNotNull(createItemIds, "This create response should have task item id!");
            Site.Assert.AreEqual<int>(2, createItemIds.Length, "There should be 2 task items' ids in response!");
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, (ResponseClassType)this.ResponseClass[0], "This create response status of first task item should be success!", null);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, (ResponseClassType)this.ResponseClass[1], "This create response status of second task item should be success!", null);
            #endregion

            #region Client calls GetItem to get two task items.
            TaskType[] taskItems = this.GetTasks(createItemIds);
            Site.Assert.IsNotNull(taskItems, "This get response should have task items!");
            Site.Assert.AreEqual<int>(2, taskItems.Length, "There should be 2 task items in response!");
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, (ResponseClassType)this.ResponseClass[0], "This get response status of first task item should be success!", null);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, (ResponseClassType)this.ResponseClass[1], "This get response status of second task item should be success!", null);
            #endregion

            #region Client calls UpdateItem to update the value of taskCompanies element of task item.
            ItemIdType[] updateItemIds = this.UpdateTasks(createItemIds);
            Site.Assert.IsNotNull(updateItemIds, "This update response should have task item id!");
            Site.Assert.AreEqual<int>(2, updateItemIds.Length, "There should be 2 task items' ids in response!");
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, (ResponseClassType)this.ResponseClass[0], "This update response status of first task item should be success!", null);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, (ResponseClassType)this.ResponseClass[1], "This update response status of second task item should be success!", null);
            #endregion

            #region Client calls CopyItem to copy the two task items.
            ItemIdType[] copyItemIds = this.CopyTasks(updateItemIds);
            Site.Assert.IsNotNull(copyItemIds, "This copy response should have task item id!");
            Site.Assert.AreEqual<int>(2, copyItemIds.Length, "There should be 2 task items' ids in response!");
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, (ResponseClassType)this.ResponseClass[0], "This copy response status of first task item should be success!", null);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, (ResponseClassType)this.ResponseClass[1], "This copy response status of second task item should be success!", null);
            #endregion

            #region Client calls MoveItem to move the task items to deleteditems folder
            ItemIdType[] moveItemIds = this.MoveTasks(updateItemIds);
            Site.Assert.IsNotNull(moveItemIds, "This move response should have task item id!");
            Site.Assert.AreEqual<int>(2, moveItemIds.Length, "There should be 2 task items' ids in response!");
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, (ResponseClassType)this.ResponseClass[0], "This move response status of first task item should be success!", null);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, (ResponseClassType)this.ResponseClass[1], "This move response status of second task item should be success!", null);
            #endregion

            #region Client calls DeleteItem to delete the task items created in the previous steps.
            ItemIdType[] deleteItemIds = new ItemIdType[copyItemIds.Length + moveItemIds.Length];
            copyItemIds.CopyTo(deleteItemIds, 0);
            moveItemIds.CopyTo(deleteItemIds, copyItemIds.Length);
            this.DeleteTasks(deleteItemIds);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, (ResponseClassType)this.ResponseClass[0], "This delete response status of first task item should be success!", null);
            Site.Assert.AreEqual<ResponseClassType>(ResponseClassType.Success, (ResponseClassType)this.ResponseClass[1], "This delete response status of second task item should be success!", null);
            #endregion
        }
        public void MSOXWSCONT_S02_TC01_UpdateContactItem()
        {
            #region Step 1:Create the contact item.
            // Create a contact item.
            ContactItemType item = this.BuildContactItemWithRequiredProperties();
            CreateItemResponseType createItemResponse = this.CallCreateItemOperation(item);

            // Check the response.
            Common.CheckOperationSuccess(createItemResponse, 1, this.Site);
            #endregion

            #region Step 2:Update the contact item.
            UpdateItemType updateItemRequest = new UpdateItemType()
            {
                // Configure ItemIds.
                ItemChanges = new ItemChangeType[]
                {
                    new ItemChangeType()
                    {
                        Item = this.ExistContactItems[0],

                        Updates = new ItemChangeDescriptionType[]
                        {
                            new SetItemFieldType()
                            {
                                Item = new PathToUnindexedFieldType()
                                {
                                    FieldURI = UnindexedFieldURIType.contactsFileAs
                                },

                                Item1 = new ContactItemType()
                                {
                                    FileAs = FileAsMappingType.LastFirstCompany.ToString()
                                }
                            }
                        }
                    }
                },

                ConflictResolution = ConflictResolutionType.AlwaysOverwrite
            };

            UpdateItemResponseType updateItemResponse = new UpdateItemResponseType();

            // Invoke UpdateItem operation.
            updateItemResponse = this.CONTAdapter.UpdateItem(updateItemRequest);

            // Check the response.
            Common.CheckOperationSuccess(updateItemResponse, 1, this.Site);
            #endregion

            #region Step 3:Get the contact item.
            // The contact item to get.
            ItemIdType[] itemArray = new ItemIdType[this.ExistContactItems.Count];
            this.ExistContactItems.CopyTo(itemArray, 0);

            GetItemResponseType getItemResponse = this.CallGetItemOperation(itemArray);

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

            ContactItemType[] contacts = Common.GetItemsFromInfoResponse<ContactItemType>(getItemResponse);

            Site.Assert.AreEqual<int>(
                1,
                contacts.Length,
                string.Format(
                    "The count of items from response should be 1, actual: '{0}'.", contacts.Length));

            Site.Assert.AreEqual<string>(
                FileAsMappingType.LastFirstCompany.ToString(),
                contacts[0].FileAs,
                string.Format(
                    "The FileAs property should be updated as set. Expected value: {0}, actual value: {1}", FileAsMappingType.LastFirstCompany.ToString(), contacts[0].FileAs));
            #endregion
        }
        /// <summary>
        /// Delete specific item.
        /// </summary>
        /// <param name="itemId">Id of specific item.</param>
        /// <returns>If specific item deleted successfully.</returns>
        protected bool DeleteItem(ItemIdType itemId)
        {
            // If id is null return false.
            if (itemId == null)
            {
                return false;
            }

            DeleteItemType deleteItemRequest = new DeleteItemType();
            deleteItemRequest.AffectedTaskOccurrences = AffectedTaskOccurrencesType.AllOccurrences;
            deleteItemRequest.AffectedTaskOccurrencesSpecified = true;
            deleteItemRequest.SendMeetingCancellations = CalendarItemCreateOrDeleteOperationType.SendToNone;
            deleteItemRequest.SendMeetingCancellationsSpecified = true;

            // Serialize item ids and change keys to ItemIdType arrays.
            ItemIdType[] itemIdTypes = new ItemIdType[1];
            itemIdTypes[0] = itemId;

            deleteItemRequest.ItemIds = itemIdTypes;
            deleteItemRequest.DeleteType = DisposalType.HardDelete;
            DeleteItemResponseType deleteItemResponse = this.COREAdapter.DeleteItem(deleteItemRequest);
            return deleteItemResponse.ResponseMessages.Items[0].ResponseCode == ResponseCodeType.NoError;
        }
        public void MSOXWSCORE_S04_TC20_VerifyOperationsWithSOAPHeaderSuccessful()
        {
            #region Step 1: Create one item with recipient.
            // Clear the soap header.
            this.ClearSoapHeaders();

            // Configure the SOAP headers for CreateItem and UpdateItem operations.
            Dictionary<string, object> headerValues = new Dictionary<string, object>();
            headerValues = this.ConfigureSOAPHeader();

            // Configure the TimeZoneContext SOAP Header.
            TimeZoneContextType timeZoneContext = new TimeZoneContextType();
            timeZoneContext.TimeZoneDefinition = new TimeZoneDefinitionType();
            timeZoneContext.TimeZoneDefinition.Id = TestSuiteHelper.TimeZoneID;

            headerValues.Add("TimeZoneContext", timeZoneContext);
            this.COREAdapter.ConfigureSOAPHeader(headerValues);

            // Call the CreateItem operation and save the item to Drafts folder.
            MessageType[] items = new MessageType[] { this.CreateItemWithOneRecipient() };

            CreateItemResponseType createItemResponse = this.CallCreateItemOperation(DistinguishedFolderIdNameType.drafts, items);

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

            MessageType[] createdItems = Common.GetItemsFromInfoResponse<MessageType>(createItemResponse);

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

            #region Step 2: Update the item which is created in Step 1.
            ItemChangeType[] itemChanges = new ItemChangeType[]
            {
                TestSuiteHelper.CreateItemChangeItem(createdItems[0], 1)
            };

            // Clear ExistItemIds list for MoveItem.
            this.InitializeCollection();

            // Call UpdateItem operation to update the subject of the created item, by using the ItemId in CreateItem response.
            UpdateItemResponseType updateItemResponse = this.CallUpdateItemOperation(
                DistinguishedFolderIdNameType.drafts,
                true,
                itemChanges);

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

            // Clear the soap header.
            this.ClearSoapHeaders();
            #endregion

            #region Step 3: Move the item updated in Step 2 from Drafts folder to Inbox folder.
            // Configure the SOAP headers for MoveItem and MarkAllItemsAsRead operations.
            headerValues.Remove("TimeZoneContext");
            this.COREAdapter.ConfigureSOAPHeader(headerValues);

            // Call the MoveItem operation, by using the ItemId in UpdateItem response.
            ItemIdType[] draftsItem = new ItemIdType[this.ExistItemIds.Count];
            this.ExistItemIds.CopyTo(draftsItem, 0);
            this.InitializeCollection();
            MoveItemResponseType moveItemResponse = this.CallMoveItemOperation(DistinguishedFolderIdNameType.inbox, draftsItem);

            // Check the operation response.
            Common.CheckOperationSuccess(moveItemResponse, 1, this.Site);
            #endregion

            #region Step 4: Mark all items in Inbox folder as read.
            // Exchange 2007 and Exchange 2010 do not support the MarkAllItemsAsRead operation.
            if (Common.IsRequirementEnabled(1290, this.Site))
            {
                // Configure Inbox folder as the target folder.
                BaseFolderIdType[] folderIds = new BaseFolderIdType[1];
                DistinguishedFolderIdType distinguishedFolder = new DistinguishedFolderIdType();
                distinguishedFolder.Id = DistinguishedFolderIdNameType.inbox;
                folderIds[0] = distinguishedFolder;

                // Mark all items in Inbox folder as unread, and suppress the receive receipts.
                MarkAllItemsAsReadResponseType markAllItemsAsReadResponse = this.CallMarkAllItemsAsReadOperation(true, true, folderIds);

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

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

                // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1290
                // The MarkAllItemsAsRead operation was executed successfully, so this requirement can be captured.
                this.Site.CaptureRequirementIfIsTrue(
                    this.IsSchemaValidated,
                    1290,
                    @"[In Appendix C: Product Behavior] Implementation does support the MarkAllItemsAsRead operation which marks all items in a folder as read. (Exchange 2013  and above follow this behavior.)");
            }

            // Clear the soap header.
            this.ClearSoapHeaders();
            #endregion

            #region Step 5: Get the item in Inbox folder.
            // Configure the SOAP headers for GetItem.
            headerValues.Add("TimeZoneContext", timeZoneContext);
            this.COREAdapter.ConfigureSOAPHeader(headerValues);

            // Call the GetItem operation, by using the ItemId in MoveItem response.
            ItemIdType[] itemArray = new ItemIdType[this.ExistItemIds.Count];
            this.ExistItemIds.CopyTo(itemArray, 0);
            GetItemResponseType getItemResponse = this.CallGetItemOperation(itemArray);

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

            // Clear the soap header.
            this.ClearSoapHeaders();
            #endregion

            #region Step 6: Copy the message type item from Inbox folder to Drafts folder.
            // Configure the SOAP headers for CopyItem, SendItem and DeleteItem.
            headerValues.Remove("TimeZoneContext");
            this.COREAdapter.ConfigureSOAPHeader(headerValues);

            // Save the ID of the item in Inbox folder and call the CopyItem operation.
            itemArray = new ItemIdType[this.ExistItemIds.Count];
            this.ExistItemIds.CopyTo(itemArray, 0);
            CopyItemResponseType copyItemResponse = this.CallCopyItemOperation(DistinguishedFolderIdNameType.drafts, itemArray);

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

            ItemIdType[] copiedItemIds = Common.GetItemIdsFromInfoResponse(copyItemResponse);

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

            #region Step 7: Send the item in Drafts folder.
            // Call SendItem to send the copied item in Drafts folder, by using copiedItemIds in CopyItem response.
            SendItemResponseType sendResponse = this.CallSendItemOperation(
                copiedItemIds,
                DistinguishedFolderIdNameType.sentitems,
                false);

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

            // Remove the sent itemId from ExistItemIds list, since the item has been sent out and no copy remains.
            this.ExistItemIds.Remove(copiedItemIds[0] as ItemIdType);
            #endregion

            #region Step 8: Delete the item in Inbox folder and clean all items sent out.
            // Delete the item in Inbox folder and clear the ExistItemIds list.
            DeleteItemResponseType deleteItemResponse = this.CallDeleteItemOperation();

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

            this.InitializeCollection();

            // Clear the soap header.
            this.ClearSoapHeaders();

            // Clean the items sent out.
            this.CleanItemsSentOut(new string[] { items[0].Subject });
            #endregion
        }
        public void MSOXWSMSG_S03_TC01_CopyMessage()
        {
            #region Create message
            CreateItemType createItemRequest = GetCreateItemType(MessageDispositionType.SaveOnly, DistinguishedFolderIdNameType.drafts);
            CreateItemResponseType createItemResponse = this.MSGAdapter.CreateItem(createItemRequest);
            Site.Assert.IsTrue(this.VerifyCreateItemResponse(createItemResponse, MessageDispositionType.SaveOnly), @"Server should return success for creating the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(createItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);

            // Save the ItemId of message responseMessageItem got from the createItem response.
            ItemIdType itemIdType = new ItemIdType();
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            itemIdType.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            itemIdType.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;
            #endregion

            #region Copy message
            CopyItemType copyItemRequest = new CopyItemType
            {
                ItemIds = new ItemIdType[]
                {
                    itemIdType
                },

                // Save the copy message to inbox folder.
                ToFolderId = new TargetFolderIdType
                {
                    Item = new DistinguishedFolderIdType
                    {
                        Id = DistinguishedFolderIdNameType.inbox
                    }
                }
            };

            CopyItemResponseType copyItemResponse = this.MSGAdapter.CopyItem(copyItemRequest);
            Site.Assert.IsTrue(this.VerifyResponse(copyItemResponse), @"Server should return success for copying the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(copyItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);
            Site.Assert.IsNotNull(this.infoItems, @"InfoItems in the returned response should not be null.");
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem, @"The first item of the array of ItemType type from server response should not be null.");

            // Save the ItemId of message responseMessageItem got from the copyItem response.
            ItemIdType copyItemIdType = new ItemIdType();
            Site.Assert.IsNotNull(this.firstItemOfFirstInfoItem.ItemId, @"The ItemId property of the first item should not be null.");
            copyItemIdType.Id = this.firstItemOfFirstInfoItem.ItemId.Id;
            copyItemIdType.ChangeKey = this.firstItemOfFirstInfoItem.ItemId.ChangeKey;

            #region Verify the requirements about CopyItem
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMSG_R168");
        
            // Verify MS-OXWSMSG requirement: MS-OXWSMSG_R168            
            Site.CaptureRequirementIfIsNotNull(
                copyItemResponse,
                168,
                @"[In CopyItem] The protocol client sends a CopyItemSoapIn request WSDL message, and the protocol server responds with a CopyItemSoapOut response WSDL message.");

            Site.Assert.IsNotNull(this.infoItems[0].ResponseClass, @"The ResponseClass property of the first item of infoItems instance should not be null.");
            
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMSG_R169");
        
            // Verify MS-OXWSMSG requirement: MS-OXWSMSG_R169            
            Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                ResponseClassType.Success,
                copyItemResponse.ResponseMessages.Items[0].ResponseClass,
                169,
                @"[In CopyItem] If the CreateItem WSDL operation request is successful, the server returns a CreateItemResponse element, as specified in [MS-OXWSCORE] section 3.1.4.2.2.2, with the ResponseClass attribute, as specified in [MS-OXWSCDATA] section 2.2.4.67, of the CreateItemResponseMessage element, as specified in [MS-OXWSCDATA] section 2.2.4.12, set to ""Success"". ");

            Site.Assert.IsNotNull(this.infoItems[0].ResponseCode, @"The ResponseCode property of the first item of infoItems instance should not be null.");
            
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSMSG_R170");
        
            // Verify MS-OXWSMSG requirement: MS-OXWSMSG_R170
            Site.CaptureRequirementIfAreEqual<ResponseCodeType>(
                ResponseCodeType.NoError,
                copyItemResponse.ResponseMessages.Items[0].ResponseCode,
                170,
                @"[In CopyItem] [A successful CopyItem operation request returns a CopyItemResponse element] The ResponseCode element, as specified in [MS-OXWSCDATA] section 2.2.4.67, of the CreateItemResponseMessage element is set to ""NoError"". ");
            #endregion
            #endregion

            #region Delete the copied Email messages
            DeleteItemType deleteItemRequest = new DeleteItemType
            {
                ItemIds = new ItemIdType[]
                {
                   itemIdType,
                   copyItemIdType
                }
            };

            DeleteItemResponseType deleteItemResponse = this.MSGAdapter.DeleteItem(deleteItemRequest);
            Site.Assert.IsTrue(this.VerifyMultipleResponse(deleteItemResponse), @"Server should return success for deleting the email messages.");
            #endregion
        }
        public void MSOXWSCORE_S04_TC09_OperateMultipleEmailItemsSuccessfully()
        {
            #region Step 1: Create multiple items.
            EmailAddressType address = new EmailAddressType()
            {
                EmailAddress = Common.GetConfigurationPropertyValue("User2Name", this.Site) + "@" + Common.GetConfigurationPropertyValue("Domain", this.Site),
            };

            MessageType[] items = new MessageType[]
            {
                new MessageType
                {
                    Subject = Common.GenerateResourceName(
                        this.Site,
                        TestSuiteHelper.SubjectForCreateItem,
                        1),

                    ToRecipients = new EmailAddressType[]
                    {
                        address
                    }
                },
                new MessageType
                {
                    Subject = Common.GenerateResourceName(
                        this.Site,
                        TestSuiteHelper.SubjectForCreateItem,
                        2),

                    ToRecipients = new EmailAddressType[]
                    {
                        address
                    }
                }
            };

            CreateItemResponseType createItemResponse = this.CallCreateItemOperation(DistinguishedFolderIdNameType.drafts, items);

            // Check the operation response.
            Common.CheckOperationSuccess(createItemResponse, 2, this.Site);

            ItemType[] createdItems = Common.GetItemsFromInfoResponse<ItemType>(createItemResponse);

            // Two created items should be returned.
            Site.Assert.AreEqual<int>(
                    2,
                    createdItems.GetLength(0),
                    "Two created item should be returned! Expected Item Count: {0}, Actual Item Count: {1}",
                    2,
                    createdItems.GetLength(0));
            #endregion

            #region Step 2 - 5: Update, move, get and copy the items.
            this.OperateMultipleItems(createdItems);
            #endregion

            #region Step 6: Send the items and clean the items sent out.
            // Call SendItem to send the created message items from Inbox folder to the recipient identified by the ToRecipients element, by using createdItemIds in CreateItem response.
            ItemIdType[] itemArray = new ItemIdType[this.CopiedItemIds.Count];
            this.CopiedItemIds.CopyTo(itemArray, 0);
            SendItemResponseType sendResponse = this.CallSendItemOperation(
                itemArray,
                DistinguishedFolderIdNameType.sentitems,
                false);

            // Check the operation response.
            Common.CheckOperationSuccess(sendResponse, 2, this.Site);

            // Remove the sent items from ExistItemIds collection, since the items have been sent out and no copy remains.
            foreach (ItemIdType itemId in itemArray)
            {
                this.ExistItemIds.Remove(itemId);
            }

            // Clear the sent items.
            string[] itemSubjects = new string[2];
            itemSubjects[0] = items[0].Subject;
            itemSubjects[1] = items[1].Subject;
            this.CleanItemsSentOut(itemSubjects);
            #endregion
        }
        public void MSOXWSMSG_S01_TC05_GetAndDeleteMessageUnsuccessful()
        {
            #region Create a message with all elements except ReceivedBy and ReceivedRepresenting elements
            CreateItemType createItemRequest = GetCreateItemType(MessageDispositionType.SaveOnly, DistinguishedFolderIdNameType.drafts);
            CreateItemResponseType createItemResponse = this.MSGAdapter.CreateItem(createItemRequest);
            Site.Assert.IsTrue(this.VerifyCreateItemResponse(createItemResponse, MessageDispositionType.SaveOnly), @"Server should return success for creating the email messages.");
            this.infoItems = TestSuiteHelper.GetInfoItemsInResponse(createItemResponse);
            this.firstItemOfFirstInfoItem = TestSuiteHelper.GetItemTypeItemFromInfoItemsByIndex(this.infoItems, 0, 0);
            #endregion

            #region Delete the message created
            DeleteItemType deleteItemRequest = new DeleteItemType
            {
                ItemIds = new ItemIdType[]
                {
                   this.firstItemOfFirstInfoItem.ItemId
                }
            };

            DeleteItemResponseType deleteItemResponse = this.MSGAdapter.DeleteItem(deleteItemRequest);
            Site.Assert.IsTrue(this.VerifyResponse(deleteItemResponse), @"Server should return success for deleting the email messages.");
            #endregion

            #region Get the created message via itemIdType in above steps
            GetItemType getItemRequest = DefineGeneralGetItemRequestMessage(this.firstItemOfFirstInfoItem.ItemId, DefaultShapeNamesType.IdOnly);
            GetItemResponseType getItemResponse = this.MSGAdapter.GetItem(getItemRequest);

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

            this.Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                ResponseClassType.Error,
                getItemResponse.ResponseMessages.Items[0].ResponseClass,
                135001,
                @"[In GetItem] If the GetItem WSDL operation request is not successful, it returns a GetItemResponse element with the ResponseClass attribute of the GetItemResponseMessage element set to ""Error"". ");

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

            this.Site.CaptureRequirementIfIsTrue(
                System.Enum.IsDefined(typeof(ResponseCodeType), getItemResponse.ResponseMessages.Items[0].ResponseCode),
                135002,
                @"[In GetItem] [A unsuccessful GetItem operation request returns a GetItemResponse element] The ResponseCode element of the GetItemResponseMessage element is set to one of the common errors defined in [MS-OXWSCDATA] section 2.2.5.24.");
            #endregion

            #region Delete the message deleted.
            ItemIdType itemId = new ItemIdType()
            {
                Id = this.firstItemOfFirstInfoItem.ItemId.Id + "invalid",
                ChangeKey = this.firstItemOfFirstInfoItem.ItemId.Id,
            };

            deleteItemRequest.ItemIds = new ItemIdType[] { itemId };
            deleteItemResponse = this.MSGAdapter.DeleteItem(deleteItemRequest);
            this.Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                ResponseClassType.Error,
                deleteItemResponse.ResponseMessages.Items[0].ResponseClass,
                154001,
                @"[In DeleteItem] If the DeleteItem WSDL operation request is not successful, it returns a DeleteItemResponse element with the ResponseClass attribute of the DeleteItemResponseMessage element set to ""Error"". ");
            
            this.Site.CaptureRequirementIfIsTrue(
                System.Enum.IsDefined(typeof(ResponseCodeType), deleteItemResponse.ResponseMessages.Items[0].ResponseCode),
                154002,
                @"[In DeleteItem] [A unsuccessful DeleteItem operation request returns a DeleteItemResponse element] The ResponseCode element of the DeleteItemResponseMessage element is set to one of the common errors defined in [MS-OXWSCDATA] section 2.2.5.24.");
            #endregion
        }
        public void MSOXWSCORE_S04_TC18_MarkAsJunkSuccessfully()
        {
            Site.Assume.IsTrue(Common.IsRequirementEnabled(1787, this.Site), "Exchange 2007 and Exchange 2010 do not use the MarkAsJunk operation");

            #region Create the successful message
            MessageType[] items = new MessageType[]
            {
                new MessageType
                {
                    Sender = new SingleRecipientType
                    {
                        Item = new EmailAddressType
                        {
                            EmailAddress = Common.GetConfigurationPropertyValue("User2Name", this.Site) + "@" + Common.GetConfigurationPropertyValue("Domain", this.Site)
                        }
                    },

                    Subject = Common.GenerateResourceName(this.Site, TestSuiteHelper.SubjectForCreateItem),
                }
            };

            string itemSubject = items[0].Subject;
            string itemSender = items[0].Sender.Item.EmailAddress;

            CreateItemResponseType createItemResponse = this.CallCreateItemOperation(DistinguishedFolderIdNameType.drafts, items);

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

            MarkAsJunkType markAsJunkRequest = new MarkAsJunkType();
            markAsJunkRequest.ItemIds = Common.GetItemIdsFromInfoResponse(createItemResponse);
            markAsJunkRequest.IsJunk = true;
            markAsJunkRequest.MoveItem = true;

            MarkAsJunkResponseType markAsJunkResponse = this.COREAdapter.MarkAsJunk(markAsJunkRequest);

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

            MarkAsJunkResponseMessageType markAsJunkResponseMessage = (MarkAsJunkResponseMessageType)markAsJunkResponse.ResponseMessages.Items[0];

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

                // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1787
                this.Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                    ResponseClassType.Success,
                    markAsJunkResponseMessage.ResponseClass,
                    1787,
                    @"[In Appendix C: Product Behavior] Implementation does use [The operation ""MarkAsJunk""] which Marks an item as junk. (Exchange 2013 and above follow this behavior.)");
            }

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

                // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1790
                this.Site.CaptureRequirementIfAreEqual<ResponseClassType>(
                    ResponseClassType.Success,
                    markAsJunkResponseMessage.ResponseClass,
                    1790,
                    @"[In Appendix C: Product Behavior] Implementation does use the MarkAsJunk operation which marks an item as junk. (Exchange 2013 and above follow this behavior.)");
            }

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

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1844
            this.Site.CaptureRequirementIfIsNotNull(
                markAsJunkResponse,
                1844,
                @"[In m:MarkAsJunkResponseType Complex Type] This type [MarkAsJunkResponseType Complex Type] extends the BaseResponseMessageType, as specified in [MS-OXWSCDATA] section 2.2.4.16.");

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

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1847
            this.Site.CaptureRequirementIfIsNotNull(
                markAsJunkResponseMessage,
                1847,
                @"[In m:MarkAsJunkResponseMessageType Complex Type] This type [MarkAsJunkResponseMessageType Complex Type] extends the ResponseMessageType complex type, as specified in [MS-OXWSCDATA] section 2.2.4.57.");

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

            // Verify MS-OXWSCDATA requirement: MS-OXWSCDATA_R3060
            this.Site.CaptureRequirementIfIsNotNull(
                markAsJunkResponseMessage,
                "MS-OXWSCDATA",
                3060,
                @"[In m:ArrayOfResponseMessagesType Complex Type] The element ""MarkAsJunkResponseMessage"" with type ""m:MarkAsJunkResponseMessageType ([MS-OXWSCORE] section 3.1.4.6.3.3)"" specifies the response message for the MarkAsJunk operation ([MS-OXWSCORE] section 3.1.4.6).");

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

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1850
            this.Site.CaptureRequirementIfIsInstanceOfType(
                markAsJunkResponseMessage.MovedItemId,
                typeof(ItemIdType),
                1850,
                @"[In m:MarkAsJunkResponseMessageType Complex Type] The type of MovedItemId is t:ItemIdType (section 2.2.4.19).");

            ItemIdType[] getItemIds = new ItemIdType[] { markAsJunkResponseMessage.MovedItemId };
            GetItemResponseType getItemResponse = this.CallGetItemOperation(getItemIds);

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

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

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1851
            // When use the MovedItemId to get item and only one item is returned in the response, it means that the MovedItemId specifies an identifier of the moved item, thus this requirement can be verified.
            this.Site.CaptureRequirement(
                1851,
                @"[In m:MarkAsJunkResponseMessageType Complex Type] [The child element ""MovedItemId""] Specifies the item identifier of the moved item. ");

            // Find the item in the Junk Email folder.
            ItemIdType[] foundItems = this.FindItemsInFolder(DistinguishedFolderIdNameType.junkemail, itemSubject, "User1");

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

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1920
            // Since the value of IsJunk is true and the value of MoveItem is true, the item is moved to the Junk Email folder. Thus the response of FindItem should not be null, then this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                foundItems,
                1920,
                @"[In m:MarkAsJunkType Complex Type] [When the value of ""IsJunk"" is] True and [the value of ""MoveItem"" is] True, The operation moves the email item to the Junk Email folder. ");
            
            string blockedSender = null;
            string userName = Common.GetConfigurationPropertyValue("User1Name", this.Site);
            blockedSender = this.CORESUTControlAdapter.GetMailboxJunkEmailConfiguration(userName);

            bool isInBlockedSender = blockedSender.Contains(itemSender);

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

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1839
            this.Site.CaptureRequirementIfIsTrue(
                isInBlockedSender,
                1839,
                @"[In m:MarkAsJunkType Complex Type] [When the value of ""IsJunk"" is] True and [the value of ""MoveItem"" is] True, the operation adds the sender of the email to the blocked sender list and moves the email item to the Junk Email folder.");

            markAsJunkRequest.ItemIds = foundItems;
            markAsJunkRequest.IsJunk = true;
            markAsJunkRequest.MoveItem = false;
            markAsJunkResponse = this.COREAdapter.MarkAsJunk(markAsJunkRequest);

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

            // Find the item in the Junk Email folder.
            foundItems = this.FindItemsInFolder(DistinguishedFolderIdNameType.junkemail, itemSubject, "User1");

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

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1921
            // Since the value of IsJunk is true and the value of MoveItem is false, the item is still in the Junk Email folder. Thus the response of FindItem should not be null, then this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                foundItems,
                1921,
                @"[In m:MarkAsJunkType Complex Type] [When the value of ""IsJunk"" is] True and [the value of ""MoveItem"" is] False,The email item is not moved.");

            blockedSender = this.CORESUTControlAdapter.GetMailboxJunkEmailConfiguration(userName);
            isInBlockedSender = blockedSender.Contains(itemSender);

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

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1840
            this.Site.CaptureRequirementIfIsTrue(
                isInBlockedSender,
                1840,
                @"[In m:MarkAsJunkType Complex Type] [When the value of ""IsJunk"" is] True and [the value of ""MoveItem"" is] False, the operation adds the sender of the email to the blocked sender list.");

            markAsJunkRequest.ItemIds = foundItems;
            markAsJunkRequest.IsJunk = false;
            markAsJunkRequest.MoveItem = true;
            markAsJunkResponse = this.COREAdapter.MarkAsJunk(markAsJunkRequest);

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

            // Find the item in the Inbox folder.
            foundItems = this.FindItemsInFolder(DistinguishedFolderIdNameType.inbox, itemSubject, "User1");

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

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1922
            // Since the value of IsJunk is false and the value of MoveItem is true, the item is moved to the inbox folder. Thus the response of FindItem should not be null, then this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                foundItems,
                1922,
                @"[In m:MarkAsJunkType Complex Type] [When the value of ""IsJunk"" is] False and [the value of ""MoveItem"" is] True, The operation moves the email item back to the Inbox folder.");

            blockedSender = this.CORESUTControlAdapter.GetMailboxJunkEmailConfiguration(userName);
            isInBlockedSender = blockedSender.Contains(itemSender);

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

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1841
            this.Site.CaptureRequirementIfIsFalse(
                isInBlockedSender,
                1841,
                @"[In m:MarkAsJunkType Complex Type] [When the value of ""IsJunk"" is] False and [the value of ""MoveItem"" is] True, the operation removes the sender from the blocked sender list.");

            markAsJunkRequest.ItemIds = foundItems;
            markAsJunkRequest.IsJunk = false;
            markAsJunkRequest.MoveItem = false;
            markAsJunkResponse = this.COREAdapter.MarkAsJunk(markAsJunkRequest);

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

            // Find the item in the Inbox folder.
            foundItems = this.FindItemsInFolder(DistinguishedFolderIdNameType.inbox, itemSubject, "User1");

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

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1923
            // Since the value of IsJunk is false and the value of MoveItem is false, the item is still in the Inbox folder. Thus the response of FindItem should not be null, then this requirement can be verified.
            this.Site.CaptureRequirementIfIsNotNull(
                foundItems,
                1923,
                @"[In m:MarkAsJunkType Complex Type] [When the value of ""IsJunk"" is] False and [the value of ""MoveItem"" is] False, The email item is not moved.");

            blockedSender = this.CORESUTControlAdapter.GetMailboxJunkEmailConfiguration(userName);
            isInBlockedSender = blockedSender.Contains(itemSender);

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

            // Verify MS-OXWSCORE requirement: MS-OXWSCORE_R1842
            this.Site.CaptureRequirementIfIsFalse(
                isInBlockedSender,
                1842,
                @"[In m:MarkAsJunkType Complex Type] [When the value of ""IsJunk"" is] False and [the value of ""MoveItem"" is] False, the operation removes the sender from the blocked sender list.");

            this.ExistItemIds.Clear();
            this.ExistItemIds.Add(foundItems[0]);
            #endregion
        }
        public void MSOXWSCONT_S01_TC02_VerifyContactItemWithAllElement()
        {
            #region Step 1:Create the all property contact item.
            // Create a full property contact item.
            ContactItemType item = this.CreateFullPropertiesContact();
            CreateItemResponseType createItemResponse = this.CallCreateItemOperation(item);

            // Check the response.
            Common.CheckOperationSuccess(createItemResponse, 1, this.Site);
            #endregion

            #region Step 2:Get the created contact item.
            // The contact item to get.
            ItemIdType[] itemArray = new ItemIdType[this.ExistContactItems.Count];
            this.ExistContactItems.CopyTo(itemArray, 0);

            GetItemResponseType getItemResponse = this.CallGetItemOperation(itemArray);

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

            ContactItemType[] contacts = Common.GetItemsFromInfoResponse<ContactItemType>(getItemResponse);

            Site.Assert.AreEqual<int>(
                1,
                contacts.Length,
                string.Format(
                    "The count of items from response should be 1, actual: '{0}'.", contacts.Length));

            this.VerifyChildElementInContactItemTypeComplexType(contacts[0], item);
            #endregion
        }
        /// <summary>
        /// Initialize the Test suite.
        /// </summary>
        protected override void TestInitialize()
        {
            base.TestInitialize();
            this.BTRFAdapter = Site.GetAdapter<IMS_OXWSBTRFAdapter>();

            // If implementation doesn't support this specification [MS-OXWSBTRF] as specified in section 8, the case will not start.
            if (!bool.Parse(Common.GetConfigurationPropertyValue("MS-OXWSBTRF_Supported", this.Site)))
            {
                SutVersion currentSutVersion = (SutVersion)Enum.Parse(typeof(SutVersion), Common.GetConfigurationPropertyValue("SutVersion", this.Site));
                this.Site.Assert.Inconclusive("This test suite is not supported under current SUT, because MS-OXWSBTRF_Supported value is set to false in MS-OXWSBTRF_{0}_SHOULDMAY.deployment.ptfconfig file.", currentSutVersion);
            }
            else
            {
                this.FOLDAdapter = Site.GetAdapter<IMS_OXWSFOLDAdapter>();
                this.COREAdapter = Site.GetAdapter<IMS_OXWSCOREAdapter>();
                this.BTRFSUTControlAdapter = Site.GetAdapter<IMS_OXWSBTRFSUTControlAdapter>();

                // Add four folder types to ParentFolderType list.
                this.ParentFolderType = new Collection<DistinguishedFolderIdNameType>() 
                {
                    DistinguishedFolderIdNameType.inbox, 
                    DistinguishedFolderIdNameType.calendar, 
                    DistinguishedFolderIdNameType.contacts, 
                    DistinguishedFolderIdNameType.tasks 
                };

                // Initialize the OriginalFolderId collection to store the folder ids that items will be exported from and uploaded to
                this.OriginalFolderId = new Collection<string>();
                for (int i = 0; i < this.ParentFolderType.Count; i++)
                {
                    // Generate the folder name.
                    string folderName = Common.GenerateResourceName(this.Site, this.ParentFolderType[i] + "OriginalFolder");

                    // Create a sub folder in the specified parent folder.
                    string folderId = this.CreateSubFolder(this.ParentFolderType[i], folderName);

                    // Add the new created sub folder's id to OriginalFolderId collection.
                    this.OriginalFolderId.Add(folderId);
                    Site.Assert.IsNotNull(
                        this.OriginalFolderId[i],
                        string.Format(
                        "The sub folder named '{0}' in folder '{1}' should be created successfully.",
                        folderName,
                        this.ParentFolderType[i].ToString()));
                }

                // Initialize the CreatedItemSubject list to store all created item subjects.
                this.CreatedItemSubject = new Collection<string>();

                // Initialize CreatedItemId list to store all created item ids.
                this.CreatedItemId = new Collection<ItemIdType>();

                // Create an ItemIdType array to store the created items' ids.
                ItemIdType[] itemIds = new ItemIdType[this.OriginalFolderId.Count];

                for (int i = 0; i < itemIds.Length; i++)
                {
                    // Generate the item subject.
                    string itemSubject = Common.GenerateResourceName(this.Site, this.ParentFolderType[i] + "Item");

                    // Create items in the created sub folders. 
                    itemIds[i] = this.CreateItem(this.ParentFolderType[i], this.OriginalFolderId[i], itemSubject);
                    Site.Assert.IsNotNull(itemIds[i], string.Format("The item with subject '{0}' should be created successfully!", itemSubject));

                    // If the item id is not empty, add it to the CreatedItemId list.
                    this.CreatedItemId.Add(itemIds[i]);

                    // Add the Subject to the CreatedItemSubject list.
                    this.CreatedItemSubject.Add(itemSubject);
                }

                this.ItemCount = this.CreatedItemId.Count;
                ExchangeServiceBinding.ServiceResponseEvent += new ExchangeServiceBinding.ServiceResponseDelegate(this.ExchangeServiceBinding_ResponseEvent);
            }
        }
        public void MSOXWSSYNC_S02_TC02_SyncFolderItems_MeetingRequestMessageType()
        {
            #region Step 1. Client invokes SyncFolderItems operation to get the initial syncState of sent items folder.
            DistinguishedFolderIdNameType sentItemsFolder = DistinguishedFolderIdNameType.sentitems;
            SyncFolderItemsType request = this.CreateSyncFolderItemsRequestWithoutOptionalElements(sentItemsFolder, DefaultShapeNamesType.Default);
            SyncFolderItemsResponseType response = this.SYNCAdapter.SyncFolderItems(request);
            SyncFolderItemsResponseMessageType responseMessage = TestSuiteHelper.EnsureResponse<SyncFolderItemsResponseMessageType>(response);
            #endregion

            #region Step 2. Client invokes CreateItem operation to create a MeetingRequestMessageType item.
            // Generate the item subject
            string itemSubject = Common.GenerateResourceName(this.Site, sentItemsFolder + "ItemSubject");
            this.CreateMeetingRequest(this.User2EmailAddress, itemSubject);

            // Make sure that the meeting request exists in inbox folder of User2.
            bool isReceivedInInbox = this.SYNCSUTControlAdapter.IsItemExisting(
                Common.GetConfigurationPropertyValue("User2Name", this.Site),
                Common.GetConfigurationPropertyValue("User2Password", this.Site),
                Common.GetConfigurationPropertyValue("Domain", this.Site),
                DistinguishedFolderIdNameType.inbox.ToString(),
                itemSubject,
                Item.MeetingRequest.ToString());
            Site.Assert.IsTrue(
                isReceivedInInbox,
                string.Format("The meeting request message should exist in inbox folder of '{0}'", Common.GetConfigurationPropertyValue("User2Name", this.Site)));
            #endregion

            #region Step 3. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 2 and verify related requirements.
            responseMessage = this.GetResponseMessage(sentItemsFolder, responseMessage, DefaultShapeNamesType.Default);

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item created on server, so the changes between server and client should not be null");
            SyncFolderItemsChangesType changes = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changes.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item created on server.");
            Site.Assert.IsNotNull(changes.Items, "There should be item information returned in SyncFolderItems response since there is one item created on server.");

            Site.Assert.AreEqual<int>(1, changes.Items.Length, "Just one MeetingRequestMessageType item was created in previous step, so the count of Items array in responseMessage.Changes should be 1.");

            // If the type of item in SyncFolderItems response is MeetingRequestMessageType, then requirement MS-OXWSSYNC_R166 can be captured.
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSSYNC_R166");

            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R166
            Site.CaptureRequirementIfIsInstanceOfType(
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item,
                typeof(MeetingRequestMessageType),
                166,
                @"[In t:SyncFolderItemsCreateOrUpdateType Complex Type] The type of MeetingRequest is t:MeetingRequestMessageType ([MS-OXWSMTGS] section 2.2.4.22).");

            Site.Assert.AreEqual<int>(1, changes.ItemsElementName.Length, "Just one MeetingRequestMessageType item was created in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");
            bool isMeetingRequestCreated = changes.ItemsElementName[0] == ItemsChoiceType1.Create &&
                    (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType() == typeof(MeetingRequestMessageType);

            // Add the debug information
            Site.Log.Add(
                LogEntryKind.Debug,
                "Verify MS-OXWSSYNC_R1671. Expected value: ItemsElementName: {0}, item type: {1}; actual value: ItemsElementName: {2}, item type: {3}",
                ItemsChoiceType1.Create,
                typeof(MeetingRequestMessageType),
                changes.ItemsElementName[0],
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType());

            // If the ItemsElementName of Changes is Create and the type of Item is MeetingRequestMessageType, it indicates a meeting 
            // request has been created on server and synced on client, then requirement MS-OXWSSYNC_R1671 can be captured.
            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R1671
            Site.CaptureRequirementIfIsTrue(
                isMeetingRequestCreated,
                1671,
                @"[In t:SyncFolderItemsCreateOrUpdateType Complex Type] [The element MeetingRequest] specifies a meeting request message to create in the client message store.");
            #endregion

            #region Step 4. Client invokes UpdateItem operation to update the subject of the item that created in Step 2.
            // Generate a new item subject
            string newItemSubject = Common.GenerateResourceName(this.Site, sentItemsFolder + "NewItemSubject");
            ItemIdType[] itemId = new ItemIdType[1] { (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.ItemId };
            this.UpdateItemSubject(itemId, newItemSubject);
            #endregion

            #region Step 5. Client invokes SyncFolderItems operation with previous SyncState to get the operation result in Step 4 and verify related requirements.
            responseMessage = this.GetResponseMessage(sentItemsFolder, responseMessage, DefaultShapeNamesType.AllProperties);

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item updated on server, so the changes between server and client should not be null");
            changes = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changes.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item updated on server.");
            Site.Assert.IsNotNull(changes.Items, "There should be item information returned in SyncFolderItems response since there is one item updated on server.");

            Site.Assert.AreEqual<int>(1, changes.Items.Length, "Just one MeetingRequestMessageType item was updated in previous step, so the count of Items array in responseMessage.Changes should be 1.");
            Site.Assert.AreEqual<int>(1, changes.ItemsElementName.Length, "Just one MeetingRequestMessageType item was updated in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");
            bool isMeetingRequestUpdated = changes.ItemsElementName[0] == ItemsChoiceType1.Update &&
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType() == typeof(MeetingRequestMessageType);

            // Add the debug information
            Site.Log.Add(
                LogEntryKind.Debug,
                "Verify MS-OXWSSYNC_R1672. Expected value: ItemsElementName: {0}, item type: {1}; actual value: ItemsElementName: {2}, item type: {3}",
                ItemsChoiceType1.Update,
                typeof(MeetingRequestMessageType),
                changes.ItemsElementName[0],
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType());

            // If the ItemsElementName of Changes is Update and the type of Item is MeetingRequestMessageType, it indicates a meeting 
            // request has been updated on server and synced on client, then requirement MS-OXWSSYNC_R1672 can be captured.
            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R1672
            Site.CaptureRequirementIfIsTrue(
                isMeetingRequestUpdated,
                1672,
                @"[In t:SyncFolderItemsCreateOrUpdateType Complex Type] [The element MeetingRequest] specifies a meeting request message to update in the client message store.");

            // Call GetItem operation to get the parent folder Id of the item that in SyncFolderItems response.
            GetItemType getItemRequest = new GetItemType();
            getItemRequest.ItemIds = new BaseItemIdType[1] { (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.ItemId };
            getItemRequest.ItemShape = new ItemResponseShapeType();
            getItemRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;
            GetItemResponseType getItemResponse = this.COREAdapter.GetItem(getItemRequest);

            // Check whether the GetItem operation is executed successfully.
            foreach (ResponseMessageType message in getItemResponse.ResponseMessages.Items)
            {
                Site.Assert.AreEqual<ResponseClassType>(
                        ResponseClassType.Success,
                        message.ResponseClass,
                        string.Format("Get item should be successful! Expected response code: {0}, actual response code: {1}", ResponseCodeType.NoError, message.ResponseCode));
            }

            // Get the item information from GetItem response
            MeetingRequestMessageType[] item = Common.GetItemsFromInfoResponse<MeetingRequestMessageType>(getItemResponse);
            Site.Assert.AreEqual<int>(1, item.Length, "Only one MeetingRequestMessageType item was created, so there should be only 1 item in GetItem response.");

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

            // If the parent folder Id of the item in GetItem response is same with it in SyncFolderItems response, 
            // it indicates the folder contains the item to synchronize, then requirement MS-OXWSSYNC_R380 can be captured.
            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R380
            Site.CaptureRequirementIfAreEqual<string>(
                item[0].ParentFolderId.Id,
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.ParentFolderId.Id,
                380,
                @"[In m:SyncFolderItemsType Complex Type] [The element SyncFolderId] specifies the identity of the folder that contains the items to synchronize.");
            #endregion

            #region Step 6. Client invokes UpdateItem operation to change the IsRead property of the item which updated in Step 4.
            itemId = new ItemIdType[1] { (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.ItemId };
            this.UpdateReadFlag(itemId, this.ConvertReadFlag(itemId));
            #endregion

            #region Step 7. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 6.
            responseMessage = this.GetResponseMessage(sentItemsFolder, responseMessage, DefaultShapeNamesType.Default);

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item updated on server, so the changes between server and client should not be null");
            SyncFolderItemsChangesType changesAfterUpdateReadFlag = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changesAfterUpdateReadFlag.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item updated on server.");
            Site.Assert.IsNotNull(changesAfterUpdateReadFlag.Items, "There should be item information returned in SyncFolderItems response since there is one item updated on server.");

            Site.Assert.AreEqual<int>(1, changesAfterUpdateReadFlag.Items.Length, "Just one MeetingRequestMessageType item was updated in previous step, so the count of Items array in responseMessage.Changes should be 1.");
            #endregion

            #region Step 8. Client invokes DeleteItem operation to delete the item which updated in Step 6.
            bool isDeleted = this.SYNCSUTControlAdapter.FindAndDeleteItem(
                Common.GetConfigurationPropertyValue("User1Name", this.Site),
                Common.GetConfigurationPropertyValue("User1Password", this.Site),
                Common.GetConfigurationPropertyValue("Domain", this.Site),
                sentItemsFolder.ToString(),
                newItemSubject,
                Item.MeetingRequest.ToString());
            Site.Assert.IsTrue(isDeleted, string.Format("The item named '{0}' should be deleted from folder '{1}' successfully.", newItemSubject, sentItemsFolder));
            #endregion

            #region Step 9. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 8 and verify related requirements.
            responseMessage = this.GetResponseMessage(sentItemsFolder, responseMessage, DefaultShapeNamesType.Default);

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item deleted on server, so the changes between server and client should not be null");
            SyncFolderItemsChangesType changesAfterDelete = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changesAfterDelete.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item deleted on server.");
            Site.Assert.IsNotNull(changesAfterDelete.Items, "There should be item information returned in SyncFolderItems response since there is one item deleted on server.");

            Site.Assert.AreEqual<int>(1, changesAfterDelete.Items.Length, "Just one MeetingRequestMessageType item was deleted in previous step, so the count of Items array in responseMessage.Changes should be 1.");
            Site.Assert.AreEqual<int>(1, changesAfterDelete.ItemsElementName.Length, "Just one MeetingRequestMessageType item was deleted in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");

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

            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R184
            Site.CaptureRequirementIfAreEqual<string>(
                (changesAfterUpdateReadFlag.Items[0] as SyncFolderItemsReadFlagType).ItemId.Id,
                (changesAfterDelete.Items[0] as SyncFolderItemsDeleteType).ItemId.Id,
                184,
                @"[In t:SyncFolderItemsDeleteType Complex Type] [The element ItemId] specifies the identifier of the item to delete from the client message store.");

            bool isIncrementalSync = changesAfterDelete.ItemsElementName[0] == ItemsChoiceType1.Delete && responseMessage.SyncState != null;

            // If the ItemsElementName is Delete and the SyncState element is not null, then requirement MS-OXWSSYNC_R504 can be captured.
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSSYNC_R504");

            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R504
            Site.CaptureRequirementIfIsTrue(
                isIncrementalSync,
                504,
                @"[In Abstract Data Model]  If the SyncState element of the SyncFolderItemsType complex type (section 3.1.4.2.3.8) is included in a SyncFolderItems operation (section 3.1.4.2), the server MUST return incremental synchronization information from the last synchronization request.");
            #endregion

            #region Step 10 Clean up the mailbox of attendee.
            this.CleanupAttendeeMailbox();
            #endregion
        }
        /// <summary>
        /// Call GetItem operation.
        /// </summary>
        /// <param name="itemIds">The ItemIds to be gotten.</param>
        /// <returns>The GetItem response.</returns>
        protected GetItemResponseType CallGetItemOperation(ItemIdType[] itemIds)
        {
            GetItemType getItem = new GetItemType();
            GetItemResponseType getItemResponse = new GetItemResponseType();

            // Set the ItemShape property of GetItem operation's request
            getItem.ItemShape = new ItemResponseShapeType();
            getItem.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;

            // The contact item to get.
            getItem.ItemIds = itemIds;

            getItemResponse = this.CONTAdapter.GetItem(getItem);

            return getItemResponse;
        }
        public void MSOXWSSYNC_S02_TC04_SyncFolderItems_MeetingCancellationMessageType()
        {
            #region Step 1. Client invokes SyncFolderItems operation to get the initial syncState of junkemail folder.
            DistinguishedFolderIdNameType junkeFolder = DistinguishedFolderIdNameType.junkemail;
            SyncFolderItemsType request = this.CreateSyncFolderItemsRequestWithoutOptionalElements(junkeFolder, DefaultShapeNamesType.AllProperties);
            SyncFolderItemsResponseType response = this.SYNCAdapter.SyncFolderItems(request);
            SyncFolderItemsResponseMessageType responseMessage = TestSuiteHelper.EnsureResponse<SyncFolderItemsResponseMessageType>(response);
            #endregion

            #region Step 2. Client invokes CreateItem to create a MeetingCancellationMessageType item.
            // Generate the item subject
            string itemSubject = Common.GenerateResourceName(this.Site, junkeFolder + "ItemSubject");
            this.CreateMeetingCancellation(itemSubject);
            #endregion

            #region Step 3. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 2 and verify related requirements.
            responseMessage = this.GetResponseMessage(junkeFolder, responseMessage, DefaultShapeNamesType.AllProperties);

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item created on server, so the changes between server and client should not be null");
            SyncFolderItemsChangesType changes = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changes.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item created on server.");
            Site.Assert.IsNotNull(changes.Items, "There should be folders information returned in SyncFolderItems response since there is one item created on server.");

            Site.Assert.AreEqual<int>(1, changes.Items.Length, "Just one MeetingCancellationMessageType item was created in previous step, so the count of Items array in responseMessage.Changes should be 1.");

            // If the type of item in SyncFolderItems response is MeetingCancellationMessageType, then requirement MS-OXWSSYNC_R170 can be captured.
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXWSSYNC_R170");

            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R170
            Site.CaptureRequirementIfIsInstanceOfType(
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item,
                typeof(MeetingCancellationMessageType),
                170,
                @"[In t:SyncFolderItemsCreateOrUpdateType Complex Type] The type of MeetingCancellation is t:MeetingCancellationMessageType ([MS-OXWSMTGS] section 2.2.4.19).");

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

            // For the item creator, the read flag of a new created item should be true
            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R1951
            Site.CaptureRequirementIfIsTrue(
                ((changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item as MeetingCancellationMessageType).IsRead,
                1951,
                @"[In t:SyncFolderItemsReadFlagType Complex Type] [The element IsRead] True if the item has been read.");

            // Assert both the length of responseMessage.Changes.ItemsElementName and responseMessage.Changes.Items are 1.
            Site.Assert.AreEqual<int>(1, changes.ItemsElementName.Length, "Just one MeetingCancellationMessageType item was created in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");

            bool isMeetingCancellationCreated = changes.ItemsElementName[0] == ItemsChoiceType1.Create &&
                    (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType() == typeof(MeetingCancellationMessageType);

            // Add the debug information
            Site.Log.Add(
                LogEntryKind.Debug,
                "Verify MS-OXWSSYNC_R1711. Expected value: ItemsElementName: {0}, item type: {1}; actual value: ItemsElementName: {2}, item type: {3}",
                ItemsChoiceType1.Create,
                typeof(MeetingCancellationMessageType),
                changes.ItemsElementName[0],
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType());

            // If the ItemsElementName of Changes is Create and the type of Item is MeetingCancellationMessageType, it indicates a meeting 
            // cancellation has been created on server and synced on client, then requirement MS-OXWSSYNC_R1711 can be captured.
            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R1711
            Site.CaptureRequirementIfIsTrue(
                isMeetingCancellationCreated,
                1711,
                @"[In t:SyncFolderItemsCreateOrUpdateType Complex Type][The element MeetingCancellation] specifies a meeting cancellation message to create in the client message store.");
            #endregion

            #region Step 4. Client invokes UpdateItem operation to update the item which created in Step 2.
            // Generate a new item subject
            string newItemSubject = Common.GenerateResourceName(this.Site, junkeFolder + "NewItemSubject");
            ItemIdType[] itemId = new ItemIdType[1] { (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.ItemId };
            this.UpdateItemSubject(itemId, newItemSubject);
            #endregion

            #region Step 5. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 4 and verify related requirements.
            responseMessage = this.GetResponseMessage(junkeFolder, responseMessage, DefaultShapeNamesType.AllProperties);

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item updated on server, so the changes between server and client should not be null");
            changes = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changes.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item updated on server.");
            Site.Assert.IsNotNull(changes.Items, "There should be item information returned in SyncFolderItems response since there is one item updated on server.");

            Site.Assert.AreEqual<int>(1, changes.Items.Length, "Just one MeetingCancellationMessageType item was updated in previous step, so the count of Items array in responseMessage.Changes should be 1.");
            Site.Assert.AreEqual<int>(1, changes.ItemsElementName.Length, "Just one MeetingCancellationMessageType item was updated in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");

            bool isMeetingCancellationUpdated = changes.ItemsElementName[0] == ItemsChoiceType1.Update &&
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType() == typeof(MeetingCancellationMessageType);

            // Add the debug information
            Site.Log.Add(
                LogEntryKind.Debug,
                "Verify MS-OXWSSYNC_R1712. Expected value: ItemsElementName: {0}, item type: {1}; actual value: ItemsElementName: {2}, item type: {3}",
                ItemsChoiceType1.Update,
                typeof(MeetingCancellationMessageType),
                changes.ItemsElementName[0],
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.GetType());

            // If the ItemsElementName of Changes is Update and the type of Item is MeetingCancellationMessageType, it indicates a meeting 
            // cancellation has been updated on server and synced on client, then requirement MS-OXWSSYNC_R1712 can be captured.
            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R1712
            Site.CaptureRequirementIfIsTrue(
                isMeetingCancellationUpdated,
                1712,
                @"[In t:SyncFolderItemsCreateOrUpdateType Complex Type][The element MeetingCancellation] specifies a meeting cancellation message to update in the client message store.");
            #endregion

            #region Step 6. Client invokes UpdateItem operations to change the IsRead property of the item which updated in Step 4.
            itemId = new ItemIdType[1] { (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.ItemId };

            // Call UpdateReadFlag to update the IsRead property to its opposite value.
            this.UpdateReadFlag(itemId, this.ConvertReadFlag(itemId));
            #endregion

            #region Step 7. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 6 and verify related requirements.
            responseMessage = this.GetResponseMessage(junkeFolder, responseMessage, DefaultShapeNamesType.AllProperties);

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item updated on server, so the changes between server and client should not be null");
            SyncFolderItemsChangesType changesAfterUpdateReadFlag = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changesAfterUpdateReadFlag.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item updated on server.");
            Site.Assert.IsNotNull(changesAfterUpdateReadFlag.Items, "There should be item information returned in SyncFolderItems response since there is one item updated on server.");

            Site.Assert.AreEqual<int>(1, changesAfterUpdateReadFlag.Items.Length, "Just one MeetingCancellationMessageType item was updated in previous step, so the count of Items array in responseMessage.Changes should be 1.");

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

            // If the Item id is same before and after the update of read flag, then requirement MS-OXWSSYNC_R194 can be captured 
            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R194
            Site.CaptureRequirementIfAreEqual<string>(
                (changes.Items[0] as SyncFolderItemsCreateOrUpdateType).Item.ItemId.Id,
                (changesAfterUpdateReadFlag.Items[0] as SyncFolderItemsReadFlagType).ItemId.Id,
                194,
                @"[In t:SyncFolderItemsReadFlagType Complex Type] [The element ItemID] specifies the identifier of the read item.");

            Site.Assert.AreEqual<int>(1, changesAfterUpdateReadFlag.ItemsElementName.Length, "Just one MeetingCancellationMessageType item was updated in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");

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

            // Since the original value of IsRead is true, if it was updated to an opposite value, it should be false.
            // Verify MS-OXWSSYNC requirement: MS-OXWSSYNC_R1952
            Site.CaptureRequirementIfIsFalse(
                (changesAfterUpdateReadFlag.Items[0] as SyncFolderItemsReadFlagType).IsRead,
                1952,
                @"[In t:SyncFolderItemsReadFlagType Complex Type] [The element IsRead] False if the item hasn't been read.");
            #endregion

            #region Step 8. Client invokes DeleteItem operation to delete the item which updated in Step 6.
            bool isDeleted = this.SYNCSUTControlAdapter.FindAndDeleteItem(
                Common.GetConfigurationPropertyValue("User1Name", this.Site),
                Common.GetConfigurationPropertyValue("User1Password", this.Site),
                Common.GetConfigurationPropertyValue("Domain", this.Site),
                junkeFolder.ToString(),
                newItemSubject,
                Item.MeetingCancellation.ToString());
            Site.Assert.IsTrue(isDeleted, string.Format("The item named '{0}' should be deleted from '{1}' successfully.", newItemSubject, junkeFolder));
            #endregion

            #region Step 9. Client invokes SyncFolderItems operation with previous SyncState to sync the operation result in Step 8 and verify related requirements.
            responseMessage = this.GetResponseMessage(junkeFolder, responseMessage, DefaultShapeNamesType.AllProperties);

            // Assert the changes in response is not null
            Site.Assert.IsNotNull(responseMessage.Changes, "There is one item deleted on server, so the changes between server and client should not be null");
            changes = responseMessage.Changes;

            // Assert both the Items and ItemsElementName are not null
            Site.Assert.IsNotNull(changes.ItemsElementName, "There should be changes information returned in SyncFolderItems response since there is one item deleted on server.");
            Site.Assert.IsNotNull(changes.Items, "There should be item information returned in SyncFolderItems response since there is one item deleted on server.");

            Site.Assert.AreEqual<int>(1, changes.Items.Length, "Just one MeetingCancellationMessageType item was deleted in previous step, so the count of Items array in responseMessage.Changes should be 1.");

            // Assert the Items is an instance of SyncFolderItemsDeleteType.
            Site.Assert.IsTrue(
                changes.Items[0].GetType() == typeof(SyncFolderItemsDeleteType),
                string.Format("The responseMessage.Changes.Items should be an instance of '{0}'.", typeof(SyncFolderItemsDeleteType)));

            Site.Assert.AreEqual<int>(1, changes.ItemsElementName.Length, "Just one MeetingCancellationMessageType item was deleted in previous step, so the count of ItemsElementName array in responseMessage.Changes should be 1.");
            Site.Assert.IsTrue(changes.ItemsElementName[0] == ItemsChoiceType1.Delete, string.Format("The responseMessage.Changes.ItemsElementName should be 'Delete', the actual value is '{0}'", changes.ItemsElementName[0]));
            #endregion

            #region Step 10 Clean up the mailbox of attendee.
            this.CleanupAttendeeMailbox();
            #endregion
        }
        public void MSOXWSMTGS_S05_TC04_MoveMultipleCalendarItems()
        {
            #region Define two calendar items to move
            CalendarItemType calendarItem1 = new CalendarItemType();
            calendarItem1.UID = Guid.NewGuid().ToString();
            calendarItem1.Subject = Common.GenerateResourceName(this.Site, Common.GetConfigurationPropertyValue("MeetingSubject", this.Site));
            CalendarItemType calendarItem2 = new CalendarItemType();
            calendarItem2.UID = Guid.NewGuid().ToString();
            calendarItem2.Subject = Common.GenerateResourceName(this.Site, Common.GetConfigurationPropertyValue("MeetingSubject", this.Site));
            #endregion

            #region Create the two calendar items
            ItemInfoResponseMessageType[] calendars = this.CreateMultipleCalendarItems(Role.Organizer, new ItemType[] { calendarItem1, calendarItem2 }, CalendarItemCreateOrDeleteOperationType.SendToNone);
            Site.Assert.IsNotNull(calendars, "The calendars should be created successfully.");
            Site.Assert.IsTrue(calendars.Length == 2, "There should be only two calendars created.");

            ItemIdType[] calendarIds = new ItemIdType[] { calendars[0].Items.Items[0].ItemId, calendars[1].Items.Items[0].ItemId };
            #endregion

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

            Site.Assert.IsNotNull(
                this.MoveMultipleCalendarItems(Role.Organizer, calendarIds, targetFolderId),
                "The calendars should be moved into the inbox folder successfully.");

            #endregion

            #region Call FindItem to verify the two calendar items are moved to Inbox folder
            Site.Assert.IsNull(
                this.SearchDeletedSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", calendarItem1.UID),
                "The original calendar should not be in organizer's calendar folder after MoveItem operation.");

            Site.Assert.IsNotNull(
                this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Appointment", calendarItem1.UID),
                "The original calendar should be in organizer's inbox folder after MoveItem operation.");

            Site.Assert.IsNull(
                this.SearchDeletedSingleItem(Role.Organizer, DistinguishedFolderIdNameType.calendar, "IPM.Appointment", calendarItem2.UID),
                "The original calendar should not be in organizer's calendar folder after MoveItem operation.");

            Site.Assert.IsNotNull(
                this.SearchSingleItem(Role.Organizer, DistinguishedFolderIdNameType.inbox, "IPM.Appointment", calendarItem2.UID),
                "The original calendar should be in organizer's inbox folder after MoveItem operation.");
            #endregion

            #region Clean up organizer's inbox folder.
            this.CleanupFoldersByRole(Role.Organizer, new List<DistinguishedFolderIdNameType>() { DistinguishedFolderIdNameType.inbox });
            #endregion
        }