/// <summary>
        /// This ROP creates a new attachment on a message. 
        /// </summary>
        /// <param name="handle">The handle to operate</param>
        /// <param name="createAttachmentResponse">The response of this ROP.</param>
        /// <param name="needVerify">Whether need to verify the response.</param>
        /// <returns>The index of the output handle for the response</returns>
        private uint RopCreateAttachment(uint handle, out RopCreateAttachmentResponse createAttachmentResponse, bool needVerify)
        {
            this.rawDataValue = null;
            this.responseValue = null;
            this.responseSOHsValue = null;

            RopCreateAttachmentRequest createAttachmentRequest = new RopCreateAttachmentRequest()
            {
                RopId = (byte)RopId.RopCreateAttachment,
                LogonId = LogonId,
                InputHandleIndex = (byte)HandleIndex.FirstIndex,
                OutputHandleIndex = (byte)HandleIndex.SecondIndex,
            };

            this.responseSOHsValue = this.ProcessSingleRop(createAttachmentRequest, handle, ref this.responseValue, ref this.rawDataValue, RopResponseType.SuccessResponse);
            createAttachmentResponse = (RopCreateAttachmentResponse)this.responseValue;
            if (needVerify)
            {
                this.Site.Assert.AreEqual((uint)RopResponseType.SuccessResponse, createAttachmentResponse.ReturnValue, string.Format("RopCreateAttachmentResponse Failed! Error: 0x{0:X8}", createAttachmentResponse.ReturnValue));
            }

            return this.responseSOHsValue[0][createAttachmentResponse.OutputHandleIndex];
        }
        public void MSOXCMSG_S04_TC02_BodyPropertiesOnMessageObject()
        {
            this.CheckMapiHttpIsSupported();
            this.ConnectToServer(ConnectionType.PrivateMailboxServer);
            bool isMessageReceived = false;
            List<PropertyTag> propertiesOfMessage = new List<PropertyTag>();

            List<PropertyObj> propertyValues;

            #region Call RopLogon to logon the private mailbox.
            RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle);
            #endregion

            #region Call ROPs to send a message that contains plain text body to inbox.
            // Initialize message information, and set the handle for this message.
            // Create a message in Outbox folder.
            uint messageHandle = this.CreatedMessage(logonResponse.FolderIds[5], this.insideObjHandle);

            // Add a Recipient that message send to.
            PropertyTag[] propertyTag = this.CreateRecipientColumns();
            List<ModifyRecipientRow> modifyRecipientRow = new List<ModifyRecipientRow>
            {
                this.CreateModifyRecipientRow(Common.GetConfigurationPropertyValue("AdminUserName", this.Site), 0)
            };
            this.AddRecipients(modifyRecipientRow, messageHandle, propertyTag);

            // Set the message properties.
            List<PropertyObj> propertyListForSet = new List<PropertyObj>
            {
                new PropertyObj(PropertyNames.PidTagBody, Common.GetBytesFromUnicodeString(TestDataOfPidTagBody))
            };
            string title = Common.GenerateResourceName(Site, "Mail");
            propertyListForSet.Add(new PropertyObj(PropertyNames.PidTagNormalizedSubject, Common.GetBytesFromUnicodeString(title)));
            this.SetPropertiesForMessage(messageHandle, propertyListForSet);

            RopSaveChangesMessageResponse saveMessageResp = this.SaveMessage(messageHandle, (byte)SaveFlags.KeepOpenReadWrite);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveMessageResp.ReturnValue, TestSuiteBase.ROPSucceedMsg);

            RopSubmitMessageRequest submitMessageRequest = new RopSubmitMessageRequest()
            {
                RopId = (byte)RopId.RopSubmitMessage,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                SubmitFlags = (byte)SubmitFlags.None,
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(submitMessageRequest, messageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopSubmitMessageResponse submitMessageResponse = (RopSubmitMessageResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, submitMessageResponse.ReturnValue, "Call RopSubmitMessage should success.");
            #endregion

            #region Receive the message sent by step 2.
            ulong messageId = 0;
            isMessageReceived = this.WaitEmailBeDelivered(title, logonResponse.FolderIds[4], this.insideObjHandle, out messageId);

            Site.Assert.IsTrue(isMessageReceived, "The message should be received.");
            #endregion

            #region Call RopGetPropertiesSpecific to get the specific properties of created message.
            propertiesOfMessage = new List<PropertyTag>
            {
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBody],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagNativeBody],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBodyHtml],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRtfCompressed],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRtfInSync],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagInternetCodepage],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagMessageFlags]
            };

            propertyValues = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], messageId, this.insideObjHandle, propertiesOfMessage);

            #region Verify requirements
            PropertyObj pidTagNativeBody = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagNativeBody);
            if (Common.IsRequirementEnabled(1714, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R129");

                // Verify MS-OXCMSG requirement: MS-OXCMSG_R129
                this.Site.CaptureRequirementIfAreEqual<int>(
                    0x00000001,
                    Convert.ToInt32(pidTagNativeBody.Value),
                    2059,
                    @"[In PidTagNativeBody Property] [The value 0x00000001 indicates the best available format for storing the message body is] Plain text body.");

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

                // Verify MS-OXCMSG requirement: MS-OXCMSG_R1714
                // Because PidTagNativeBody is not null then the implementation does support the PidTagNativeBody property.
                this.Site.CaptureRequirementIfIsNotNull(
                    pidTagNativeBody,
                    1714,
                    @"[In Appendix A: Product Behavior] Implementation does support the PidTagNativeBody property. (Exchange 2010 and above follow this behavior.)");
            }

            PropertyObj pidTagMessageFlags = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagMessageFlags);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R519
            this.Site.CaptureRequirementIfAreEqual<int>(
                0x00000002,
                Convert.ToInt32(pidTagMessageFlags.Value) & (int)MessageFlags.MfUnmodified,
                519,
                @"[In PidTagMessageFlags Property] [mfUnmodified (0x00000002)] The message has not been modified since it was first saved (if unsent) or it was delivered (if sent).");

            #endregion
            #endregion

            #region Call ROPs to send a message that contains HTML body to mailbox.
            // Initialize message information, and set the handle for this message.
            // Create a message in Outbox folder.
            messageHandle = this.CreatedMessage(logonResponse.FolderIds[5], this.insideObjHandle);

            // Add a Recipient that message send to.
            this.AddRecipients(modifyRecipientRow, messageHandle, propertyTag);

            // Set the message properties.
            propertyListForSet = new List<PropertyObj>();
            title = Common.GenerateResourceName(this.Site, "Mail");
            propertyListForSet.Add(new PropertyObj(PropertyNames.PidTagNormalizedSubject, Common.GetBytesFromUnicodeString(title)));
            propertyListForSet.Add(new PropertyObj(PropertyNames.PidTagBodyHtml, Common.GetBytesFromUnicodeString(TestDataOfPidTagBodyHtml)));
            propertyListForSet.Add(new PropertyObj(PropertyNames.PidTagHtml, PropertyHelper.GetBinaryFromGeneral(Encoding.ASCII.GetBytes(TestDataOfPidTagBodyHtml))));
            propertyListForSet.Add(new PropertyObj(PropertyNames.PidTagBodyContentId, Common.GetBytesFromUnicodeString(TestDataOfPidTagBodyContentId)));
            propertyListForSet.Add(new PropertyObj(PropertyNames.PidTagBodyContentLocation, Common.GetBytesFromUnicodeString(TestDataOfPidTagBodyContentLocation)));

            this.SetPropertiesForMessage(messageHandle, propertyListForSet);

            saveMessageResp = this.SaveMessage(messageHandle, (byte)SaveFlags.KeepOpenReadWrite);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveMessageResp.ReturnValue, TestSuiteBase.ROPSucceedMsg);

            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(submitMessageRequest, messageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            submitMessageResponse = (RopSubmitMessageResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, submitMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Receive the message sent by step 7.
            messageId = 0;
            isMessageReceived = this.WaitEmailBeDelivered(title, logonResponse.FolderIds[4], this.insideObjHandle, out messageId);

            Site.Assert.IsTrue(isMessageReceived, "The message should be received.");
            #endregion

            #region Call RopGetPropertiesSpecific to get the specific properties of created message.
            propertiesOfMessage = new List<PropertyTag>
            {
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagNativeBody],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRtfCompressed],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRtfInSync],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagInternetCodepage],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBodyContentId],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBodyContentLocation],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagHtml],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagMessageFlags],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBodyHtml]
            };

            propertyValues = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], messageId, this.insideObjHandle, propertiesOfMessage);

            pidTagNativeBody = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagNativeBody);
            PropertyObj pidTagHtml = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagHtml);

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

                // Verify MS-OXCMSG requirement: MS-OXCMSG_R131
                this.Site.CaptureRequirementIfAreEqual<int>(
                    0x00000003,
                    Convert.ToInt32(pidTagNativeBody.Value),
                    2061,
                    @"[In PidTagNativeBody Property] [The value 0x00000003 indicates the best available format for storing the message body is] HTML body.");
            }

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R2082
            this.Site.CaptureRequirementIfIsNotNull(
                pidTagHtml.Value,
                2082,
                @"[In PidTagHtml Property] [Type] The PidTagHtml property ([MS-OXPROPS] section 2.722) contains the message body text in HTML format.");

            PropertyObj pidTagBodyContentLocation = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagBodyContentLocation);

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R2076, the value of PidTagBodyContentLocation is {0}.", pidTagBodyContentLocation.Value.ToString());

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R2076
            bool isVerifiedR2076 = Uri.IsWellFormedUriString(pidTagBodyContentLocation.Value.ToString(), UriKind.RelativeOrAbsolute);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR2076,
                2076,
                @"[In PidTagBodyContentLocation Property] The PidTagBodyContentLocation property ([MS-OXPROPS] section 2.611) contains a globally unique URI that serves as a label for the current message body.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R2077, the value of PidTagBodyContentLocation is {0}.", pidTagBodyContentLocation.Value.ToString());

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R2077
            bool isVerifiedR2077 = Uri.IsWellFormedUriString(pidTagBodyContentLocation.Value.ToString(), UriKind.RelativeOrAbsolute);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR2077,
                2077,
                @"[In PidTagBodyContentLocation Property] The URI can be either absolute or relative.");
            #endregion

            #region Call ROPs to send a message that contains a Clear-signed body to mailbox.
            #region Call RopCreateMessage to create Message object.
            messageHandle = this.CreatedMessage(logonResponse.FolderIds[5], this.insideObjHandle);
            #endregion

            #region Call RopModifyRecipients to add recipient to message created by step2
            this.AddRecipients(modifyRecipientRow, messageHandle, propertyTag);
            #endregion

            #region Call RopSetProperties to set properties of created message.
            propertyListForSet = new List<PropertyObj>();
            title = Common.GenerateResourceName(this.Site, "Mail");
            propertyListForSet.Add(new PropertyObj(PropertyNames.PidTagNormalizedSubject, Common.GetBytesFromUnicodeString(title)));
            propertyListForSet.Add(new PropertyObj(PropertyNames.PidTagMessageClass, Common.GetBytesFromUnicodeString("IPM.Note.SMIME.MultipartSigned")));
            propertyListForSet.Add(new PropertyObj(PropertyNames.PidTagBody, Common.GetBytesFromUnicodeString(TestDataOfPidTagBody)));

            this.SetPropertiesForMessage(messageHandle, propertyListForSet);
            #endregion

            #region RopCreateAttachment success response
            RopCreateAttachmentRequest createAttachmentRequest = new RopCreateAttachmentRequest()
            {
                RopId = (byte)RopId.RopCreateAttachment,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                OutputHandleIndex = CommonOutputHandleIndex
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(createAttachmentRequest, messageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopCreateAttachmentResponse createAttachmentResponse = (RopCreateAttachmentResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, createAttachmentResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            uint attachmentHandle = this.ResponseSOHs[0][createAttachmentResponse.OutputHandleIndex];
            #endregion

            propertyListForSet = new List<PropertyObj>
            {
                new PropertyObj(PropertyNames.PidTagAttachMethod, BitConverter.GetBytes(0x00000001)),
                new PropertyObj(PropertyNames.PidTagAttachMimeTag, Common.GetBytesFromUnicodeString("multipart/signed")),
                new PropertyObj(PropertyNames.PidTagAttachFilename, Common.GetBytesFromUnicodeString("SMIME.p7m")),
                new PropertyObj(PropertyNames.PidTagAttachLongFilename, Common.GetBytesFromUnicodeString("SMIME.p7m")),
                new PropertyObj(PropertyNames.PidTagDisplayName, Common.GetBytesFromUnicodeString("SMIME.p7m"))
            };

            this.SetPropertiesForMessage(attachmentHandle, propertyListForSet);

            #region RopSaveChangesAttachment success response
            RopSaveChangesAttachmentRequest saveChangesAttachmentRequest = new RopSaveChangesAttachmentRequest()
            {
                RopId = (byte)RopId.RopSaveChangesAttachment,
                LogonId = CommonLogonId,
                ResponseHandleIndex = CommonOutputHandleIndex, // This index specifies the location in the Server object handle table that is referenced in the response.
                InputHandleIndex = CommonInputHandleIndex,
                SaveFlags = 0x0C // ForceSave
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(saveChangesAttachmentRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopSaveChangesAttachmentResponse saveChangesAttachmentResponse = (RopSaveChangesAttachmentResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveChangesAttachmentResponse.ReturnValue, "Call RopSaveChangesAttachment should success.");
            #endregion RopSaveChangesAttachment success response

            #region Call RopSaveChangesMessage to save created message.
            saveMessageResp = this.SaveMessage(messageHandle, (byte)SaveFlags.ForceSave);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveMessageResp.ReturnValue, "Call RopSaveChangesMessage should success.");
            #endregion

            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(submitMessageRequest, messageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            submitMessageResponse = (RopSubmitMessageResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, submitMessageResponse.ReturnValue, "Call RopSubmitMessage should success.");
            #endregion

            #region Receive the message sent by step 12.
            messageId = 0;
            isMessageReceived = this.WaitEmailBeDelivered(title, logonResponse.FolderIds[4], this.insideObjHandle, out messageId);

            Site.Assert.IsTrue(isMessageReceived, "The message should be received.");
            #endregion

            #region Call RopGetPropertiesSpecific to get the specific properties of created message.
            propertiesOfMessage = new List<PropertyTag>
            {
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBody],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagNativeBody],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBodyHtml],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRtfCompressed],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRtfInSync],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagInternetCodepage],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBodyContentId],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBodyContentLocation],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagHtml],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagMessageFlags]
            };

            propertyValues = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], messageId, this.insideObjHandle, propertiesOfMessage);

            pidTagNativeBody = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagNativeBody);
            #endregion

            #region Create an undefined body message in inbox folder
            messageHandle = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle);

            saveMessageResp = this.SaveMessage(messageHandle, (byte)SaveFlags.ForceSave);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveMessageResp.ReturnValue, TestSuiteBase.ROPSucceedMsg);

            #endregion

            #region Call RopGetPropertiesSpecific to get the specific properties of created message.
            propertiesOfMessage = new List<PropertyTag>
            {
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBody],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagNativeBody],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBodyHtml],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRtfCompressed],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRtfInSync],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagInternetCodepage]
            };

            propertyValues = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], saveMessageResp.MessageId, this.insideObjHandle, propertiesOfMessage);

            #region Verify requirements
            if (Common.IsRequirementEnabled(1714, this.Site))
            {
                pidTagNativeBody = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagNativeBody);

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

                // Verify MS-OXCMSG requirement: MS-OXCMSG_R128
                this.Site.CaptureRequirementIfAreEqual<int>(
                    0x00000000,
                    Convert.ToInt32(pidTagNativeBody.Value),
                    2058,
                    @"[In PidTagNativeBody Property] [The value 0x00000000 indicates the best available format for storing the message body is] Undefined body.");
            }
            #endregion
            #endregion

            #region Call RopRelease to release created message.
            this.ReleaseRop(messageHandle);
            #endregion

            #region Create a new Rich Text Format (RTF) compressed body message in inbox folder.
            messageHandle = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle);

            propertyListForSet = new List<PropertyObj>
            {
                new PropertyObj(PropertyNames.PidTagRtfCompressed, PropertyHelper.GetBinaryFromGeneral(this.rtfCompressedText))
            };
            this.SetPropertiesForMessage(messageHandle, propertyListForSet);

            saveMessageResp = this.SaveMessage(messageHandle, (byte)SaveFlags.ForceSave);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveMessageResp.ReturnValue, "Call RopSaveChangesMessage should success.");
            #endregion

            #region Call RopGetPropertiesSpecific to get the specific properties of created message.
            propertiesOfMessage = new List<PropertyTag>
            {
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBody],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagNativeBody],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagBodyHtml],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRtfCompressed],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRtfInSync],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagInternetCodepage],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagObjectType],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRecordKey]
            };

            propertyValues = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], saveMessageResp.MessageId, this.insideObjHandle, propertiesOfMessage);

            #region Verify requirements
            if (Common.IsRequirementEnabled(1714, this.Site))
            {
                pidTagNativeBody = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagNativeBody);

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

                // Verify MS-OXCMSG requirement: MS-OXCMSG_R130
                this.Site.CaptureRequirementIfAreEqual<int>(
                    0x00000002,
                    Convert.ToInt32(pidTagNativeBody.Value),
                    2060,
                    @"[In PidTagNativeBody Property] [The value 0x00000002 indicates the best available format for storing the message body is] RTF compressed body.");
            }

            PropertyObj pidTagRtfInSync = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagRtfInSync);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R138
            this.Site.CaptureRequirementIfIsTrue(
                Convert.ToBoolean(pidTagRtfInSync.Value),
                2068,
                @"[In PidTagRtfInSync Property] The PidTagRtfInSync property ([MS-OXPROPS] section 2.931) is set to ""TRUE"" (0x01) if the RTF body has been synchronized with the contents in the PidTagBody property (section 2.2.1.56.1).");
            #endregion
            #endregion

            #region Call RopRelease to release created message.
            this.ReleaseRop(messageHandle);
            #endregion
        }
        public void MSOXCMSG_S08_TC10_ErrorCodeRelatedWithAttachmentROPs()
        {
            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);
            #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 RopCreateAttachment with InputHandleIndex set to 0x01 and expect a failure response.
            RopCreateAttachmentRequest createAttachmentRequest = new RopCreateAttachmentRequest()
            {
                RopId = (byte)RopId.RopCreateAttachment,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation.
                InputHandleIndex = 0x01, // Set InputHandleIndex to 0x01 which doesn't refer to a Message object.
                OutputHandleIndex = CommonOutputHandleIndex // This index specifies the location 0x01 in the Server Object Handle Table where the handle for the output Server Object is stored. 
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(createAttachmentRequest, targetMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopCreateAttachmentResponse createAttachmentResponse = (RopCreateAttachmentResponse)this.response;

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1712
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0x000004B9,
                createAttachmentResponse.ReturnValue,
                1712,
                @"[In Receiving a RopCreateAttachment ROP Request] [ecNullObject (0x000004B9)] The value of the InputHandleIndex field on which this ROP [RopCreateAttachment] was called does not refer to a Message object.");
            #endregion

            #region Call RopCreateAttachment to create an attachment and expect a successful response.
            uint attachmentId;
            uint attachmentHandle = this.CreateAttachment(openedMessageHandle, out createAttachmentResponse, out attachmentId);
            #endregion

            #region Call RopSaveChangesAttachment and set the attachmentID to the message ID and expect a failure response.
            RopSaveChangesAttachmentRequest saveChangesAttachmentRequest = new RopSaveChangesAttachmentRequest()
            {
                RopId = (byte)RopId.RopSaveChangesAttachment,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation.
                ResponseHandleIndex = CommonOutputHandleIndex, // This index specifies the location in the Server object handle table that is referenced in the response.
                InputHandleIndex = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. 
                SaveFlags = (byte)SaveFlags.ForceSave
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(saveChangesAttachmentRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopSaveChangesAttachmentResponse saveChangesAttachmentResponse = (RopSaveChangesAttachmentResponse)this.response;
            Site.Assert.AreNotEqual<uint>(TestSuiteBase.Success, saveChangesAttachmentResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R467
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0x80040102,
                saveChangesAttachmentResponse.ReturnValue,
                467,
                @"[In Receiving a RopSaveChangesAttachment ROP Request] [ecNotSupported (0x80040102)] The value of the InputHandleIndex field on which this ROP [RopSaveChangesAttachment] was called does not refer to an Attachment object.");
            #endregion

            #region Call RopSaveChangesAttachment and set SaveFlags to 0x03 which doesn't specified in the Open Specification and expect a failure response.
            saveChangesAttachmentRequest.SaveFlags = 0x03; // Set SaveFlags to 0x03 which doesn't specified in the Open Specification
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(saveChangesAttachmentRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            saveChangesAttachmentResponse = (RopSaveChangesAttachmentResponse)this.response;
            Site.Assert.AreNotEqual<uint>(TestSuiteBase.Success, saveChangesAttachmentResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R466
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0x80040102,
                saveChangesAttachmentResponse.ReturnValue,
                466,
                @"[In Receiving a RopSaveChangesAttachment ROP Request] [ecNotSupported (0x80040102)] The value of the SaveFlags field is not a supported combination as specified in section 2.2.3.3.1.");
            #endregion

            #region Call RopSaveChangesAttachment to save the newly created attachment.
            this.SaveAttachment(attachmentHandle, out saveChangesAttachmentResponse);
            #endregion

            #region Call RopOpenAttachment with InputHandleIndex set to 0x01 which doesn't refer to a message object and expect a failure response
            RopOpenAttachmentRequest openAttachmentRequest = new RopOpenAttachmentRequest()
            {
                RopId = (byte)RopId.RopOpenAttachment,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation.
                InputHandleIndex = 0x01, // Set InputHandleIndex to 0x01 which doesn't refer to a Message object.
                OutputHandleIndex = CommonOutputHandleIndex, // This index specifies the location 0x01 in the Server Object Handle Table where the handle for the output Server Object is stored. 
                OpenAttachmentFlags = 0x01,
                AttachmentID = attachmentId
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openAttachmentRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopOpenAttachmentResponse openAttachmentResponseFirst = (RopOpenAttachmentResponse)this.response;
            Site.Assert.AreNotEqual<uint>(TestSuiteBase.Success, openAttachmentResponseFirst.ReturnValue, "The InputHandleIndex is wrong.");

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1620
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0x000004B9,
                openAttachmentResponseFirst.ReturnValue,
                1620,
                @"[In Receiving a RopOpenAttachment ROP Request] [ecNullObject (0x000004B9)] The value of the InputHandleIndex field on which this ROP [RopOpenAttachment] was called does not refer to a Message object.");
            #endregion

            #region Call RopRelease to release attachment.
            this.ReleaseRop(attachmentHandle);
            #endregion

            #region Call RopGetAttachmentTable with InputHandleIndex set to 0x01 and expect a failure response
            RopGetAttachmentTableRequest getAttachmentTableRequest = new RopGetAttachmentTableRequest()
            {
                RopId = (byte)RopId.RopGetAttachmentTable,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation.
                InputHandleIndex = 0x01, // Set InputHandleIndex to 0x01 which doesn't refer to a Message object
                OutputHandleIndex = CommonOutputHandleIndex, // This index specifies the location 0x01 in the Server Object Handle Table where the handle for the output Server Object is stored. 
                TableFlags = 0x00 // Open the table 
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getAttachmentTableRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopGetAttachmentTableResponse getAttachmentTableResponse = (RopGetAttachmentTableResponse)this.response;

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1526
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0x000004B9,
                getAttachmentTableResponse.ReturnValue,
                1526,
                @"[In Receiving a RopGetAttachmentTable ROP Request] [ecNullObject (0x000004B9)] The value of the InputHandleIndex field on which this ROP [RopGetAttachmentTable] was called does not refer to a Message object.");
            #endregion

            #region Call RopDeleteAttachment and set InputHandleIndex to 0x01 and expect a failure response.
            RopDeleteAttachmentRequest deleteAttachmentRequest = new RopDeleteAttachmentRequest()
            {
                RopId = (byte)RopId.RopDeleteAttachment,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation.
                InputHandleIndex = CommonInputHandleIndex, // Set InputHandleIndex to 0x00 which doesn't refer to a Message object.
                AttachmentID = attachmentId
            };

            // Set InputHandleIndex to 0x00 which doesn't refer to a Message object.
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(deleteAttachmentRequest, TestSuiteBase.InvalidInputHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopDeleteAttachmentResponse deleteAttachmentResponse = (RopDeleteAttachmentResponse)this.response;

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1524
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0x000004B9,
                deleteAttachmentResponse.ReturnValue,
                1524,
                @"[In Receiving a RopDeleteAttachment ROP Request] [ecNullObject (0x000004B9)] The value of the InputHandleIndex field on which this ROP [RopDeleteAttachment] was called does not refer to a Message object.");
            #endregion

            #region Call RopDeleteAttachment and set AttachmentID to a nonexisting one and expect a failure response.
            deleteAttachmentRequest.InputHandleIndex = 0x00;
            deleteAttachmentRequest.AttachmentID = attachmentId + 5;
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(deleteAttachmentRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            deleteAttachmentResponse = (RopDeleteAttachmentResponse)this.response;

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1063
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0x8004010F,
                deleteAttachmentResponse.ReturnValue,
                1063,
                @"[In Receiving a RopDeleteAttachment ROP Request] [ecNotFound (0x8004010F)] The value of the AttachmentID field does not correspond to an attachment on the Message object.");
            #endregion

            #region Call RopDeleteAttachment to delete the attachment and expect a successful response.
            deleteAttachmentRequest.AttachmentID = attachmentId;
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(deleteAttachmentRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            deleteAttachmentResponse = (RopDeleteAttachmentResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, deleteAttachmentResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopOpenAttachment to open the deleted attachment and expect a failure response.
            RopOpenAttachmentResponse openAttachmentResponse;
            this.OpenAttachment(openedMessageHandle, out openAttachmentResponse, attachmentId, OpenAttachmentFlags.ReadWrite);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R440
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0x8004010F,
                openAttachmentResponse.ReturnValue,
                440,
                @"[In Receiving a RopOpenAttachment ROP Request] [ecNotFound (0x8004010F)] The value of the AttachmentID field does not correspond to an attachment on the Message object.");
            #endregion

            #region Call RopRelease to release the created message and attachment.
            this.ReleaseRop(attachmentHandle);
            this.ReleaseRop(targetMessageHandle);
            #endregion
        }
        /// <summary>
        /// Create an attachment of the given message.
        /// </summary>
        /// <param name="objectHandle">A Server object handle.</param>
        /// <param name="createAttachmentResponse">The RopCreateAttachmentResponse value.</param>
        /// <param name="attachmentId">The created attachment ID.</param>
        /// <returns>A Server object handle of the created attachment.</returns>
        protected uint CreateAttachment(uint objectHandle, out RopCreateAttachmentResponse createAttachmentResponse, out uint attachmentId)
        {
            RopCreateAttachmentRequest createAttachmentRequest = new RopCreateAttachmentRequest()
            {
                RopId = (byte)RopId.RopCreateAttachment,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                OutputHandleIndex = CommonOutputHandleIndex
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(createAttachmentRequest, objectHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            createAttachmentResponse = (RopCreateAttachmentResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, createAttachmentResponse.ReturnValue, "Call RopCreateAttachment should success.");
            attachmentId = createAttachmentResponse.AttachmentID;

            return this.ResponseSOHs[0][createAttachmentResponse.OutputHandleIndex];
        }