public void MSOXCMSG_S07_TC04_Transaction()
        {
            this.CheckMapiHttpIsSupported();
            this.ConnectToServer(ConnectionType.PrivateMailboxServer);

            #region Call RopLogon to log on a mailbox.
            RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle);
            #endregion

            #region Call RopCreateMessage to create a message
            uint targetMessageHandle = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle);
            #endregion

            #region Call RopSaveChangesMessage to save the message
            RopSaveChangesMessageResponse saveChangesMessageResponse;
            saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveChangesMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopOpenMessage to open the message for the first time.
            RopOpenMessageResponse openMessageResponse;
            uint openedMessageHandle1 = this.OpenSpecificMessage(logonResponse.FolderIds[4], saveChangesMessageResponse.MessageId, this.insideObjHandle, MessageOpenModeFlags.ReadWrite, out openMessageResponse);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopOpenMessage to open the message for the second time.
            uint openedMessageHandle2 = this.OpenSpecificMessage(logonResponse.FolderIds[4], saveChangesMessageResponse.MessageId, this.insideObjHandle, MessageOpenModeFlags.ReadWrite, out openMessageResponse);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopModifyRecipient to modify the recipient.
            // Initialize TestUser1 TestUser2 TestUser5 TestUser4 TestUser3
            PropertyTag[] propertyTag = this.CreateRecipientColumns();
            List<ModifyRecipientRow> modifyRecipientRow = new List<ModifyRecipientRow>
            {
                this.CreateModifyRecipientRow(TestUser1, 0),
                this.CreateModifyRecipientRow(TestUser2, 1),
                this.CreateModifyRecipientRow(TestUser5, 2),
                this.CreateModifyRecipientRow(TestUser4, 3),
                this.CreateModifyRecipientRow(TestUser3, 4)
            };

            RopModifyRecipientsResponse modifyRecipientsResponse;
            this.AddRecipients(modifyRecipientRow, openedMessageHandle1, propertyTag, out modifyRecipientsResponse);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, modifyRecipientsResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopReadRecipients to read the recipient of the created message and expect the error code 0x8004010F (ecNotFound) is returned.
            RopReadRecipientsRequest readRecipientsRequest = new RopReadRecipientsRequest()
            {
                RopId = (byte)RopId.RopReadRecipients,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with RopReadRecipients.
                InputHandleIndex = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. 
                RowId = 0x00000000, // Starting index for the recipients to be retrieved
                Reserved = 0x0000 // Set the Reserved value to 0x0000 as indicated in Open Specification. 
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(readRecipientsRequest, openedMessageHandle2, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopReadRecipientsResponse readRecipientsResponse1 = (RopReadRecipientsResponse)this.response;
            Site.Assert.AreNotEqual<uint>(TestSuiteBase.Success, readRecipientsResponse1.ReturnValue, "Can't find any recipients of the message.");
            #endregion

            #region Call RopSaveChangesMessage to save the message
            saveChangesMessageResponse = this.SaveMessage(openedMessageHandle1, (byte)SaveFlags.ForceSave);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveChangesMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopOpenMessage to open the message for the third time.
            uint openedMessageHandle3 = this.OpenSpecificMessage(logonResponse.FolderIds[4], saveChangesMessageResponse.MessageId, this.insideObjHandle, MessageOpenModeFlags.ReadWrite, out openMessageResponse);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopReadRecipients to read the recipient of the created message again and expect a successful response
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(readRecipientsRequest, openedMessageHandle3, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopReadRecipientsResponse readRecipientsResponse2 = (RopReadRecipientsResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, readRecipientsResponse2.ReturnValue, TestSuiteBase.ROPSucceedMsg);

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R395, readRecipientsResponse1.ReturnValue is {0}, readRecipientsResponse2.ReturnValue is {1}.", readRecipientsResponse1.ReturnValue, readRecipientsResponse2.ReturnValue);
        
            // Verify MS-OXCMSG requirement: MS-OXCMSG_R395
            bool isVerifiedR395 = readRecipientsResponse1.ReturnValue != 0x00000000 && readRecipientsResponse2.ReturnValue == 0x00000000;
            
            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR395,
                395,
                @"[In Receiving a RopModifyRecipients ROP Request] 3. The changes made to the recipients (2) MUST NOT be included in the response buffer returned for ROP requests that apply to recipients (2) on different Message object handles.");
            #endregion

            #region Call RopOpenMessage to open the message for the fourth time
            uint openedMessageHandle4 = this.OpenSpecificMessage(logonResponse.FolderIds[4], saveChangesMessageResponse.MessageId, this.insideObjHandle, MessageOpenModeFlags.ReadWrite, out openMessageResponse);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopRemoveAllRecipients to remove all recipients of the newly created message in step 2, and expected to get the successful response.
            RopRemoveAllRecipientsRequest removeAllRecipientsRequest = new RopRemoveAllRecipientsRequest()
            {
                RopId = (byte)RopId.RopRemoveAllRecipients,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with RopRemoveAllRecipients.
                InputHandleIndex = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. 
                Reserved = 0x00000000
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(removeAllRecipientsRequest, openedMessageHandle3, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopRemoveAllRecipientsResponse removeAllRecipientsResponse = (RopRemoveAllRecipientsResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, removeAllRecipientsResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Use the message handle 4 to call RopReadRecipients to get all recipients of the message created in step 2.
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(readRecipientsRequest, openedMessageHandle4, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopReadRecipientsResponse readRecipientsResponse3 = (RopReadRecipientsResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, readRecipientsResponse3.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopSaveChangesMessage to save the message
            saveChangesMessageResponse = this.SaveMessage(openedMessageHandle3, (byte)SaveFlags.ForceSave);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveChangesMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopOpenMessage to open the message for the fifth time
            uint openedMessageHandle5 = this.OpenSpecificMessage(logonResponse.FolderIds[4], saveChangesMessageResponse.MessageId, this.insideObjHandle, MessageOpenModeFlags.ReadWrite, out openMessageResponse);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Use the message handle 5 to call RopReadRecipients to get all recipients of the message created in step 2.
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(readRecipientsRequest, openedMessageHandle5, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopReadRecipientsResponse readRecipientsResponse4 = (RopReadRecipientsResponse)this.response;
            Site.Assert.AreNotEqual<uint>(TestSuiteBase.Success, readRecipientsResponse4.ReturnValue, "Can't find any recipients of the message.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R382. readRecipientsResponse3.ReturnValue is {0}, readRecipientsResponse3.ReturnValue is {1}.", readRecipientsResponse3.ReturnValue, readRecipientsResponse4.ReturnValue);
        
            // Verify MS-OXCMSG requirement: MS-OXCMSG_R382
            bool isVerifiedR382 = readRecipientsResponse3.ReturnValue == 0x00000000 && readRecipientsResponse4.ReturnValue != 0x00000000;
            
            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR382,
                382,
                @"[In Receiving a RopRemoveAllRecipients ROP Request] [Until the server receives a RopSaveChangesMessage ROP request ([MS-OXCROPS] section 2.2.6.3) from the client, the server adheres to the following:] The changes made to the recipients (2) MUST NOT be included in the response buffer returned for ROP requests that apply to recipients (2) on different Message object handles.");
            #endregion

            #region Call RopRelease to release the created message.
            this.ReleaseRop(targetMessageHandle);
            #endregion
        }
        public void MSOXCMSG_S07_TC01_RopModifyRemoveRecipientSuccessfully()
        {
            this.CheckMapiHttpIsSupported();
            this.ConnectToServer(ConnectionType.PrivateMailboxServer);

            #region Call RopLogon to log on a mailbox.
            RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle);
            #endregion

            #region Call RopCreateMessage to create a message
            uint targetMessageHandle = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle);
            #endregion

            #region Call RopSaveChangesMessage to save the message
            RopSaveChangesMessageResponse saveChangesMessageResponse;
            saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveChangesMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopOpenMessage to open the message.
            RopOpenMessageResponse openMessageResponse;
            uint openedMessageHandle = this.OpenSpecificMessage(logonResponse.FolderIds[4], saveChangesMessageResponse.MessageId, this.insideObjHandle, MessageOpenModeFlags.ReadWrite, out openMessageResponse);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopRemoveAllRecipients to remove all recipients of the newly created message in step 2, and expected to get a successful response.
            RopRemoveAllRecipientsRequest removeAllRecipientsRequest = new RopRemoveAllRecipientsRequest()
            {
                RopId = (byte)RopId.RopRemoveAllRecipients,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with RopRemoveAllRecipients.
                InputHandleIndex = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. 
                Reserved = 0x00000000
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(removeAllRecipientsRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopRemoveAllRecipientsResponse removeAllRecipientsResponse = (RopRemoveAllRecipientsResponse)this.response;

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1491
            this.Site.CaptureRequirementIfAreEqual<uint>(
                TestSuiteBase.Success,
                removeAllRecipientsResponse.ReturnValue,
                1491,
                @"[In Receiving a RopRemoveAllRecipients ROP Request] The call to the RopRemoveAllRecipients ROP succeeds even if the Message object on which it is executed has no recipients (2).");
            #endregion

            #region Call RopModifyRecipients to modify the recipient and expect a successful response.
            PropertyTag[] propertyTag = null;
            ModifyRecipientRow[] modifyRecipientRow = null;
            this.CreateRecipientColumnsAndRecipientRows(out propertyTag, out modifyRecipientRow);

            RopModifyRecipientsRequest modifyRecipientsRequest = new RopModifyRecipientsRequest()
            {
                RopId = (byte)RopId.RopModifyRecipients,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with RopModifyRecipients.
                InputHandleIndex = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. In example, the value is 0x08
                ColumnCount = Convert.ToUInt16(propertyTag.Length),
                RowCount = Convert.ToUInt16(modifyRecipientRow.Length),
                RecipientColumns = propertyTag,
                RecipientRows = modifyRecipientRow
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(modifyRecipientsRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopModifyRecipientsResponse modifyRecipientsResponse = (RopModifyRecipientsResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, modifyRecipientsResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopSaveChangesMessage to save the changes of the message.
            saveChangesMessageResponse = this.SaveMessage(openedMessageHandle, (byte)SaveFlags.ForceSave);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveChangesMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopOpenMessage to open the message.
            openedMessageHandle = this.OpenSpecificMessage(logonResponse.FolderIds[4], saveChangesMessageResponse.MessageId, this.insideObjHandle, MessageOpenModeFlags.ReadWrite, out openMessageResponse);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopRemoveAllRecipients to remove all recipients.
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(removeAllRecipientsRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            removeAllRecipientsResponse = (RopRemoveAllRecipientsResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, removeAllRecipientsResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopGetPropertiesSpecific to get property PidTagRowid.

            // Prepare property Tag 
            PropertyTag[] tagArray = this.GetModifiedProperties();

            RopGetPropertiesSpecificRequest getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest()
            {
                RopId = (byte)RopId.RopGetPropertiesSpecific,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with RopGetPropertiesSpecific.
                InputHandleIndex = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. 
                PropertySizeLimit = 0xFFFF, // This value specifies the maximum number of the property
                PropertyTagCount = (ushort)tagArray.Length,
                PropertyTags = tagArray,
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getPropertiesSpecificRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse = (RopGetPropertiesSpecificResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, getPropertiesSpecificResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);

            List<PropertyObj> ps = PropertyHelper.GetPropertyObjFromBuffer(tagArray, getPropertiesSpecificResponse);

            // Parse getPropertiesSpecificResponse to get the value of properties which are modified when calling RopModifyRecipients to verify MS-OXCMSG_R381.
            PropertyObj pidTagRowid = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagRowid);
            PropertyObj pidTagDisplayType = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagDisplayType);
            PropertyObj pidTagAddressBookDisplayNamePrintable = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagAddressBookDisplayNamePrintable);
            PropertyObj pidTagSmtpAddress = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagSmtpAddress);
            PropertyObj pidTagSendInternetEncoding = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagSendInternetEncoding);
            PropertyObj pidTagDisplayTypeEx = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagDisplayTypeEx);
            PropertyObj pidTagRecipientDisplayName = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagRecipientDisplayName);
            PropertyObj pidTagRecipientFlags = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagRecipientFlags);
            PropertyObj pidTagRecipientTrackStatus = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagRecipientTrackStatus);
            PropertyObj pidTagRecipientResourceState = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagRecipientResourceState);
            PropertyObj pidTagRecipientOrder = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagRecipientOrder);
            PropertyObj pidTagRecipientEntryId = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagRecipientEntryId);

            // Add the debug information
            this.Site.Log.Add(
                LogEntryKind.Debug,
                "Verify MS-OXCMSG_R381. pidTagRowid = {0}, pidTagDisplayType = {1}, pidTagAddressBookDisplayNamePrintable = {2}, pidTagSmtpAddress = {3}, pidTagSendInternetEncoding = {4}, pidTagDisplayTypeEx = {5}, pidTagRecipientDisplayName = {6}, pidTagRecipientFlags = {7}, pidTagRecipientTrackStatus {8}, pidTagRecipientResourceState = {9}, pidTagRecipientOrder = {10}, pidTagRecipientEntryId = {11}",
                pidTagRowid,
                pidTagDisplayType,
                pidTagAddressBookDisplayNamePrintable,
                pidTagSmtpAddress,
                pidTagSendInternetEncoding,
                pidTagDisplayTypeEx,
                pidTagRecipientDisplayName,
                pidTagRecipientFlags,
                pidTagRecipientTrackStatus,
                pidTagRecipientResourceState,
                pidTagRecipientOrder,
                pidTagRecipientEntryId);

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R381
            bool isVerifiedR381 = (pidTagRowid == null || BitConverter.ToUInt32((byte[])pidTagRowid.Value, 0) == 0x8004010F)
                && (pidTagDisplayType == null || BitConverter.ToUInt32((byte[])pidTagDisplayType.Value, 0) == 0x8004010F)
                && (pidTagAddressBookDisplayNamePrintable == null || BitConverter.ToUInt32((byte[])pidTagAddressBookDisplayNamePrintable.Value, 0) == 0x8004010F)
                && (pidTagSmtpAddress == null || BitConverter.ToUInt32((byte[])pidTagSmtpAddress.Value, 0) == 0x8004010F)
                && (pidTagSendInternetEncoding == null || BitConverter.ToUInt32((byte[])pidTagSendInternetEncoding.Value, 0) == 0x8004010F)
                && (pidTagDisplayTypeEx == null || BitConverter.ToUInt32((byte[])pidTagDisplayTypeEx.Value, 0) == 0x8004010F)
                && (pidTagRecipientDisplayName == null || BitConverter.ToUInt32((byte[])pidTagRecipientDisplayName.Value, 0) == 0x8004010F)
                && (pidTagRecipientFlags == null || BitConverter.ToUInt32((byte[])pidTagRecipientFlags.Value, 0) == 0x8004010F)
                && (pidTagRecipientTrackStatus == null || BitConverter.ToUInt32((byte[])pidTagRecipientTrackStatus.Value, 0) == 0x8004010F)
                && (pidTagRecipientResourceState == null || BitConverter.ToUInt32((byte[])pidTagRecipientResourceState.Value, 0) == 0x8004010F)
                && (pidTagRecipientOrder == null || BitConverter.ToUInt32((byte[])pidTagRecipientOrder.Value, 0) == 0x8004010F)
                && (pidTagRecipientEntryId == null || BitConverter.ToUInt32((byte[])pidTagRecipientEntryId.Value, 0) == 0x8004010F);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR381,
                381,
                @"[In Receiving a RopRemoveAllRecipients ROP Request] Until the server receives a RopSaveChangesMessage ROP request ([MS-OXCROPS] section 2.2.6.3) from the client, the server adheres to the following: The PidTagRowid property (section 2.2.1.38) and associated data of removed recipients (2) MUST NOT be returned as part of any subsequent handling of ROPs for the opened Message object on the same Message object handle.");
            #endregion

            #region Call RopRelease to release the created message.
            this.ReleaseRop(targetMessageHandle);
            #endregion
        }
        public void MSOXCMSG_S07_TC03_ErrorCodesOfReadModifyRemoveAllRecipients()
        {
            this.CheckMapiHttpIsSupported();
            this.ConnectToServer(ConnectionType.PrivateMailboxServer);

            #region Call RopLogon to log on a mailbox.
            RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle);
            #endregion

            #region Call RopCreateMessage to create a message
            uint targetMessageHandle = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle);
            #endregion

            #region Call RopModifyRecipient to modify the recipient and expect error code 0x000004B9 is returned.
            // Initialize TestUser1 
            PropertyTag[] propertyTag = this.CreateRecipientColumns();
            List<ModifyRecipientRow> modifyRecipientRow = new List<ModifyRecipientRow>
            {
                this.CreateModifyRecipientRow(TestUser1, 0)
            };

            RopModifyRecipientsResponse modifyRecipientsResponse;

            RopModifyRecipientsRequest modifyRecipientsRequest = new RopModifyRecipientsRequest
            {
                RopId = (byte)RopId.RopModifyRecipients,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                ColumnCount = Convert.ToUInt16(propertyTag.Length),
                RowCount = Convert.ToUInt16(modifyRecipientRow.Count),
                RecipientColumns = propertyTag,
                RecipientRows = modifyRecipientRow.ToArray()
            };

            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(modifyRecipientsRequest, TestSuiteBase.InvalidInputHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            modifyRecipientsResponse = (RopModifyRecipientsResponse)this.response;

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1982");
        
            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1982
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0x000004B9,
                modifyRecipientsResponse.ReturnValue,
                1982,
                @"[In Receiving a RopModifyRecipients ROP Request] [ecNullObject (0x000004B9)] The value of the InputHandleIndex field on which this ROP was called does not refer to a Message object.");
            #endregion

            #region Call RopModifyRecipient to modify the recipient.
            // Initialize TestUser1 
            modifyRecipientRow.Add(this.CreateModifyRecipientRow(TestSuiteBase.TestUser1, 0));
            this.AddRecipients(modifyRecipientRow, targetMessageHandle, propertyTag, out modifyRecipientsResponse);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, modifyRecipientsResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopSaveChangesMessage to save the message
            RopSaveChangesMessageResponse saveChangesMessageResponse;
            saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveChangesMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopOpenMessage to open the message.
            RopOpenMessageResponse openMessageResponse;
            uint openedMessageHandle = this.OpenSpecificMessage(logonResponse.FolderIds[4], saveChangesMessageResponse.MessageId, this.insideObjHandle, MessageOpenModeFlags.ReadWrite, out openMessageResponse);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopReadRecipients with InputHandleIndex set to 0x01 (which does not refer to a Message object) to read the recipient of the created message and expect the error code 0x000004B9 (ecNullObject) is returned.
            RopReadRecipientsRequest readRecipientsRequest = new RopReadRecipientsRequest()
            {
                RopId = (byte)RopId.RopReadRecipients,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with RopReadRecipients.
                InputHandleIndex = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. 
                RowId = 0x00000000, // Starting index for the recipients to be retrieved
                Reserved = 0x0000 // Reserved value set to 0x0000 as indicated in MS-OXCMSG. 
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(readRecipientsRequest, TestSuiteBase.InvalidInputHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopReadRecipientsResponse readRecipientsResponse = (RopReadRecipientsResponse)this.response;

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1057");
        
            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1057
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0x000004B9,
                readRecipientsResponse.ReturnValue,
                1057,
                @"[In Receiving a RopReadRecipients ROP Request] [ecNullObject (0x000004B9)] The InputHandleIndex on which this ROP [RopReadRecipients] was called does not refer to a Message object.");
            #endregion

            #region Call RopModifyRecipients and set ModifyRecipientRow.RecipientRowSize to 0x0000 and set RowId to an existing value.
            List<ModifyRecipientRow> modifyRecipientRowNew = new List<ModifyRecipientRow>
            {
                this.ChangeRecipientRowSize(TestUser1, 0, RecipientType.PrimaryRecipient, 0x0000)
            };

            this.AddRecipients(modifyRecipientRowNew, targetMessageHandle, propertyTag, out modifyRecipientsResponse);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, modifyRecipientsResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopReadRecipients to read the recipient of the opened message.
            readRecipientsRequest.InputHandleIndex = 0x00; // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. 
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(readRecipientsRequest, targetMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            readRecipientsResponse = (RopReadRecipientsResponse)this.response;
            Site.Assert.AreNotEqual<uint>(TestSuiteBase.Success, readRecipientsResponse.ReturnValue, "Can't find any recipient of the message");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R393");
        
            // Verify MS-OXCMSG requirement: MS-OXCMSG_R393
            // The RowId field and associated data are not returned as part of subsequent handling of ROPs for the opened Message handle if RecipientRows is null, and then MS-OXCMSG_R393 can be verified.
            this.Site.CaptureRequirementIfIsNull(
                readRecipientsResponse.RecipientRows,
                393,
                @"[In Receiving a RopModifyRecipients ROP Request] 1. If a recipient (2) was deleted, its RowId field and associated data MUST NOT be returned as part of any subsequent handling of ROPs for the opened Message object.");
            #endregion

            #region Call RopSaveChangesMessage to save the message
            saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveChangesMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopOpenMessage to open the message
            RopOpenMessageResponse openMessageResponseNew;
            openedMessageHandle = this.OpenSpecificMessage(logonResponse.FolderIds[4], saveChangesMessageResponse.MessageId, this.insideObjHandle, MessageOpenModeFlags.ReadWrite, out openMessageResponseNew);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponseNew.ReturnValue, TestSuiteBase.ROPSucceedMsg);

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R391. The recipient number after adding one recipient is {0}, the recipient number after adding recipient with RecipientRowSize set to 0x0000 is {1}.", openMessageResponse.RowCount, openMessageResponseNew.RowCount);

            // MS-OXCMSG_R391 can be verified if the recipient number after adding one recipient is 1 and the recipient number after adding recipient with RecipientRowSize set to 0x0000 is 0.
            // Verify MS-OXCMSG requirement: MS-OXCMSG_R391
            bool isVerifiedR391 = openMessageResponse.RowCount == 1 && openMessageResponseNew.RowCount == 0;
            
            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR391,
                391,
                @"[In Receiving a RopModifyRecipients ROP Request] If the value of the RecipientRowSize field in the ModifyRecipientRow structure within the RecipientRows field of the request buffer is 0x0000 then the server deletes the recipient (2) from the Message object.");
            #endregion

            #region Call RopRemoveAllRecipients with InputHandleIndex set to a nonexisting one and expect error code 0x000004B9 is returned.
            RopRemoveAllRecipientsRequest removeAllRecipientsRequest = new RopRemoveAllRecipientsRequest()
            {
                RopId = (byte)RopId.RopRemoveAllRecipients,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with RopRemoveAllRecipients.
                InputHandleIndex = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. 
                Reserved = 0x00000000
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(removeAllRecipientsRequest, TestSuiteBase.InvalidInputHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopRemoveAllRecipientsResponse removeAllRecipientsResponse = (RopRemoveAllRecipientsResponse)this.response;

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1493");
        
            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1493
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0x000004B9,
                removeAllRecipientsResponse.ReturnValue,
                1493,
                @"[In Receiving a RopRemoveAllRecipients ROP Request] [ecNullObject (0x000004B9)] The value of the InputHandleIndex field on which this ROP [RopRemoveAllRecipients] was called does not refer to a Message object.");
            #endregion

            #region Call RopModifyRecipient to modify the recipient.
            // Initialize TestUser1 TestUser2 TestUser5 TestUser4 TestUser3
            modifyRecipientRow.Add(this.CreateModifyRecipientRow(TestSuiteBase.TestUser1, 0, RecipientType.PrimaryRecipient));
            modifyRecipientRow.Add(this.CreateModifyRecipientRow(TestUser2, 1, RecipientType.CcRecipient));
            modifyRecipientRow.Add(this.CreateModifyRecipientRow(TestUser5, 2, RecipientType.BccRecipient));
            modifyRecipientRow.Add(this.CreateModifyRecipientRow(TestUser4, 3));
            modifyRecipientRow.Add(this.CreateModifyRecipientRow(TestUser3, 4));

            this.AddRecipients(modifyRecipientRow, openedMessageHandle, propertyTag, out modifyRecipientsResponse);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, modifyRecipientsResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopRemoveAllRecipients to remove all recipients of the opened message
            removeAllRecipientsRequest.InputHandleIndex = 0x0; // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. 
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(removeAllRecipientsRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            removeAllRecipientsResponse = (RopRemoveAllRecipientsResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, removeAllRecipientsResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopReadRecipients to read the recipient of the opened message.
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(readRecipientsRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            readRecipientsResponse = (RopReadRecipientsResponse)this.response;
            Site.Assert.AreNotEqual<uint>(TestSuiteBase.Success, readRecipientsResponse.ReturnValue, "Can't find any recipient of the message");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R729");
        
            // Verify MS-OXCMSG requirement: MS-OXCMSG_R729
            // All recipients added above have been removed if RecipientRows is null, and then MS-OXCMSG_R729 can be verified.
            this.Site.CaptureRequirementIfIsNull(
                readRecipientsResponse.RecipientRows,
                729,
                @"[In RopRemoveAllRecipients ROP] The client sends the RopRemoveAllRecipients ROP request ([MS-OXCROPS] section 2.2.6.4) to delete all recipients (2) from a message.");
            #endregion

            #region Call RopRelease to release the created message.
            this.ReleaseRop(targetMessageHandle);
            #endregion
        }