public void MSOXCMSG_S08_TC02_RopGetAttachmentSuccessfully()
        {
            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 RopCreateAttachment to create the attachment1 of the message
            RopCreateAttachmentResponse createAttachmentResponse;
            uint attachmentId1;
            uint attachmentHandle = this.CreateAttachment(openedMessageHandle, out createAttachmentResponse, out attachmentId1);
            #endregion

            #region Call SetPropertiesSpecific to set PidTagDisplayName property.
            List<PropertyObj> propertyList = new List<PropertyObj>
            {
                new PropertyObj(PropertyNames.PidTagDisplayName, Common.GetBytesFromUnicodeString("First attachment"))
            };

            this.SetPropertiesForMessage(attachmentHandle, propertyList);
            #endregion

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

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

            #region Call RopCreateAttachment to create the attachment2 of the message
            uint attachmentId2;
            attachmentHandle = this.CreateAttachment(openedMessageHandle, out createAttachmentResponse, out attachmentId2);
            #endregion

            #region Call SetPropertiesSpecific to set PidTagDisplayName property.
            propertyList = new List<PropertyObj>
            {
                new PropertyObj(PropertyNames.PidTagDisplayName, Common.GetBytesFromUnicodeString("Second attachment"))
            };

            this.SetPropertiesForMessage(attachmentHandle, propertyList);
            #endregion

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

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

            bool isVerifiedR1836 = !(attachmentId1 == attachmentId2);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1836
            Site.CaptureRequirementIfIsTrue(
                isVerifiedR1836,
                1836,
                @"[In PidTagAttachNumber Property] The value of property PidTagAttachNumber is different among the two Attachment objects in a message.");
            #endregion

            #region Call RopGetValidAttachments and expect a successful response
            if (Common.IsRequirementEnabled(1715, this.Site))
            {
                RopGetValidAttachmentsRequest getValidAttachmentsRequest = new RopGetValidAttachmentsRequest()
                {
                    RopId = (byte)RopId.RopGetValidAttachments,
                    LogonId = CommonLogonId,
                    InputHandleIndex = CommonInputHandleIndex
                };
                this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getValidAttachmentsRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
                RopGetValidAttachmentsResponse getValidAttachmentsResponse = (RopGetValidAttachmentsResponse)this.response;

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

                // Verify MS-OXCMSG requirement: MS-OXCMSG_R1715
                // Calling RopGetValidAttachments succeeds indicates that implementation supports the RopGetValidAttachments ROP.
                this.Site.CaptureRequirementIfAreEqual<uint>(
                    TestSuiteBase.Success,
                    getValidAttachmentsResponse.ReturnValue,
                    1715,
                    @"[In Appendix A: Product Behavior] Implementation does support the RopGetValidAttachments ROP. (Exchange 2007 follows this behavior.)");
            }
            #endregion

            #region Call RopGetAttachmentTable with TableFlags set to 0x00 and expect a successful response.
            RopGetAttachmentTableRequest getAttachmentTableRequest = new RopGetAttachmentTableRequest()
            {
                RopId = (byte)RopId.RopGetAttachmentTable,
                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. 
                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;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, getAttachmentTableResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            uint attachmentTableHandle = this.ResponseSOHs[0][getAttachmentTableResponse.OutputHandleIndex];

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R890
            // Calling RopGetAttachmentTable succeeds and the handle of the attachment table is not null indicate that RopGetAttachmentTable ROP retrieves a handle to a Table object.
            this.Site.CaptureRequirementIfIsNotNull(
                attachmentTableHandle,
                890,
                @"[In RopGetAttachmentTable ROP] The RopGetAttachmentTable ROP ([MS-OXCROPS] section 2.2.6.17) retrieves a handle to a Table object that represents the attachments stored on the Message object.");

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R905
            this.Site.CaptureRequirementIfAreEqual<uint>(
                TestSuiteBase.Success,
                getAttachmentTableResponse.ReturnValue,
                905,
                @"[In RopGetAttachmentTable ROP Request Buffer] [TableFlags] [Standard (0x00)] Open the table.");
            #endregion

            #region Call RopGetAttachmentTable with TableFlags set to 0x40 and expect a successful response
            getAttachmentTableRequest.TableFlags = 0x40; // Open the table 
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getAttachmentTableRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            getAttachmentTableResponse = (RopGetAttachmentTableResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, getAttachmentTableResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            attachmentTableHandle = this.ResponseSOHs[0][getAttachmentTableResponse.OutputHandleIndex];
            #endregion

            #region Call RopSetColumns to set the display name of the attachment table and expect a successful response
            PropertyTag[] propertyTags = new PropertyTag[2];
            propertyTags[0] = PropertyHelper.PropertyTagDic[PropertyNames.PidTagDisplayName];
            propertyTags[1] = PropertyHelper.PropertyTagDic[PropertyNames.PidTagAttachNumber];

            this.SetColumnsSuccess(propertyTags, attachmentTableHandle);

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R906
            this.Site.CaptureRequirementIfAreEqual<uint>(
                TestSuiteBase.Success,
                getAttachmentTableResponse.ReturnValue,
                906,
                @"[In RopGetAttachmentTable ROP Request Buffer] [TableFlags] [Unicode (0x40)] Open the table.");
            #endregion

            #region Call RopQueryColumnsAll to get all the string type properties in the attachment table and expect all the string type properties are returned in Unicode format
            RopQueryColumnsAllRequest queryColumnsAllRequest = new RopQueryColumnsAllRequest()
            {
                RopId = (byte)RopId.RopQueryColumnsAll,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(queryColumnsAllRequest, attachmentTableHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopQueryColumnsAllResponse queryColumnsAllResponse = (RopQueryColumnsAllResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, queryColumnsAllResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopQueryRows to query all rows.
            RopQueryRowsResponse queryRowsResponse = this.QueryRowsSuccess(attachmentTableHandle);

            bool isVerifiedR907 = false;

            for (int i = 0; i < queryRowsResponse.RowCount; i++)
            {
                byte[] rowData = queryRowsResponse.RowData.PropertyRows[i].PropertyValues[0].Value;
                if (Common.IsUtf16LEString(rowData))
                {
                    isVerifiedR907 = true;
                }
                else
                {
                    isVerifiedR907 = false;
                    break;
                }
            }

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R907
            // Property type ptypString indicates that the string data is in Unicode format, and then MS-OXCMSG_R907 can be verified.     
            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR907,
                907,
                @"[In RopGetAttachmentTable ROP Request Buffer] [TableFlags] [Unicode (0x40)] Also requests that the columns containing string data be returned in Unicode format.");

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

            bool isExitsFirstAttach = false;
            bool isExitsSecondAttach = false;

            Site.Assert.AreEqual<int>(2, queryRowsResponse.RowCount, "The message should include 2 attachments.");

            for (int i = 0; i < queryRowsResponse.RowCount; i++)
            {
                int attachmentID = BitConverter.ToInt32(queryRowsResponse.RowData.PropertyRows[i].PropertyValues[1].Value, 0);

                if (attachmentID == attachmentId1)
                {
                    isExitsFirstAttach = true;
                }

                if (attachmentID == attachmentId2)
                {
                    isExitsSecondAttach = true;
                }
            }

            bool isVerifiedR312 = isExitsFirstAttach && isExitsSecondAttach;

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R312
            // Because according to above step, the message include 2 attachments.
            // When a client calls the RopGetAttachmentTable ROP, the server returns a table of properties for each Attachment object associated with the Message object.
            // If the table from server only includes 2 rows and the PidTagAttachNumber property columns include all attachment ids of attachment associated with Message object.
            // R312 will be verified.
            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR312,
                312,
                @"[In Sending a RopGetAttachmentTable ROP Request] When a client calls the RopGetAttachmentTable ROP ([MS-OXCROPS] section 2.2.6.17), the server returns a table of properties for each Attachment object associated with the Message object, as specified in [MS-OXCTABL].");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R490");
            bool isVerifiedR490 = isVerifiedR312;

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R490
            // Because the PidTagAttachNumber can be obtained from the table return from server when call RopGetAttachmentTable ROP.
            // So R490 will be verified.
            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR490,
                490,
                @"[In Receiving a RopGetAttachmentTable ROP Request] The Table object returned by the RopGetAttachmentTable ROP ([MS-OXCROPS] section 2.2.6.17) allows access to the properties of Attachment objects.");
            #endregion

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