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
        }
        public void MSOXCMSG_S08_TC05_RopDeleteAttachmentSuccessfully()
        {
            this.CheckMapiHttpIsSupported();
            this.ConnectToServer(ConnectionType.PrivateMailboxServer);

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

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

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

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

            #region Call RopGetPropertiesSpecific to get the PidTagHasAttachments and pidTagMessageFlags properties of the opened message.
            PropertyTag[] tagArray = this.MessageProperties();
            RopGetPropertiesSpecificRequest getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest()
            {
                RopId = (byte)RopId.RopGetPropertiesSpecific,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                PropertySizeLimit = 0xFFFF,
                PropertyTagCount = (ushort)tagArray.Length,
                PropertyTags = tagArray
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getPropertiesSpecificRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse = (RopGetPropertiesSpecificResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, getPropertiesSpecificResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);

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

            // Parse property response to get Property Value to verify test case requirement
            PropertyObj pidTagHasAttachmentsFirst = PropertyHelper.GetPropertyByName(ptsFirst, PropertyNames.PidTagHasAttachments);
            PropertyObj pidTagMessageFlagsFirst = PropertyHelper.GetPropertyByName(ptsFirst, PropertyNames.PidTagMessageFlags);
            bool isHasAttachmentFirst = (Convert.ToInt32(pidTagMessageFlagsFirst.Value) & 0x00000010) == 0x00000010;
            Site.Assert.IsFalse(isHasAttachmentFirst, "The message should not contains any attachment.");
            #endregion

            #region Call RopCreateAttachment to create an attachment.
            RopCreateAttachmentResponse createAttachmentResponse;
            uint attachmentId;
            uint attachmentHandle = this.CreateAttachment(openedMessageHandle, out createAttachmentResponse, out attachmentId);
            #endregion

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

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

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

            #region Call RopOpenAttachment to open the attachment as read/write.
            RopOpenAttachmentResponse openAttachmentResponse;
            this.OpenAttachment(openedMessageHandle, out openAttachmentResponse, attachmentId, OpenAttachmentFlags.ReadWrite);
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openAttachmentResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopGetPropertiesSpecific to get the PidTagHasAttachments and pidTagMessageFlags properties of the message.
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getPropertiesSpecificRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            getPropertiesSpecificResponse = (RopGetPropertiesSpecificResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, getPropertiesSpecificResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);

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

            // Parse property response to get Property Value to verify test case requirement
            PropertyObj pidTagHasAttachmentsSecond = PropertyHelper.GetPropertyByName(ptsSecond, PropertyNames.PidTagHasAttachments);
            PropertyObj pidTagMessageFlagsSecond = PropertyHelper.GetPropertyByName(ptsSecond, PropertyNames.PidTagMessageFlags);
            bool isHasAttachmentSecond = (Convert.ToInt32(pidTagMessageFlagsSecond.Value) & 0x00000010) == 0x00000010;

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R16
            this.Site.CaptureRequirementIfAreEqual<bool>(
                isHasAttachmentSecond,
                Convert.ToBoolean(pidTagHasAttachmentsSecond.Value),
                16,
                @"[In PidTagHasAttachments Property] The server computes this property [PidTagHasAttachments] from the mfHasAttach flag of the PidTagMessageFlags property ([MS-OXPROPS] section 2.780).");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R498. The value of PidTagHasAttachments before creating the attachment is {0}, the value of PidTagHasAttachments after creating the attachment is {1}.", pidTagHasAttachmentsFirst.Value, pidTagHasAttachmentsSecond.Value);

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R498
            // MS-OXCMSG_R498 can be verified if the value of PidTagHasAttachments before creating the attachment is false and the value of PidTagHasAttachments after creating the attachment is true.
            bool isVerifiedR498 = !Convert.ToBoolean(pidTagHasAttachmentsFirst.Value) && Convert.ToBoolean(pidTagHasAttachmentsSecond.Value);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR498,
                498,
                @"[In PidTagHasAttachments Property] The PidTagHasAttachments property ([MS-OXPROPS] section 2.706) indicates whether the Message object contains at least one attachment.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R875. The value of PidTagHasAttachments before creating the attachment is {0}, the value of PidTagHasAttachments after creating the attachment is {1}.", pidTagHasAttachmentsFirst.Value, pidTagHasAttachmentsSecond.Value);

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R875
            // The value of PidTagHasAttachments before creating the attachment is false and the value of PidTagHasAttachments after creating the attachment is true indicate that RopSaveChangesAttachment commits the changes made to the attachment object.
            bool isVerifiedR875 = !Convert.ToBoolean(pidTagHasAttachmentsFirst.Value) && Convert.ToBoolean(pidTagHasAttachmentsSecond.Value);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR875,
                875,
                @"[In RopSaveChangesAttachment ROP] The RopSaveChangesAttachment ROP ([MS-OXCROPS] section 2.2.6.15) commits the changes made to the Attachment object.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R522. The value of isHasAttachmentSecond is {0}.", isHasAttachmentSecond);

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R522
            // One attachment is created in the previous step, so MS-OXCMSG_R522 can be verified if the value of isHasAttachmentSecond is true.
            this.Site.CaptureRequirementIfIsTrue(
                isHasAttachmentSecond,
                522,
                @"[In PidTagMessageFlags Property] [mfHasAttach (0x00000010)] The message has at least one attachment.");
            #endregion

            #region Call RopDeleteAttachment to delete the attachment and expect a successful response.
            RopDeleteAttachmentRequest deleteAttachmentRequest = new RopDeleteAttachmentRequest()
            {
                RopId = (byte)RopId.RopDeleteAttachment,
                LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation.
                InputHandleIndex = CommonInputHandleIndex, // This index specifies the location 0x01 in the Server Object Handle Table where the handle for the input Server Object is stored.
                AttachmentID = attachmentId
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(deleteAttachmentRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopDeleteAttachmentResponse 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.
            this.OpenAttachment(openedMessageHandle, out openAttachmentResponse, attachmentId, OpenAttachmentFlags.ReadWrite);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R868
            // The deleted attachment can't be opened indicates that RopDeleteAttachment deletes an existing Attachment object from the Message object.
            this.Site.CaptureRequirementIfAreNotEqual<uint>(
                TestSuiteBase.Success,
                openAttachmentResponse.ReturnValue,
                868,
                @"[In RopDeleteAttachment ROP] The RopDeleteAttachment ROP ([MS-OXCROPS] section 2.2.6.14) deletes an existing Attachment object from the Message object.");
            #endregion

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

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

            #region Call RopGetPropertiesSpecific to get the PidTagHasAttachments property of the opened message and expect a successful response with its value is false
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getPropertiesSpecificRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            getPropertiesSpecificResponse = (RopGetPropertiesSpecificResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, getPropertiesSpecificResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);

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

            // Parse property response to get Property Value to verify test case requirement
            PropertyObj pidTagHasAttachmentsThird = PropertyHelper.GetPropertyByName(ptsThird, PropertyNames.PidTagHasAttachments);
            PropertyObj pidTagMessageFlagsThird = PropertyHelper.GetPropertyByName(ptsThird, PropertyNames.PidTagMessageFlags);
            bool isHasAttachmentThird = (Convert.ToInt32(pidTagMessageFlagsThird.Value) & 0x00000010) == 0x00000010;
            Site.Assert.IsFalse(isHasAttachmentThird, "The message should not contains any attachment.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R469. The value of PidTagHasAttachments before calling RopDeleteAttachment is {0}, the value of PidTagHasAttachments after calling RopDeleteAttachment is {1}", pidTagHasAttachmentsSecond.Value, pidTagHasAttachmentsThird.Value);

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R469
            // The value of PidTagHasAttachments before calling RopDeleteAttachment is true and after calling RopDeleteAttachment is false indicate that server recalculates the PidTagHasAttachments property while processing the RopDeleteAttachment ROP.
            bool isVerifiedR469 = !Convert.ToBoolean(pidTagHasAttachmentsThird.Value) && Convert.ToBoolean(pidTagHasAttachmentsSecond.Value);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR469,
                469,
                @"[In Receiving a RopDeleteAttachment ROP Request] The server recalculates the PidTagHasAttachments property (section 2.2.1.2) while processing the RopDeleteAttachment ROP ([MS-OXCROPS] section 2.2.6.14).");
            #endregion

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

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

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

            #region Call RopSaveChangesMessage to save the message
            RopSaveChangesMessageResponse saveChangesMessageResponse;
            saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave);
            #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 to create an attachment.
            RopCreateAttachmentResponse createAttachmentResponse;
            uint attachmentId;
            uint attachmentHandle = this.CreateAttachment(openedMessageHandle, out createAttachmentResponse, out attachmentId);
            #endregion

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

            #region Call RopSaveChangesMessage to save the message
            saveChangesMessageResponse = this.SaveMessage(openedMessageHandle, 0x04);
            #endregion

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

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

            #region Call RopDeleteAttachment to delete the attachment and expect a successful response.
            RopDeleteAttachmentRequest deleteAttachmentRequest = new RopDeleteAttachmentRequest()
            {
                RopId = (byte)RopId.RopDeleteAttachment,
                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. 
                AttachmentID = attachmentId
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(deleteAttachmentRequest, openedMessageHandle1, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopDeleteAttachmentResponse deleteAttachmentResponse = (RopDeleteAttachmentResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, deleteAttachmentResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Use the message handle 2 to call RopGetPropertiesSpecific to get the PidTagHasAttachments property.

            // PidTagHasAttachments
            List<PropertyTag> tagArray = new List<PropertyTag>
            {
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagHasAttachments]
            };

            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse;
            getPropertiesSpecificResponse = this.GetSpecificPropertiesOfMessage(openedMessageHandle2, tagArray);

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

            // Parse property response to get Property Value to verify test case requirement
            PropertyObj pidTagHasAttachmentsFirst = PropertyHelper.GetPropertyByName(ptsFirst, PropertyNames.PidTagHasAttachments);
            #endregion

            #region Use the message handle 1 to call RopSaveChangesMessage.
            saveChangesMessageResponse = this.SaveMessage(openedMessageHandle1, 0x04);
            #endregion

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

            #region Use the message handle 3 to call RopGetPropertiesSpecific to get the PidTagHasAttachments property.
            getPropertiesSpecificResponse = this.GetSpecificPropertiesOfMessage(openedMessageHandle3, tagArray);

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

            // Parse property response to get Property Value to verify test case requirement
            PropertyObj pidTagHasAttachmentsSecond = PropertyHelper.GetPropertyByName(ptsSecond, PropertyNames.PidTagHasAttachments);

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1523. The value of PidTagHasAttachments before committing the pending changes is {0}, The value of PidTagHasAttachments after committing the pending changes is {1}.", pidTagHasAttachmentsFirst.Value, pidTagHasAttachmentsSecond.Value);

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1523
            // The value of PidTagHasAttachments before committing the pending changes is true and after committing is false indicates that the attachment is not permanently removed from the message until the client calls the RopSaveChangesMessage.
            bool isVerifiedR1523 = Convert.ToBoolean(pidTagHasAttachmentsFirst.Value) && !Convert.ToBoolean(pidTagHasAttachmentsSecond.Value);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR1523,
                1523,
                @"[In Receiving a RopDeleteAttachment ROP Request] The attachment is not permanently removed from the message until the client calls the RopSaveChangesMessage ROP ([MS-OXCROPS] section 2.2.6.3).");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1523. The value of PidTagHasAttachments before committing the pending changes is {0}, The value of PidTagHasAttachments after committing the pending changes is {1}.", pidTagHasAttachmentsFirst.Value, pidTagHasAttachmentsSecond.Value);

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1062
            // The value of PidTagHasAttachments before committing the pending changes is true and after committing is false indicates that the changes are not committed to the database until the RopSaveChangesMessage is called.
            bool isVerifiedR1062 = Convert.ToBoolean(pidTagHasAttachmentsFirst.Value) && !Convert.ToBoolean(pidTagHasAttachmentsSecond.Value);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR1062,
                1062,
                @"[In Receiving a RopSaveChangesAttachment ROP Request] Although the server commits any pending changes to the Attachment object in the context of its containing Message object, the changes MUST NOT be committed to the database until the RopSaveChangesMessage ROP ([MS-OXCROPS] section 2.2.6.3) has been executed on the handle of the Message object.");
            #endregion

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