/// <summary>
        /// This method is used to map concrete property IDs to abstract, client-defined named properties. 
        /// </summary>
        /// <param name="propertyIdType">Specifies different PropertyId type.</param>
        public void RopGetNamesFromPropertyIdsMethod(PropertyIdType propertyIdType)
        {
            // The property IDs needs to get in RopGetNamesFromPropertyIds ROP request.
            PropertyId[] propertyIds = new PropertyId[1];
            #region Set and save property
            if (propertyIdType == PropertyIdType.HaveAssociatedName || propertyIdType == PropertyIdType.LessThan0x8000)
            {
                TaggedPropertyValue[] tagPropertyValue = new TaggedPropertyValue[1];
                tagPropertyValue[0] = this.GetTaggedPropertyTag(ObjectToOperate.FirstObject);
                if (tagPropertyValue[0].PropertyTag.PropertyType == 0x0102)
                {
                    tagPropertyValue[0].Value = Common.AddInt16LengthBeforeBinaryArray(tagPropertyValue[0].Value);
                }

                this.RopSetProperties(this.cprptFirstHandle, tagPropertyValue, true);
                if (this.cprptCurrentType == ServerObjectType.Message)
                {
                    this.RopSaveChangesMessage(this.cprptFirstHandle, true);
                }
                else if (this.cprptCurrentType == ServerObjectType.Attachment)
                {
                    this.RopSaveChangesAttachment(this.cprptFirstHandle, true);
                }
            }
            #endregion

            RopGetNamesFromPropertyIdsResponse getNamesFromPropertyIdsResponse = this.RopGetNamesFromPropertyIds(this.cprptCurrentHandle, propertyIds);

            #region Verify response
            this.VerifyRopGetNamesFromPropertyIds((ushort)propertyIds.Length, propertyIds, getNamesFromPropertyIdsResponse, this.cprptCurrentType);

            this.Site.Assert.AreEqual((uint)CPRPTErrorCode.None, getNamesFromPropertyIdsResponse.ReturnValue, string.Format("RopGetNamesFromPropertyIds Failed! Error: 0x{0:X8}", getNamesFromPropertyIdsResponse.ReturnValue));

            #endregion
        }
        /// <summary>
        /// Get the bytes value of one property from a list of properties.
        /// </summary>
        /// <param name="propertyName">The property need to get value.</param>
        /// <param name="propertyRow">The property row.</param>
        /// <param name="propertyTags">The properties tags.</param>
        /// <returns>The bytes value of the property.</returns>
        private byte[] GetPropertyFromList(PropertyId propertyName, PropertyRow propertyRow, PropertyTag[] propertyTags)
        {
            byte[] value = new byte[0];
            TaggedPropertyValue[] allProperties = null;
            if (propertyRow != null && propertyRow.PropertyValues != null && propertyRow.PropertyValues.Count > 0)
            {
                allProperties = new TaggedPropertyValue[propertyTags.Length];
                for (int i = 0; i < propertyTags.Length; i++)
                {
                    allProperties[i] = new TaggedPropertyValue
                    {
                        PropertyTag = propertyTags[i],
                        Value = propertyRow.PropertyValues[i].Value
                    };
                }
            }

            foreach (TaggedPropertyValue taggedValue in allProperties)
            {
                if (taggedValue.PropertyTag.PropertyId == (ushort)propertyName)
                {
                    value = taggedValue.Value;
                    break;
                }
            }

            return value;
        }
        /// <summary>
        /// Check if an unexpected message with a specific property value exists in the target mailbox.
        /// </summary>
        /// <param name="folderHandle">Handle of a specific folder.</param>
        /// <param name="contentsTableHandle">Handle of a specific contents table.</param>
        /// <param name="propertyTagList">>Array of PropertyTag structures. This field specifies the property values that are visible in table rows.</param>
        /// <param name="unexpectedPropertyValue">The value of a specific property of the message to be checked in the target mailbox.</param>
        /// <param name="propertyName">The property name of a specific property of the message to be checked in the target mailbox, which type should be string. The default property name is PidTagSubject.</param>
        /// <returns>A bool value indicates whether a message with specific property value exists in the target mailbox. True means exist, otherwise not.</returns>
        protected bool CheckUnexpectedMessageExist(uint folderHandle, ref uint contentsTableHandle, PropertyTag[] propertyTagList, string unexpectedPropertyValue, PropertyId propertyName = PropertyId.PidTagSubject)
        {
            bool doesUnexpectedMessageExist = false;
            bool isExpectedPropertyInPropertyList = false;
            RopGetContentsTableResponse ropGetContentTableResponse = this.OxoruleAdapter.RopGetContentsTable(folderHandle, ContentTableFlag.None, out contentsTableHandle);
            Site.Assert.AreEqual<uint>(0, ropGetContentTableResponse.ReturnValue, "Getting contents table should succeed.");

            RopQueryRowsResponse getNormalMailMessageContent = this.OxoruleAdapter.QueryPropertiesInTable(contentsTableHandle, propertyTagList);
            Site.Assert.AreEqual<uint>(0, getNormalMailMessageContent.ReturnValue, "Getting mail message operation should succeed.");
            if (getNormalMailMessageContent.RowData.Count > 0)
            {
                for (int i = 0; i < propertyTagList.Length; i++)
                {
                    if (propertyTagList[i].PropertyId == (ushort)propertyName)
                    {
                        isExpectedPropertyInPropertyList = true;
                        for (int j = 0; j < getNormalMailMessageContent.RowData.PropertyRows.Count; j++)
                        {
                            string propertyValue = AdapterHelper.PropertyValueConvertToString(getNormalMailMessageContent.RowData.PropertyRows[j].PropertyValues[i].Value);
                            Site.Log.Add(LogEntryKind.Debug, "The value of the {0} property of the No.{1} message is : {2}", propertyName.ToString(), j + 1, propertyValue);
                            if (propertyValue.Contains(unexpectedPropertyValue))
                            {
                                doesUnexpectedMessageExist = true;
                                return doesUnexpectedMessageExist;
                            }
                        }
                    }
                }

                Site.Assert.IsTrue(isExpectedPropertyInPropertyList, "The property {0} to be checked should be included in the property list.", propertyName.ToString());
            }

            return doesUnexpectedMessageExist;
        }
        /// <summary>
        /// Get the expected message properties included in a specific contents table after retry preconfigured times.
        /// </summary>
        /// <param name="folderHandle">Handle of a specific folder.</param>
        /// <param name="contentsTableHandle">Handle of a specific contents table.</param>
        /// <param name="propertyTagList">>Array of PropertyTag structures. This field specifies the property values that are visible in table rows.</param>
        /// <param name="expectedMessageIndex">The index of the specific message in the table.</param>
        /// <param name="expectedPropertyValue">The value of a specific property of the message to be found in the target mailbox.</param>
        /// <param name="expectedPropertyName">The property name of a specific property of the message to be found in the target mailbox, which type should be string. The default property name is PidTagSubject.</param>
        /// <returns>Response of the RopQueryRow ROP contents the expected message properties.</returns>
        protected RopQueryRowsResponse GetExpectedMessage(uint folderHandle, ref uint contentsTableHandle, PropertyTag[] propertyTagList, ref int expectedMessageIndex, string expectedPropertyValue, PropertyId expectedPropertyName = PropertyId.PidTagSubject)
        {
            RopQueryRowsResponse getNormalMailMessageContent = new RopQueryRowsResponse();
            uint repeatTime = 0;
            uint rowCount = 0;
            bool isExpectedPropertyInPropertyList = false;

            // If retry time more than expected, terminates the loop
            while (repeatTime < this.getMessageRepeatTime)
            {
                RopGetContentsTableResponse ropGetContentsTableResponse = this.OxoruleAdapter.RopGetContentsTable(folderHandle, ContentTableFlag.None, out contentsTableHandle);
                Site.Assert.AreEqual<uint>(0, ropGetContentsTableResponse.ReturnValue, "Getting contents table should succeed.");
                rowCount = ropGetContentsTableResponse.RowCount;
                repeatTime++;

                if (rowCount > 0)
                {
                    getNormalMailMessageContent = this.OxoruleAdapter.QueryPropertiesInTable(contentsTableHandle, propertyTagList);
                    Site.Assert.AreEqual<uint>(0, getNormalMailMessageContent.ReturnValue, "Getting mail message operation should succeed.");

                    for (int i = 0; i < propertyTagList.Length; i++)
                    {
                        if (propertyTagList[i].PropertyId == (ushort)expectedPropertyName)
                        {
                            isExpectedPropertyInPropertyList = true;
                            for (int j = 0; j < getNormalMailMessageContent.RowData.PropertyRows.Count; j++)
                            {
                                string propertyValue = AdapterHelper.PropertyValueConvertToString(getNormalMailMessageContent.RowData.PropertyRows[j].PropertyValues[i].Value);
                                if (propertyValue.Contains(expectedPropertyValue))
                                {
                                    expectedMessageIndex = j;
                                    return getNormalMailMessageContent;
                                }
                            }
                        }
                    }

                    Site.Assert.IsTrue(isExpectedPropertyInPropertyList, "The property {0} to be checked should be included in the property list.", expectedPropertyName.ToString());
                }

                if (repeatTime == this.getMessageRepeatTime)
                {
                    break;
                }

                Thread.Sleep(this.WaitForTheRuleToTakeEffect);
            }

            Site.Assert.Fail("Can't find the message which has a property {0} ant its value is {1} in the target mailbox.", expectedPropertyName.ToString(), expectedPropertyValue);
            return getNormalMailMessageContent;
        }
        /// <summary>
        /// Verify the RopGetNamesFromPropertyIds operation related requirements.
        /// </summary>
        /// <param name="propertyIdCount">The PropertyIdCount parameter in the request buffer which indicates the number of PropertyId.</param>
        /// <param name="propertyIds">A list of PropertyId in the request buffer.</param>
        /// <param name="ropGetNamesFromPropertyIdsResponse">The RopGetNamesFromPropertyIds response buffer structure.</param>
        /// <param name="objectType">Indicates which object type the RopGetNamesFromPropertyIds operation is acting on.</param>
        private void VerifyRopGetNamesFromPropertyIds(
            ushort propertyIdCount,
            PropertyId[] propertyIds,
            RopGetNamesFromPropertyIdsResponse ropGetNamesFromPropertyIdsResponse,
            ServerObjectType objectType)
        {
            // Since the RopGetNamesFromPropertyIds ROP response was parsed successfully, MS-OXCPRPT_R51802 can be captured directly.
            Site.CaptureRequirement(
                51802,
                @"[In Processing RopGetNamesFromPropertyIds] The server responds with a RopGetNamesFromPropertyIds ROP response buffer.");

            if (ropGetNamesFromPropertyIdsResponse.ReturnValue.Equals((uint)CPRPTErrorCode.None))
            {
                if (objectType == ServerObjectType.Message)
                {
                    // If the object type this operation acting on is Message object and this operation is performed successfully, then the following requirement can be captured.
                    Site.CaptureRequirement(
                        23701,
                        @"[In RopGetNamesFromPropertyIds ROP] This operation [RopGetNamesFromPropertyIds ROP] is valid on Message objects.");
                }

                if (objectType == ServerObjectType.Folder)
                {
                    // If the object type this operation acting on is Folder object and this operation is performed successfully, then the following requirement can be captured.
                    Site.CaptureRequirement(
                        23703,
                        @"[In RopGetNamesFromPropertyIds ROP] This operation [RopGetNamesFromPropertyIds ROP] is valid on Folder objects.");
                }

                if (objectType == ServerObjectType.Attachment)
                {
                    // If the object type this operation acting on is Attachment object and this operation is performed successfully, then the following requirement can be captured.
                    Site.CaptureRequirement(
                        23702,
                        @"[In RopGetNamesFromPropertyIds ROP] This operation [RopGetNamesFromPropertyIds ROP] is valid on Attachment objects.");
                }

                if (objectType == ServerObjectType.Logon)
                {
                    // If the object type this operation acting on is Logon object and this operation is performed successfully, then the following requirement can be captured.
                    Site.CaptureRequirement(
                        23704,
                        @"[In RopGetNamesFromPropertyIds ROP] This operation [RopGetNamesFromPropertyIds ROP] is valid on Logon objects.");
                }

                // The parser has ensured the field satisfied the format, otherwise the response cannot be received.
                Site.CaptureRequirement(
                  248,
                  @"[In RopGetNamesFromPropertyIds ROP Response Buffer] PropertyNameCount: 2 bytes integer.");

                if (ropGetNamesFromPropertyIdsResponse.PropertyNameCount != 0)
                {
                    // The parser has ensured the field satisfied the format, otherwise the response cannot be received.
                    Site.CaptureRequirement(
                          250,
                          @"[In RopGetNamesFromPropertyIds ROP Response Buffer] PropertyNames (variable): An array of PropertyName structures ([MS-OXCDATA] section 2.6).");
                }

                // Add the debug information
                Site.Log.Add(
                    LogEntryKind.Debug,
                    "Verify MS-OXCPRPT_R658, PropertyNameCount is {0}, ProertyNames is {1}",
                    ropGetNamesFromPropertyIdsResponse.PropertyNameCount,
                    ropGetNamesFromPropertyIdsResponse.PropertyNames);
            }

            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R249
            Site.CaptureRequirementIfAreEqual<ushort>(
                propertyIdCount,
                ropGetNamesFromPropertyIdsResponse.PropertyNameCount,
                249,
                @"[In RopGetNamesFromPropertyIds ROP Response Buffer] PropertyNameCount: This value MUST be equal to the value of the PropertyIdCount field of the ROP request buffer. ");

            Site.CaptureRequirementIfAreEqual<ushort>(
               propertyIdCount,
               (ushort)ropGetNamesFromPropertyIdsResponse.PropertyNames.Length,
               24802,
               @"[In RopGetNamesFromPropertyIds ROP Response Buffer] propertyNameCount: An integer that specifies the number of structures contained in the PropertyNames field. ");

            // Examine each property ID in the request message and each associated PropertyName in the response message.The order of the ID and Name matches.
            for (int i = 0; i < propertyIds.Length; i++)
            {
                if (propertyIds[i].ID < 0x8000)
                {
                    // Add the debug information
                    Site.Log.Add(
                        LogEntryKind.Debug,
                        "Verify MS-OXCPRPT_R518,The PropertyId requested is {0}, The GUID response in PropertyName is {1}, The expected value of GUID is {2}",
                        propertyIds[i].ID,
                        ropGetNamesFromPropertyIdsResponse.PropertyNames[i].Guid.ToString(),
                        this.valuePSMAPI.ToString());

                    // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R518
                    // Check whether the PropertyName's GUID is PS-MAPI
                    bool isVerifyR518 = Common.CompareByteArray(ropGetNamesFromPropertyIdsResponse.PropertyNames[i].Guid, this.valuePSMAPI);

                    Site.CaptureRequirementIfIsTrue(
                        isVerifyR518,
                        518,
                        @"[In Processing RopGetNamesFromPropertyIds] For each property ID in the PropertyIds field of the ROP request buffer, the server MUST perform the following: If the property ID is less than 0x8000, the associated PropertyName structure ([MS-OXCDATA] section 2.6.1) contained in the PropertyNames field of the ROP response buffer MUST be composed as follows: The structure's GUID field is set to the PS_MAPI property set ([MS-OXPROPS] section 1.3.2).");

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

                    Site.CaptureRequirementIfAreEqual<byte>(
                        0x00,
                        ropGetNamesFromPropertyIdsResponse.PropertyNames[i].Kind,
                        519,
                        @"[In Processing RopGetNamesFromPropertyIds] For each property ID in the PropertyIds field of the ROP request buffer, the server MUST perform the following: If the property ID is less than 0x8000, the associated PropertyName structure ([MS-OXCDATA] section 2.6.1) contained in the PropertyNames field of the ROP response buffer MUST be composed as follows:: The structure's Kind field is set to 0x00.");

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

                    Site.CaptureRequirementIfAreEqual<uint>(
                        (uint)propertyIds[i].ID,
                        (uint)ropGetNamesFromPropertyIdsResponse.PropertyNames[i].LID,
                        520,
                        @"[In Processing RopGetNamesFromPropertyIds] For each property ID in the PropertyIds field of the ROP request buffer, the server MUST perform the following: If the property ID is less than 0x8000, the associated PropertyName structure ([MS-OXCDATA] section 2.6.1) contained in the PropertyNames field of the ROP response buffer MUST be composed as follows:: The structure's LID field is set to the property ID.");
                }
            }

            bool isCDATAR25Valid = true;
            bool isCDATAR27Valid = true;
            foreach (PropertyName propertyName in ropGetNamesFromPropertyIdsResponse.PropertyNames)
            {
                // The parser has ensured the field satisfied the format, otherwise the response cannot be received.
                Site.CaptureRequirement(
                    "MS-OXCDATA",
                    30,
                    @"[In PropertyName Structure] Name (optional) (variable):  The value is a Unicode (UTF-16 format) string, followed by two zero bytes as terminating null characters, that identifies the property within its property set.");

                Site.CaptureRequirementIfIsNotNull(
                    propertyName.Guid,
                    "MS-OXCDATA",
                    21,
                    @"[In PropertyName Structure] GUID (16 bytes):  The GUID that identifies the property set for the named property.");

                // The parser has ensured the field satisfied the format, otherwise the response cannot be received.
                Site.CaptureRequirement(
                    "MS-OXCDATA",
                    26,
                    @"[In PropertyName Structure] LID (optional) (4 bytes):  An unsigned integer that identifies the named property within its property set.");

                if ((propertyName.LID != 0x00 && propertyName.Kind != 0x00) || ((propertyName.Kind == 0x01 || propertyName.Kind == 0x0ff) && propertyName.LID != 0x00))
                {
                    isCDATAR25Valid = false;
                }

                if ((propertyName.NameSize != null && propertyName.Kind != 0x01) || ((propertyName.Kind == 0x00 || propertyName.Kind == 0x0ff) && propertyName.NameSize != null))
                {
                    isCDATAR27Valid = false;
                }
            }

            Site.CaptureRequirementIfIsTrue(
                isCDATAR25Valid,
                "MS-OXCDATA",
                25,
                @"[In PropertyName Structure] LID (optional) (4 bytes): This field is present only if the value of the Kind field is equal to 0x00.");

            Site.CaptureRequirementIfIsTrue(
               isCDATAR27Valid,
               "MS-OXCDATA",
               27,
               @"[In PropertyName Structure] NameSize (optional) (1 byte):  This field is present only if the value of the Kind field is equal to 0x01.");

            Site.CaptureRequirementIfIsTrue(
               isCDATAR27Valid,
               "MS-OXCDATA",
               29,
               @"[In PropertyName Structure] Name (optional) (variable): This field is present only if Kind is equal to 0x01.");

            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R521
            // The property ID values has been verified that have an associated PropertyName.
            // Server will set the PropertyName value according to the PropertyId. So if the returned PropertyNames is not null, this requirement can be verified.
            Site.CaptureRequirementIfIsNotNull(
                ropGetNamesFromPropertyIdsResponse.PropertyNames,
                521,
                @"[In Processing RopGetNamesFromPropertyIds] For each property ID in the PropertyIds field of the ROP request buffer, the server MUST perform the following: For property IDs that have an associated PropertyName structure, the server MUST return the PropertyName structure associated with the property ID.");

            // Since the RopGetNamesFromPropertyIds ROP response was parsed successfully, MS-OXCPRPT_R230 can be captured directly.
            Site.CaptureRequirement(
                230,
                @"[In RopGetNamesFromPropertyIds ROP] The RopGetNamesFromPropertyIds ROP ([MS-OXCROPS] section 2.2.8.2) maps concrete property IDs to abstract, client-defined named properties");
        }
        public void MSOXCROPS_S06_TC04_TestRopsQuery()
        {
            this.CheckTransportIsSupported();

            this.cropsAdapter.RpcConnect(
                Common.GetConfigurationPropertyValue("SutComputerName", this.Site),
                ConnectionType.PrivateMailboxServer,
                Common.GetConfigurationPropertyValue("UserEssdn", this.Site),
                Common.GetConfigurationPropertyValue("Domain", this.Site),
                Common.GetConfigurationPropertyValue("AdminUserName", this.Site),
                Common.GetConfigurationPropertyValue("PassWord", this.Site));

            // Step 1: Send the RopQueryNamedProperties request and verify the success response.
            #region RopQueryNamedProperties success response

            // Log on to the private mailbox.
            RopLogonResponse logonResponse = Logon(LogonType.Mailbox, this.userDN, out inputObjHandle);

            // Call GetCreatedMessageHandle to create message and get the created message handle.
            uint messageHandle = GetCreatedMessageHandle(logonResponse.FolderIds[4], inputObjHandle);

            RopQueryNamedPropertiesRequest queryNamedPropertiesRequest = new RopQueryNamedPropertiesRequest();
            RopQueryNamedPropertiesResponse queryNamedPropertiesResponse;

            queryNamedPropertiesRequest.RopId = (byte)RopId.RopQueryNamedProperties;

            queryNamedPropertiesRequest.LogonId = TestSuiteBase.LogonId;
            queryNamedPropertiesRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;
            queryNamedPropertiesRequest.QueryFlags = (byte)QueryFlags.NoStrings;
            queryNamedPropertiesRequest.HasGuid = Convert.ToByte(TestSuiteBase.Zero);
            queryNamedPropertiesRequest.PropertyGuid = null;

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 1: Begin to send the RopQueryNamedProperties request.");

            // Send the RopQueryNamedProperties request and verify the success response.
            this.responseSOHs = cropsAdapter.ProcessSingleRop(
                queryNamedPropertiesRequest,
                messageHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            queryNamedPropertiesResponse = (RopQueryNamedPropertiesResponse)response;

            Site.Assert.AreEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                queryNamedPropertiesResponse.ReturnValue,
                "if ROP succeeds, ReturnValue of its response will be 0 (success)");

            #endregion

            // Step 2: Send the RopQueryNamedProperties request and verify the failure response.
            #region RopQueryNamedProperties failure response

            queryNamedPropertiesRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex1;

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 2: Begin to send the RopQueryNamedProperties request.");

            // Send the RopQueryNamedProperties request and verify the failure response.
            this.responseSOHs = cropsAdapter.ProcessSingleRop(
                queryNamedPropertiesRequest,
                messageHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.FailureResponse);
            queryNamedPropertiesResponse = (RopQueryNamedPropertiesResponse)response;

            Site.Assert.AreNotEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                queryNamedPropertiesResponse.ReturnValue,
                "if ROP failure, ReturnValue of its response will not be 0 (success)");
            Site.Assert.AreNotEqual<uint>(
                MS_OXCROPSAdapter.ReturnValueForRopQueryNamedProperties,
                queryNamedPropertiesResponse.ReturnValue,
                "if ROP failure, ReturnValue of its response will not be 0x00040380 (success)");

            #endregion

            // Step 3: Send the RopGetPropertyIdsFromNames request and verify the success response.
            #region RopGetPropertyIdsFromNames success response

            RopGetPropertyIdsFromNamesRequest getPropertyIdsFromNamesRequest;
            RopGetPropertyIdsFromNamesResponse getPropertyIdsFromNamesResponse;

            getPropertyIdsFromNamesRequest.RopId = (byte)RopId.RopGetPropertyIdsFromNames;
            getPropertyIdsFromNamesRequest.LogonId = TestSuiteBase.LogonId;
            getPropertyIdsFromNamesRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;
            getPropertyIdsFromNamesRequest.Flags = (byte)GetPropertyIdsFromNamesFlags.Create;

            // Call CreatePropertyNameArray method to create propertyName array.
            PropertyName[] propertyNameArray = this.CreatePropertyNameArray(3);

            getPropertyIdsFromNamesRequest.PropertyNameCount = (ushort)propertyNameArray.Length;
            getPropertyIdsFromNamesRequest.PropertyNames = propertyNameArray;

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 3: Begin to send the RopQueryNamedProperties request.");

            // Send the RopGetPropertyIdsFromNames request and verify the success response.
            this.responseSOHs = cropsAdapter.ProcessSingleRop(
                getPropertyIdsFromNamesRequest,
                this.inputObjHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            getPropertyIdsFromNamesResponse = (RopGetPropertyIdsFromNamesResponse)response;

            Site.Assert.AreEqual<uint>(
                TestSuiteBase.SuccessReturnValue,
                getPropertyIdsFromNamesResponse.ReturnValue,
                "If RopGetPropertyIdsFromNames succeeds, its response contains ReturnValue 0 (success)");

            #endregion

            // Step 4: Send the RopGetPropertyIdsFromNames request and verify the failure response.
            #region RopGetPropertyIdsFromNames failure response

            getPropertyIdsFromNamesRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex1;

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 4: Begin to send the RopGetPropertyIdsFromNames request.");

            this.responseSOHs = cropsAdapter.ProcessSingleRop(
                getPropertyIdsFromNamesRequest,
                this.inputObjHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.FailureResponse);

            #endregion

            // Step 5: Send the RopGetNamesFromPropertyIds request and verify the success response.
            #region RopGetNamesFromPropertyIds success response

            RopGetNamesFromPropertyIdsRequest getNamesFromPropertyIdsRequest;
            RopGetNamesFromPropertyIdsResponse getNamesFromPropertyIdsResponse;

            getNamesFromPropertyIdsRequest.RopId = (byte)RopId.RopGetNamesFromPropertyIds;
            getNamesFromPropertyIdsRequest.LogonId = TestSuiteBase.LogonId;
            getNamesFromPropertyIdsRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0;
            getNamesFromPropertyIdsRequest.PropertyIdCount = getPropertyIdsFromNamesResponse.PropertyIdCount;
            getNamesFromPropertyIdsRequest.PropertyIds = getPropertyIdsFromNamesResponse.PropertyIds;

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Step 5: Begin to send the RopGetNamesFromPropertyIds request.");

            // Send the RopGetNamesFromPropertyIds request and verify the success response.
            this.responseSOHs = cropsAdapter.ProcessSingleRop(
                getNamesFromPropertyIdsRequest,
                this.inputObjHandle,
                ref this.response,
                ref this.rawData,
                RopResponseType.SuccessResponse);
            getNamesFromPropertyIdsResponse = (RopGetNamesFromPropertyIdsResponse)response;

            #endregion

            // Step 6: Send the RopGetNamesFromPropertyIds request and verify the failure response.
            #region RopGetNamesFromPropertyIds failure response

            // Refer to MS-OXCROPS endnote<14>: For some ROPs, Exchange 2003 and Exchange 2007 use different methods to resolve the
            // server object and, therefore, do not fail the ROP if the index is invalid.
            if (Common.IsRequirementEnabled(4713, this.Site))
            {
                getNamesFromPropertyIdsRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex1;
                PropertyId propertyId = new PropertyId
                {
                    ID = TestSuiteBase.PropertyId
                };
                getNamesFromPropertyIdsRequest.PropertyIdCount = TestSuiteBase.PropertyIdCount;
                getNamesFromPropertyIdsRequest.PropertyIds = new PropertyId[1] { propertyId };

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Step 6: Begin to send the RopGetNamesFromPropertyIds request.");

                // Send the RopGetNamesFromPropertyIds request and verify the failure response.
                this.responseSOHs = cropsAdapter.ProcessSingleRop(
                    getNamesFromPropertyIdsRequest,
                    this.inputObjHandle,
                    ref this.response,
                    ref this.rawData,
                    RopResponseType.FailureResponse);
                getNamesFromPropertyIdsResponse = (RopGetNamesFromPropertyIdsResponse)response;

                Site.Assert.AreEqual<uint>(
                    TestSuiteBase.SuccessReturnValue,
                    getNamesFromPropertyIdsResponse.ReturnValue,
                    "<14> Section 3.2.5.1: For some ROPs, Exchange 2003 and Exchange 2007 use different methods to resolve the Server object and, therefore, do not fail the ROP if the index is invalid.");
            }
            else
            {
                // Verify the response on server other than Exchange 2007.
                getNamesFromPropertyIdsRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex1;
                PropertyId propertyId = new PropertyId
                {
                    ID = TestSuiteBase.PropertyId
                };
                getNamesFromPropertyIdsRequest.PropertyIdCount = TestSuiteBase.PropertyIdCount;
                getNamesFromPropertyIdsRequest.PropertyIds = new PropertyId[1] { propertyId };

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Step 6: Begin to send the RopGetNamesFromPropertyIds request.");

                // Send the RopGetNamesFromPropertyIds request and verify the failure response.
                this.responseSOHs = cropsAdapter.ProcessSingleRop(
                    getNamesFromPropertyIdsRequest,
                    this.inputObjHandle,
                    ref this.response,
                    ref this.rawData,
                    RopResponseType.FailureResponse);
                getNamesFromPropertyIdsResponse = (RopGetNamesFromPropertyIdsResponse)response;

                Site.Assert.AreNotEqual<uint>(
                    TestSuiteBase.SuccessReturnValue,
                    getNamesFromPropertyIdsResponse.ReturnValue,
                    "For this response, this field SHOULD be set to a value other than 0x00000000.");
            }

            #endregion
        }
        /// <summary>
        /// RopGetNamesFromPropertyIds implementation
        /// </summary>
        /// <param name="objHandle">This index specifies the location in the Server object handle table where the handle for the input Server object is stored</param>
        /// <param name="propertyIds">Array of unsigned 16-bit integers, number of integers in the array is specified by the PropertyIdCount field.</param>
        /// <returns>Structure of RopGetNamesFromPropertyIdsResponse</returns>
        private RopGetNamesFromPropertyIdsResponse RopGetNamesFromPropertyIds(uint objHandle, PropertyId[] propertyIds)
        {
            this.rawDataValue = null;
            this.responseValue = null;
            this.responseSOHsValue = null;

            RopGetNamesFromPropertyIdsRequest getNamesFromPropertyIdsRequest;
            RopGetNamesFromPropertyIdsResponse getNamesFromPropertyIdsResponse;

            getNamesFromPropertyIdsRequest.RopId = (byte)RopId.RopGetNamesFromPropertyIds;
            getNamesFromPropertyIdsRequest.LogonId = LogonId;
            getNamesFromPropertyIdsRequest.InputHandleIndex = (byte)HandleIndex.FirstIndex;
            getNamesFromPropertyIdsRequest.PropertyIds = propertyIds;
            if (getNamesFromPropertyIdsRequest.PropertyIds != null)
            {
                getNamesFromPropertyIdsRequest.PropertyIdCount = (ushort)propertyIds.Length;
            }
            else
            {
                // GetNamesFromPropertyIdsRequest.PropertyIds is null, so count of getNamesFromPropertyIdsRequest.PropertyIds is 0x00.
                getNamesFromPropertyIdsRequest.PropertyIdCount = 0x00;
            }

            this.responseSOHsValue = this.ProcessSingleRop(getNamesFromPropertyIdsRequest, objHandle, ref this.responseValue, ref this.rawDataValue, RopResponseType.SuccessResponse);
            getNamesFromPropertyIdsResponse = (RopGetNamesFromPropertyIdsResponse)this.responseValue;
            return getNamesFromPropertyIdsResponse;
        }