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_S03_TC06_RopSetReadFlagsFailure()
        {
            this.CheckMapiHttpIsSupported();
            this.ConnectToServer(ConnectionType.PrivateMailboxServer);

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

            #region Call RopOpenFolder to open inbox folder.
            uint folderHandle = this.OpenSpecificFolder(logonResponse.FolderIds[4], this.insideObjHandle);
            #endregion

            #region Call RopCreateMessage to create a new Message object in inbox folder.
            uint targetMessageHandle = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle);
            #endregion

            #region Call RopModifyRecipients to add recipient to message created by step2
            PropertyTag[] propertyTag = this.CreateRecipientColumns();
            List<ModifyRecipientRow> modifyRecipientRow = new List<ModifyRecipientRow>
            {
                this.CreateModifyRecipientRow(Common.GetConfigurationPropertyValue("AdminUserName", this.Site), 0)
            };
            this.AddRecipients(modifyRecipientRow, targetMessageHandle, propertyTag);
            #endregion

            #region Call RopSaveChangesMessage to save the Message object created by step 2.
            RopSaveChangesMessageResponse saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveChangesMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            ulong[] messageIds = new ulong[1];
            messageIds[0] = saveChangesMessageResponse.MessageId;
            #endregion

            #region Call RopGetContentsTable to get the contents table of inbox folder before submit message.
            RopGetContentsTableResponse getContentsTableResponse = this.GetContentTableSuccess(folderHandle);
            uint contentTableHandle = this.ResponseSOHs[0][getContentsTableResponse.OutputHandleIndex];
            uint rowCountBeforeSubmit = getContentsTableResponse.RowCount;
            this.ReleaseRop(contentTableHandle);
            #endregion

            #region Call RopSubmitMessage to submit message
            RopSubmitMessageRequest submitMessageRequest = new RopSubmitMessageRequest()
            {
                RopId = (byte)RopId.RopSubmitMessage,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                SubmitFlags = (byte)SubmitFlags.None
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(submitMessageRequest, targetMessageHandle, 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.");

            List<PropertyTag> propertyTags = new List<PropertyTag>
            {
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagMessageFlags]
            };
            List<PropertyObj> ps = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], messageIds[0], this.insideObjHandle, propertyTags);
            PropertyObj pidTagMessageFlagsSet = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagMessageFlags);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R520
            this.Site.CaptureRequirementIfAreEqual<int>(
                0x00000004,
                Convert.ToInt32(pidTagMessageFlagsSet.Value) & (int)MessageFlags.MfSubmitted,
                520,
                @"[In PidTagMessageFlags Property] [mfSubmitted (0x00000004)] The message is marked for sending as a result of a call to the RopSubmitMessage ROP.");
            #endregion

            #region Call RopSetReadFlags which contains an incorrect InputHandleIndex.
            // RopSetReadFlags
            RopSetReadFlagsRequest setReadFlagsRequet = new RopSetReadFlagsRequest()
            {
                RopId = (byte)RopId.RopSetReadFlags,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation.
                InputHandleIndex = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. 
                WantAsynchronous = 0x00, // Does not asynchronous 
                ReadFlags = 0x00, // rfClearNotifyUnread
                MessageIds = messageIds,
                MessageIdCount = Convert.ToUInt16(messageIds.Length)
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(setReadFlagsRequet, TestSuiteBase.InvalidInputHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopSetReadFlagsResponse setReadFlagesResponse = (RopSetReadFlagsResponse)this.response;

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

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

            #region Receive the message sent by step 7.
            bool isMessageReceived = WaitEmailBeDelivered(folderHandle, rowCountBeforeSubmit);
            Site.Assert.IsTrue(isMessageReceived, "The message should be received.");
            #endregion
        }
        public void MSOXCMSG_S04_TC01_GeneralPropertiesOnMessageObject()
        {
            this.CheckMapiHttpIsSupported();
            this.ConnectToServer(ConnectionType.PrivateMailboxServer);

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

            #region Call RopOpenFolder to open inbox folder.
            uint folderHandle = this.OpenSpecificFolder(logonResponse.FolderIds[4], this.insideObjHandle);
            #endregion

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

            #region Call RopModifyRecipients to add recipient to message created by step2
            PropertyTag[] recipientColumns = this.CreateRecipientColumns();
            List<ModifyRecipientRow> modifyRecipientRow = new List<ModifyRecipientRow>
            {
                this.CreateModifyRecipientRow(Common.GetConfigurationPropertyValue("AdminUserName", this.Site), 0)
            };
            this.AddRecipients(modifyRecipientRow, targetMessageHandle, recipientColumns);
            #endregion

            #region Call RopGetPropertiesSpecific to get PidTagMessageFlags property for created message before save message.
            // Prepare property Tag 
            PropertyTag[] tagArray = new PropertyTag[1];
            tagArray[0] = PropertyHelper.PropertyTagDic[PropertyNames.PidTagMessageFlags];

            // Get properties for Created Message
            RopGetPropertiesSpecificRequest getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest()
            {
                RopId = (byte)RopId.RopGetPropertiesSpecific,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation.
                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, targetMessageHandle, 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);

            PropertyObj pidTagMessageFlags = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagMessageFlags);
            #endregion

            #region Call RopSetProperties to set PidTagMessageFlags property of created message.
            List<PropertyObj> propertyList = this.SetGeneralPropertiesOfMessage();
            int messageFlags = Convert.ToInt32(pidTagMessageFlags.Value) | (int)MessageFlags.MfResend;
            propertyList.Add(new PropertyObj(PropertyNames.PidTagMessageFlags, BitConverter.GetBytes(messageFlags)));
            this.SetPropertiesForMessage(targetMessageHandle, propertyList);
            #endregion

            #region Call RopSaveChangesMessage to save created message.
            RopSaveChangesMessageResponse saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave);

            // The message ID of specific message created by above step.
            ulong messageId = saveChangesMessageResponse.MessageId;
            #endregion

            #region Call RopGetContentsTable to get the contents table of inbox folder before submit message.
            RopGetContentsTableResponse getContentsTableResponse = this.GetContentTableSuccess(folderHandle);
            uint contentTableHandle = this.ResponseSOHs[0][getContentsTableResponse.OutputHandleIndex];
            uint rowCountBeforeSubmit = getContentsTableResponse.RowCount;
            this.ReleaseRop(contentTableHandle);
            #endregion

            #region Call RopSubmitMessage to submit message
            RopSubmitMessageRequest submitMessageRequest = new RopSubmitMessageRequest()
            {
                RopId = (byte)RopId.RopSubmitMessage,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                SubmitFlags = (byte)SubmitFlags.None
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(submitMessageRequest, targetMessageHandle, 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 Call RopOpenMessage to open created message.
            RopOpenMessageRequest openMessageRequest = new RopOpenMessageRequest
            {
                RopId = (byte)RopId.RopOpenMessage,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                OutputHandleIndex = CommonOutputHandleIndex,
                CodePageId = 0x0FFF,
                FolderId = logonResponse.FolderIds[4],
                OpenModeFlags = (byte)MessageOpenModeFlags.ReadOnly,
                MessageId = messageId
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openMessageRequest, this.insideObjHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopOpenMessageResponse openMessageResponse = (RopOpenMessageResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, "Call RopOpenMessage should success.");
            targetMessageHandle = this.ResponseSOHs[0][openMessageResponse.OutputHandleIndex];

            #region Verify MS-OXCMSG_R676, MS-OXCMSG_R678 and MS-OXCMSG_R1298
            string subjectPrefixInOpenResponse = System.Text.ASCIIEncoding.ASCII.GetString(openMessageResponse.SubjectPrefix.String);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R676
            this.Site.CaptureRequirementIfAreEqual<string>(
                TestDataOfPidTagSubjectPrefix,
                subjectPrefixInOpenResponse.Substring(0, subjectPrefixInOpenResponse.Length - 1),
                676,
                @"[In RopOpenMessage ROP Response Buffer] [SubjectPrefix] The SubjectPrefix field contains the value of the PidTagSubjectPrefix property (section 2.2.1.9).");

            string normalizedSubjectInOpenResponse = System.Text.ASCIIEncoding.ASCII.GetString(openMessageResponse.NormalizedSubject.String);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R678
            this.Site.CaptureRequirementIfAreEqual<string>(
                TestSuiteBase.TestDataOfPidTagNormalizedSubject,
                normalizedSubjectInOpenResponse.Substring(0, normalizedSubjectInOpenResponse.Length - 1),
                678,
                @"[In RopOpenMessage ROP Response Buffer] [NormalizedSubject] The NormalizedSubject field contains the value of the PidTagNormalizedSubject property (section 2.2.1.10).");

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1298
            this.Site.CaptureRequirementIfAreEqual<int>(
                0x10,
                openMessageResponse.RecipientRows[0].RecipientType,
                1298,
                @"[In RopOpenMessage ROP Response Buffer] [RecipientRows] The value 0x10 means when resending a previous failure, this flag indicates that this recipient (1) did not successfully receive the message on the previous attempt.");

            #endregion
            #endregion

            #region Call RopGetPropertiesAll to get all properties of created message.
            RopGetPropertiesAllRequest getPropertiesAllRequest = new RopGetPropertiesAllRequest()
            {
                RopId = (byte)RopId.RopGetPropertiesAll,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,

                // Set PropertySizeLimit,which specifies the maximum size allowed for a property value returned,
                // as specified in [MS-OXCROPS] section 2.2.8.4.1.
                PropertySizeLimit = 0xFFFF,
                WantUnicode = 1,
            };

            // In process, call capture code to verify adapter requirement
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getPropertiesAllRequest, targetMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.MessageProperties);
            RopGetPropertiesAllResponse getPropertiesAllResponse = (RopGetPropertiesAllResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, getPropertiesAllResponse.ReturnValue, "Call RopGetPropertiesAll should success.");
            List<PropertyObj> propertyValues = PropertyHelper.GetPropertyObjFromBuffer(getPropertiesAllResponse);

            PropertyObj pidTagImportance = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagImportance);
            PropertyObj pidTagPriority = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagPriority);
            PropertyObj pidTagSensitivity = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagSensitivity);
            PropertyObj pidTagTrustSender = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagTrustSender);
            PropertyObj pidTagSubject = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagSubject);
            PropertyObj pidTagSubjectPrefix = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagSubjectPrefix);
            PropertyObj pidTagNormalizedSubject = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagNormalizedSubject);

            #region Verify requirements
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1668 ,the property count is {0}.", getPropertiesAllResponse.PropertyValueCount);

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1668
            bool isVerifiedR1668 = getPropertiesAllResponse.PropertyValueCount > 0;

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR1668,
                1668,
                @"[In RopOpenMessage ROP Response Buffer] [HasNamedProperties] Nonzero: Named properties are defined for this Message object and can be obtained through a RopGetPropertiesAll ROP request ([MS-OXCROPS] section 2.2.8.4).");

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R72
            this.Site.CaptureRequirementIfAreEqual<int>(
                0x00000000,
                Convert.ToInt32(pidTagImportance.Value),
                72,
                @"[In PidTagImportance Property] [The value 0x00000000 indicates the level of importance assigned by the end user to the Message object is] Low importance.");

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R80
            this.Site.CaptureRequirementIfAreEqual<int>(
                -1,
                Convert.ToInt32(pidTagPriority.Value),
                80,
                @"[In PidTagPriority Property] [The value 0xFFFFFFFF indicates  the client's request for the priority is] Not urgent.");

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R86
            this.Site.CaptureRequirementIfAreEqual<int>(
                0x00000001,
                Convert.ToInt32(pidTagSensitivity.Value),
                86,
                @"[In PidTagSensitivity Property] [The value 0x00000001 indicates the sender's assessment of the sensitivity of the Message object is] Personal.");

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

                // Verify MS-OXCMSG requirement: MS-OXCMSG_R1236
                this.Site.CaptureRequirementIfAreEqual<int>(
                    0x00000001,
                    (int)pidTagTrustSender.Value,
                    1236,
                    @"[In PidTagTrustSender] The value 0x00000001 indicates that the message was delivered through a trusted transport channel.");

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

                // Verify MS-OXCMSG requirement: MS-OXCMSG_R1713
                this.Site.CaptureRequirementIfIsNotNull(
                    pidTagTrustSender.Value,
                    1713,
                    @"[In Appendix A: Product Behavior] Implementation does support the PidTagTrustSender property. (Exchange 2007 follows this behavior.)");
            }

            PropertyObj pidTagPurportedSenderDomain = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagPurportedSenderDomain);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1214
            this.Site.CaptureRequirementIfAreEqual<string>(
                Common.GetConfigurationPropertyValue("Domain", this.Site),
                pidTagPurportedSenderDomain.Value.ToString(),
                1214,
                @"[In PidTagPurportedSenderDomain Property] The PidTagPurportedSenderDomain property ([MS-OXPROPS] section 2.865) contains the domain name of the last sender responsible for transmitting the current message.");

            PropertyObj pidTagAlternateRecipientAllowed = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagAlternateRecipientAllowed);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1797
            this.Site.CaptureRequirementIfIsTrue(
                Convert.ToBoolean(pidTagAlternateRecipientAllowed.Value),
                1797,
                @"[In PidTagAlternateRecipientAllowed Property] This property [PidTagAlternateRecipientAllowed] is set to ""TRUE"" if autoforwarding is allowed.");

            PropertyObj pidTagResponsibility = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagResponsibility);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1198
            this.Site.CaptureRequirementIfIsTrue(
                Convert.ToBoolean(pidTagResponsibility.Value),
                1198,
                @"[In PidTagResponsibility Property] This property [PidTagResponsibility] is set to ""TRUE"" if another agent has accepted responsibility.");

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

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R515
            this.Site.CaptureRequirementIfAreEqual<int>(
                0x00000080,
                Convert.ToInt32(pidTagMessageFlags.Value) & 0x00000080,
                515,
                @"[In PidTagMessageFlags Property] [mfResend (0x00000080)] The message includes a request for a resend operation with a non-delivery report.");
            #endregion
            #endregion

            #region Call RopGetPropertiesSpecific to get the specific properties of created message.
            List<PropertyTag> propertiesOfMessage = this.GetPropertyTagListOfMessageObject();
            propertyValues = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], messageId, this.insideObjHandle, propertiesOfMessage);

            // Parse property response get Property Value to verify test  case requirement
            pidTagImportance = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagImportance);
            pidTagSubjectPrefix = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagSubjectPrefix);
            pidTagNormalizedSubject = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagNormalizedSubject);
            pidTagSubject = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagSubject);
            PropertyObj pidTagRecipientDisplayName = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagRecipientDisplayName);

            #region Verify requirements
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R58");

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R58
            this.Site.CaptureRequirementIfAreEqual<string>(
                TestDataOfPidTagSubjectPrefix,
                pidTagSubjectPrefix.Value.ToString(),
                58,
                @"[In PidTagSubjectPrefix Property] The PidTagSubjectPrefix property ([MS-OXPROPS] section 2.1096) contains the prefix for the subject of the message.");

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R64
            this.Site.CaptureRequirementIfAreEqual<string>(
                TestSuiteBase.TestDataOfPidTagNormalizedSubject,
                pidTagNormalizedSubject.Value.ToString(),
                64,
                @"[In PidTagNormalizedSubject Property] The PidTagNormalizedSubject property ([MS-OXPROPS] section 2.877) contains the normalized subject of the message, as specified in [MS-OXCMAIL] section 2.2.3.2.6.1.");

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

            string mailSubject = TestDataOfPidTagSubjectPrefix + TestDataOfPidTagNormalizedSubject;

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1238
            this.Site.CaptureRequirementIfAreEqual<string>(
                mailSubject,
                pidTagSubject.Value.ToString(),
                1238,
                @"[In PidTagSubject Property] The PidTagSubject property ([MS-OXPROPS] section 2.1021) contains the full subject of an e-mail message.");

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1239
            this.Site.CaptureRequirementIfAreEqual<string>(
                mailSubject,
                pidTagSubject.Value.ToString(),
                1239,
                @"[In PidTagSubject Property] The full subject is a concatenation of the subject prefix, as identified by the PidTagSubjectPrefix property (section 2.2.1.9), and the normalized subject, as identified by the PidTagNormalizedSubject property (section 2.2.1.10).");

            PropertyObj pidTagAutoForwarded = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagAutoForwarded);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1108
            this.Site.CaptureRequirementIfAreEqual<byte>(
                0x00,
                Convert.ToByte(pidTagAutoForwarded.Value),
                1108,
                @"[In PidTagAutoForwarded Property] If this property [PidTagAutoForwarded] is unset, a default value of 0x00 is assumed.");
            
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R2047");
        
            // Verify MS-OXCMSG requirement: MS-OXCMSG_R2047
            this.Site.CaptureRequirementIfAreEqual<string>(
                Common.GetConfigurationPropertyValue("AdminUserName", this.Site),
                pidTagRecipientDisplayName.Value.ToString(),
                2047,
                @"[In PidTagRecipientDisplayName Property] The PidTagRecipientDisplayName property ([MS-OXPROPS] section 2.888) specifies the display name of a recipient (2).");
            #endregion
            #endregion

            #region Receive the message sent by step 9.
            bool isMessageReceived = WaitEmailBeDelivered(folderHandle, rowCountBeforeSubmit);
            Site.Assert.IsTrue(isMessageReceived, "The message should be received.");
            #endregion

            #region Call RopRelease to release all resources.
            this.ReleaseRop(targetMessageHandle);
            this.ReleaseRop(folderHandle);
            #endregion
        }
        public void MSOXCMSG_S03_TC01_RopSetReadFlags()
        {
            this.CheckMapiHttpIsSupported();
            this.ConnectToServer(ConnectionType.PrivateMailboxServer);

            List<PropertyTag> propertyTags = new List<PropertyTag>
            {
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagMessageFlags],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagChangeKey],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagLastModificationTime],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagCreatorEntryId],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRead],
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagRecipientDisplayName]
            };

            List<PropertyObj> ps = new List<PropertyObj>();

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

            #region Call RopCreateMessage to create a new Message object in inbox folder.
            uint targetMessageHandle = this.CreatedMessage(logonResponse.FolderIds[5], this.insideObjHandle);
            #endregion

            #region Call RopModifyRecipients to add recipient to message created by step2
            PropertyTag[] propertyTag = this.CreateRecipientColumns();
            List<ModifyRecipientRow> modifyRecipientRow = new List<ModifyRecipientRow>
            {
                this.CreateModifyRecipientRow(Common.GetConfigurationPropertyValue("AdminUserName", this.Site), 0)
            };
            this.AddRecipients(modifyRecipientRow, targetMessageHandle, propertyTag);
            #endregion

            #region Call RopSetProperties to set the properties of message created by step 2.
            PropertyTag[] tagArray = propertyTags.ToArray();

            // Get properties for Created Message
            RopGetPropertiesSpecificRequest getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest()
            {
                RopId = (byte)RopId.RopGetPropertiesSpecific,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                PropertySizeLimit = 0xFFFF, // This value specifies the maximum number of the property
                PropertyTagCount = (ushort)tagArray.Length,
                PropertyTags = tagArray
            };

            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getPropertiesSpecificRequest, targetMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse = (RopGetPropertiesSpecificResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, getPropertiesSpecificResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);

            ps = PropertyHelper.GetPropertyObjFromBuffer(tagArray, getPropertiesSpecificResponse);
            
            List<PropertyObj> propertyList = new List<PropertyObj>();
            string title = Common.GenerateResourceName(Site, "Mail");
            propertyList.Add(new PropertyObj(PropertyNames.PidTagNormalizedSubject, Common.GetBytesFromUnicodeString(title)));

            // Set PidTagReadReceiptRequested property.
            propertyList.Add(new PropertyObj(0x0029, (ushort)PropertyType.PtypBoolean, new byte[] { 0x01 }));

            // Set PidTagNonReceiptNotificationRequested property.
            propertyList.Add(new PropertyObj(0x0C06, (ushort)PropertyType.PtypBoolean, new byte[] { 0x01 }));

            // Set PidTagReadReceiptAddressType property.
            propertyList.Add(new PropertyObj(0x4029, (ushort)PropertyType.PtypString, Common.GetBytesFromUnicodeString("EX")));

            // Set PidTagReadReceiptEmailAddress property.
            string userName = Common.GetConfigurationPropertyValue("AdminUserName", this.Site);
            string domain = Common.GetConfigurationPropertyValue("Domain", this.Site);
            string mailAddress = string.Format("{0}@{1}", userName, domain);

            propertyList.Add(new PropertyObj(0x402A, (ushort)PropertyType.PtypString, Common.GetBytesFromUnicodeString(mailAddress)));

            this.SetPropertiesForMessage(targetMessageHandle, propertyList);
            #endregion

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

            #region Call RopSubmitMessage to submit message
            RopSubmitMessageRequest submitMessageRequest = new RopSubmitMessageRequest()
            {
                RopId = (byte)RopId.RopSubmitMessage,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                SubmitFlags = (byte)SubmitFlags.None
            };

            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(submitMessageRequest, targetMessageHandle, 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;
            bool isMessageReceived = this.WaitEmailBeDelivered(title, logonResponse.FolderIds[4], this.insideObjHandle, out messageId);

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

            #region Verify requirements
            ulong[] messageIds = new ulong[1];
            messageIds[0] = messageId;

            ps = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], messageId, this.insideObjHandle, propertyTags);
            PropertyObj pidTagMessageFlagsSetBefore = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagMessageFlags);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R529
            this.Site.CaptureRequirementIfAreEqual<int>(
                0x00000100,
                Convert.ToInt32(pidTagMessageFlagsSetBefore.Value) & (int)MessageFlags.MfNotifyRead,
                529,
                @"[In PidTagMessageFlags Property] [mfNotifyRead (0x00000100)] The user who sent the message has requested notification when a recipient (1) first reads it.");

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R531
            this.Site.CaptureRequirementIfAreEqual<int>(
                0x00000200,
                Convert.ToInt32(pidTagMessageFlagsSetBefore.Value) & (int)MessageFlags.MfNotifyUnread,
                531,
                @"[In PidTagMessageFlags Property] [mfNotifyUnread (0x00000200)] The user who sent the message has requested notification when a recipient (1) deletes it before reading or the Message object expires.");
            #endregion

            #region Call RopOpenFolder to open inbox folder.
            uint folderHandle = this.OpenSpecificFolder(logonResponse.FolderIds[4], this.insideObjHandle);
            #endregion

            #region Call RopSetReadFlags to change the state of the PidTagMessageFlags property to rfDefault on Message object within inbox Folder.
            RopSetReadFlagsRequest setReadFlagsRequet = new RopSetReadFlagsRequest()
            {
                RopId = (byte)RopId.RopSetReadFlags,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation.
                InputHandleIndex = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. 
                WantAsynchronous = 0x00, // Does not asynchronous 
                MessageIds = messageIds,
                MessageIdCount = Convert.ToUInt16(messageIds.Length),
                ReadFlags = (byte)ReadFlags.Default
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(setReadFlagsRequet, folderHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopSetReadFlagsResponse setReadFlagesResponse = (RopSetReadFlagsResponse)this.response;

            ps = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], messageIds[0], this.insideObjHandle, propertyTags);
            PropertyObj pidTagMessageFlagsSetDefault = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagMessageFlags);
            PropertyObj pidTagChangeKeyBeforeSet = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagChangeKey);
            PropertyObj pidTagLastModificationTimeBeforeSet = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagLastModificationTime);
            PropertyObj pidTagRead = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagRead);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R815
            this.Site.CaptureRequirementIfAreEqual<int>(
                (int)MessageFlags.MfRead,
                Convert.ToInt32(pidTagMessageFlagsSetDefault.Value) & (int)MessageFlags.MfRead,
                815,
                @"[In RopSetReadFlags ROP Request Buffer] [ReadFlags] [rfDefault (0x00)] The server sets the read flag and sends the receipt.");

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R2045
            this.Site.CaptureRequirementIfIsTrue(
                Convert.ToBoolean(pidTagRead.Value),
                2045,
                @"[In PidTagRead Property] The PidTagRead property ([MS-OXPROPS] section 2.867) indicates whether a message has been read.");    
            #endregion

            #region Call RopSetReadFlags to change the state of the PidTagMessageFlags property to rfClearReadFlag on Message object within inbox Folder.
            setReadFlagsRequet.ReadFlags = (byte)ReadFlags.ClearReadFlag;
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(setReadFlagsRequet, folderHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            setReadFlagesResponse = (RopSetReadFlagsResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, setReadFlagesResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);

            ps = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], messageIds[0], this.insideObjHandle, propertyTags);
            PropertyObj pidTagMessageFlagsSetClearReadFlag = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagMessageFlags);
            PropertyObj pidTagChangeKeyAfterSet = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagChangeKey);
            PropertyObj pidTagLastModificationTimeAfterSet = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagLastModificationTime);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R822
            this.Site.CaptureRequirementIfAreNotEqual<int>(
                (int)MessageFlags.MfRead,
                Convert.ToInt32(pidTagMessageFlagsSetClearReadFlag.Value) & (int)MessageFlags.MfRead,
                822,
                @"[In RopSetReadFlags ROP Request Buffer] [ReadFlags] [rfClearReadFlag (0x04)] Server clears the mfRead bit.");

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R795
            this.Site.CaptureRequirementIfAreNotEqual<int>(
                Convert.ToInt32(pidTagMessageFlagsSetDefault.Value),
                Convert.ToInt32(pidTagMessageFlagsSetClearReadFlag.Value),
                795,
                @"[In RopSetReadFlags ROP] The RopSetReadFlags ROP ([MS-OXCROPS] section 2.2.6.10) changes the state of the PidTagMessageFlags property (section 2.2.1.6) on one or more Message objects within a Folder object.");

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1145
            this.Site.CaptureRequirementIfAreNotEqual<int>(
                Convert.ToInt32(pidTagMessageFlagsSetDefault.Value),
                Convert.ToInt32(pidTagMessageFlagsSetClearReadFlag.Value),
                1145,
                @"[In PidTagMessageFlags Property] The pidTagMessageFlages property is modified using the RopSetReadFlags ROP ([MS-OXCROPS] section 2.2.6.10), as described in section 2.2.3.10.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1703, the PidTagMessageFlags value is {0}.", pidTagMessageFlagsSetClearReadFlag.Value);

            bool isSameChangekey = Common.CompareByteArray((byte[])pidTagChangeKeyBeforeSet.Value, (byte[])pidTagChangeKeyAfterSet.Value);
            Site.Assert.IsTrue(isSameChangekey, "The PidTagChangeKey property should not be changed.");

            Site.Assert.AreEqual<DateTime>(
                Convert.ToDateTime(pidTagLastModificationTimeBeforeSet.Value),
                Convert.ToDateTime(pidTagLastModificationTimeAfterSet.Value),
                "The PidTagLastModificationTime property should not be changed.");

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1703
            // Because above step has verified only changes the PidTagMessageFlags property, not the PidTagChangeKey property and PidTagLastModificationTime property.
            // R1703 will be direct verified.
            this.Site.CaptureRequirement(
               1703,
               @"[In Receiving a RopSetReadFlags ROP Request] The server immediately commits the changes to the Message objects as if the Message objects had been opened and the RopSaveMessageChanges ROP ([MS-OXCROPS] section 2.2.6.3) had been called, except that it [server] only changes the PidTagMessageFlags property (section 2.2.1.6), not the PidTagChangeKey property ([MS-OXCFXICS] section 2.2.1.2.7), the PidTagLastModificationTime property (section 2.2.2.2), or any other property that is modified during a RopSaveChangesMessage ROP request ([MS-OXCROPS] section 2.2.6.3).");

            #endregion

            #region Call RopSetReadFlags to change the state of the PidTagMessageFlags property to rfSuppressReceipt on Message object within inbox Folder.
            setReadFlagsRequet.ReadFlags = (byte)ReadFlags.SuppressReceipt;
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(setReadFlagsRequet, folderHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            setReadFlagesResponse = (RopSetReadFlagsResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, setReadFlagesResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);

            ps = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], messageIds[0], this.insideObjHandle, propertyTags);
            PropertyObj pidTagMessageFlagsSetSuppressReceipt = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagMessageFlags);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R818
            this.Site.CaptureRequirementIfAreEqual<int>(
                (int)MessageFlags.MfRead,
                Convert.ToInt32(pidTagMessageFlagsSetSuppressReceipt.Value) & (int)MessageFlags.MfRead,
                818,
                @"[In RopSetReadFlags ROP Request Buffer] [ReadFlags] [rfSuppressReceipt (0x01)] The server sets the mfRead bit.");
            #endregion

            #region Call RopSetReadFlags to change the state of the PidTagMessageFlags property to rfGenerateReceiptOnly on Message object within inbox Folder.
            setReadFlagsRequet.ReadFlags = (byte)ReadFlags.GenerateReceiptOnly;
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(setReadFlagsRequet, folderHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            setReadFlagesResponse = (RopSetReadFlagsResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, setReadFlagesResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R825
            this.Site.CaptureRequirementIfAreEqual<uint>(
                TestSuiteBase.Success,
                setReadFlagesResponse.ReturnValue,
                825,
                @"[In RopSetReadFlags ROP Request Buffer] [ReadFlags] [rfGenerateReceiptOnly (0x10)] The server sends a read receipt if one is pending, but does not change the mfRead bit.");
            #endregion

            #region Call RopSetReadFlags to change the state of the PidTagMessageFlags property to rfClearNotifyRead on Message object within inbox Folder.
            setReadFlagsRequet.ReadFlags = (byte)ReadFlags.ClearNotifyRead; // rfClearNotifyRead
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(setReadFlagsRequet, folderHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            setReadFlagesResponse = (RopSetReadFlagsResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, setReadFlagesResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);

            ps = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], messageIds[0], this.insideObjHandle, propertyTags);
            PropertyObj pidTagMessageFlagsSetClearNotifyRead = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagMessageFlags);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R827
            this.Site.CaptureRequirementIfAreNotEqual<int>(
                (int)MessageFlags.MfNotifyRead,
                Convert.ToInt32(pidTagMessageFlagsSetClearNotifyRead.Value) & (int)MessageFlags.MfNotifyRead,
                827,
                @"[In RopSetReadFlags ROP Request Buffer] [ReadFlags] [rfClearNotifyRead (0x20)] The server clears the mfNotifyRead bit but does not send a read receipt.");
            #endregion

            #region Call RopSetReadFlags to change the state of the PidTagMessageFlags property to rfClearNotifyUnread on Message object within inbox Folder.
            setReadFlagsRequet.ReadFlags = (byte)ReadFlags.ClearNotifyUnread; // rfClearNotifyUnread
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(setReadFlagsRequet, folderHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            setReadFlagesResponse = (RopSetReadFlagsResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, setReadFlagesResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);

            ps = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], messageIds[0], this.insideObjHandle, propertyTags);
            PropertyObj pidTagMessageFlagsSetClearNotifyUnread = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagMessageFlags);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R829
            this.Site.CaptureRequirementIfAreNotEqual<int>(
                (int)MessageFlags.MfNotifyUnread,
                Convert.ToInt32(pidTagMessageFlagsSetClearNotifyUnread.Value) & (int)MessageFlags.MfNotifyUnread,
                829,
                @"[In RopSetReadFlags ROP Request Buffer] [ReadFlags] [rfClearNotifyUnread (0x40)] The server clears the mfNotifyUnread bit but does not send a nonread receipt.");
            #endregion

            #region Call RopRelease to release all resources.
            this.ReleaseRop(targetMessageHandle);
            this.ReleaseRop(folderHandle);
            #endregion
        }