/// <summary>
 /// Add Recipient to specific message.
 /// </summary>
 /// <param name="serverId">Server id.</param>
 /// <param name="messageHandle">Message handle.</param>
 private void AddRecipient(int serverId, uint messageHandle)
 {
     RopModifyRecipientsRequest modifyRecipientRequest = new RopModifyRecipientsRequest
     {
         RopId = 0x0E,
         LogonId = 0x00,
         InputHandleIndex = 0x00
     };
     PropertyTag[] tags = null;
     ModifyRecipientRow[] recipientRow = null;
     this.CreateSampleRecipientColumnsAndRecipientRows(out tags, out recipientRow);
     modifyRecipientRequest.RecipientColumns = tags;
     modifyRecipientRequest.RecipientRows = recipientRow;
     modifyRecipientRequest.RowCount = (ushort)recipientRow.Length;
     modifyRecipientRequest.ColumnCount = (ushort)tags.Length;
     this.Process(serverId, modifyRecipientRequest, messageHandle);
 }
        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
        }
        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
        }
        /// <summary>
        /// Add recipients to specific message.
        /// </summary>
        /// <param name="recipientRows">The list of ModifyRecipientRow.</param>
        /// <param name="messageHandle">The Server object handle of Message.</param>
        /// <param name="propertyTag">The properties of Recipient</param>
        /// <param name="modifyRecipientsResponse">The response of calling RopModifyRecipients.</param>
        protected void AddRecipients(List<ModifyRecipientRow> recipientRows, uint messageHandle, PropertyTag[] propertyTag, out RopModifyRecipientsResponse modifyRecipientsResponse)
        {
            RopModifyRecipientsRequest modifyRecipientsRequest = new RopModifyRecipientsRequest
            {
                RopId = (byte)RopId.RopModifyRecipients,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                ColumnCount = Convert.ToUInt16(propertyTag.Length),
                RowCount = Convert.ToUInt16(recipientRows.Count),
                RecipientColumns = propertyTag,
                RecipientRows = recipientRows.ToArray()
            };

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