/// <summary>
        /// The capture code in NspiResolveNamesW.
        /// </summary>
        /// <param name="returnValue">The return value of NspiResolveNamesW.</param>
        /// <param name="mids">The mids parameter of NspiResolveNamesW.</param>
        /// <param name="rows">The PropertyRowSet_r structure the server returns.</param>
        private void VerifyNspiResolveNamesW(ErrorCodeValue returnValue, PropertyTagArray_r? mids, PropertyRowSet_r? rows)
        {
            // The IDL code parses the return value. If the IDL code can return success, the server must return the right result.
            this.Site.CaptureRequirement(
                1406,
                @"[In NspiResolveNamesW] Return Values: The server returns a long value that specifies the return status of the method.");

            if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp")
            {
                // The following IDL definition is used to generate the stub class, which is used to communicate with server. So if the operation can be called successfully, the following requirement can be captured directly.
                this.Site.CaptureRequirement(
                    1689,
                    @"[In NspiResolveNamesW] The interface definition is:

                long NspiResolveNamesW(
                    [in] NSPI_HANDLE hRpc,
                    [in] DWORD Reserved,
                    [in] STAT* pStat,
                    [in, unique] PropertyTagArray_r* pPropTags,
                    [in] WstringsArray_r* paWStr,
                    [out] PropertyTagArray_r** ppMIds,
                    [out] PropertyRowSet_r** ppRows
                );");
            }

            if ((returnValue == ErrorCodeValue.Success) || (returnValue == ErrorCodeValue.ErrorsReturned))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXNSPI_R1425");

                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1425
                // This structure, which is returned from the server, contains a list of Minimal Entry IDs. 
                // If it's not null, it illustrates that the server must have constructed the list.
                this.Site.CaptureRequirementIfIsNotNull(
                    mids,
                    1425,
                    @"[In NspiResolveNamesW] [Server Processing Rules: Upon receiving message NspiResolveNamesW, the server MUST process the data from the message subject to the following constraints:] [Constraint 6] The server constructs a list of the Minimal Entry IDs specified in section 2.2.1.9 to return to the client.");

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

                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1428
                // This structure, which is returned from the server, contains a list of Minimal Entry IDs. If it's not null, it illustrates that the 
                // server has returned the list of Minimal Entry IDs in the output parameter ppMIds.
                this.Site.CaptureRequirementIfIsNotNull(
                    mids,
                    1428,
                    @"[In NspiResolveNamesW] [Server Processing Rules: Upon receiving message NspiResolveNamesW, the server MUST process the data from the message subject to the following constraints:] [Constraint 6] The server MUST return this list of Minimal Entry IDs [Minimal Entry IDs resulted from the ANR process] in the output parameter ppMIds.");
            }

            if (mids != null)
            {
                this.VerifyPropertyTagArray_r();

                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1403
                // This test suite parses code according to this definition. So if the codes can reach here, this requirement can be captured directly.
                this.Site.CaptureRequirement(
                    1403,
                    @"[In NspiResolveNamesW] ppMIds: A PropertyTagArray_r value.");
            }

            if (rows != null)
            {
                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1404
                // This test suite parses code according to this definition. So if the codes can reach here, this requirement can be captured directly.
                this.Site.CaptureRequirement(
                    1404,
                    @"[In NspiResolveNamesW] ppRows: A reference to a PropertyRowSet_r structure (section 2.2.4), [which contains the address book container rows that the server returns in response to the request.] ");

                this.VerifyPropertyRowSetStructure(rows.Value);
            }

            this.VerifyReturnValues(returnValue);
            this.VerifyThreePossbleOutcomesOfANRProcess(mids, rows);
            this.VerifyMinimalEntryIDStructure();
        }
        /// <summary>
        /// The capture code in NspiGetMatches.
        /// </summary>
        /// <param name="returnValue">The return value of NspiGetMatches.</param>
        /// <param name="rows">The rows that the server returns.</param>
        /// <param name="outMIds">A PropertyTagArray_r value which contains a list of Minimal Entry IDs that comprise a restricted address book container.</param>
        /// <param name="inputStat">The input parameter STAT.</param>
        /// <param name="outputStat">The output parameter STAT.</param>
        private void VerifyNspiGetMatches(ErrorCodeValue returnValue, PropertyRowSet_r? rows, PropertyTagArray_r? outMIds, STAT inputStat, STAT outputStat)
        {
            if (outMIds != null)
            {
                this.VerifyPropertyTagArray_r();

                // According to the description in the Open Specification, outMIds holds a list of Minimal Entry IDs that comprise a restricted address book container.
                // So if outMIds is not null, it specifies that the list is instantiated as a PropertyTagArray_r structure.
                this.Site.CaptureRequirement(
                    507,
                    @"[In Explicit Tables] The list [a list of Minimal Entry IDs] is instantiated in the protocol either as an array of DWORDs or as a PropertyTagArray_r structure.");
            }

            // The IDL code parses the returned value. If the IDL code can return success, the server must return the right result.
            this.Site.CaptureRequirement(
                1097,
                @"[In NspiGetMatches] Return Values: The server returns a long value specifying the return status of the method.");

            // This parameter is defined as PropertyTagArray_r structure. If the parser code can parse the structure successfully, it illustrates that the server returns the result correctly.
            this.Site.CaptureRequirement(
                1091,
                @"[In NspiGetMatches] ppOutMIds: A PropertyTagArray_r value.");

            if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp")
            {
                // The following IDL definition is used to generate the stub class, which is used to communicate with server. So if the operation can be called successfully, the following requirement can be captured directly.
                this.Site.CaptureRequirement(
                    1682,
                    @"[In NspiGetMatches] The interface definition is:

                long NspiGetMatches(
                    [in] NSPI_HANDLE hRpc,
                    [in] DWORD Reserved1,
                    [in, out] STAT* pStat,
                    [in, unique] PropertyTagArray_r* pReserved,
                    [in] DWORD Reserved2,
                    [in, unique] Restriction_r* Filter,
                    [in, unique] PropertyName_r* lpPropName,
                    [in] DWORD ulRequested,
                    [out] PropertyTagArray_r** ppOutMIds,
                    [in, unique] PropertyTagArray_r* pPropTags,
                    [out] PropertyRowSet_r** ppRows
                );");
            }

            if (returnValue == ErrorCodeValue.Success)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXNSPI_R1166");

                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1166
                // The parameter rows is returned from the server. If it is not null, it illustrates that the 
                // server has returned the PropertyRowSet_r structure in the output parameter pProws.
                this.Site.CaptureRequirementIfIsNotNull(
                    rows,
                    1166,
                    @"[In NspiGetMatches] The server MUST return the constructed PropertyRowSet_r in the output parameter ppRows.");
            }

            this.VerifyReturnValues(returnValue);

            if (rows != null)
            {
                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1095
                // This test suite parses code according to this definition. So if the codes can reach here, this requirement can be captured directly.
                this.Site.CaptureRequirement(
                    1095,
                    @"[In NspiGetMatches] ppRows: A reference to a PropertyRowSet_r value.");

                foreach (PropertyRow_r propertyRow in rows.Value.ARow)
                {
                    this.VerifyStringOrString8Value(propertyRow);

                    // Parse the Minimal Entry ID if it exists.
                    if (propertyRow.LpProps[0].Value.Bin.Cb > 0)
                    {
                        EphemeralEntryID ephemeralEntryID = AdapterHelper.ParseEphemeralEntryIDFromBytes(propertyRow.LpProps[0].Value.Bin.Lpb);

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

                        // Verify MS-OXNSPI requirement: MS-OXNSPI_R506
                        // The NspiGetMatches method returns an Explicit Table. So if the parsed ephemeralEntryID is not null, it means that the Explicit Table is implemented as a list of Minimal Entry IDs.
                        this.Site.CaptureRequirementIfIsNotNull(
                            ephemeralEntryID,
                            506,
                            @"[In Explicit Tables] This table [Explicit Table] is implemented as a list of Minimal Entry IDs.");
                    }
                }

                this.VerifyPropertyRowSetStructure(rows.Value);
            }

            this.VerifySTATStructure(returnValue, inputStat, outputStat, true);
            this.VerifyMinimalEntryIDStructure();
        }
        /// <summary>
        /// Verify there are three possible outcomes to the ANR process.
        /// </summary>
        /// <param name="mids">The mids parameter of NspiResolveNames or NspiResolveNamesW.</param>
        /// <param name="rows">The PropertyRowSet_r structure the server returns.</param>
        private void VerifyThreePossbleOutcomesOfANRProcess(PropertyTagArray_r? mids, PropertyRowSet_r? rows)
        {
            if (rows != null)
            {
                foreach (PropertyRow_r propertyRow in rows.Value.ARow)
                {
                    this.VerifyStringOrString8Value(propertyRow);
                }
            }

            if (mids != null)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXNSPI_R1611.");

                bool validAnrResult = true;
                this.Site.Assert.IsTrue(mids.Value.CValues > 0, "There should be values returned from server.");
                foreach (uint minimalEntryID in mids.Value.AulPropTag)
                {
                    if (!(minimalEntryID == (uint)ANRMinEntryID.MID_AMBIGUOUS
                        || minimalEntryID == (uint)ANRMinEntryID.MID_RESOLVED
                        || minimalEntryID == (uint)ANRMinEntryID.MID_UNRESOLVED))
                    {
                        validAnrResult = false;
                        break;
                    }
                }

                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1611
                this.Site.CaptureRequirementIfIsTrue(
                    validAnrResult,
                    1611,
                    @"[In Ambiguous Name Resolution] There are three possible outcomes [MID_UNRESOLVED, MID_AMBIGUOUS and MID_RESOLVED] to the ANR process.");

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

                this.Site.CaptureRequirementIfIsTrue(
                    validAnrResult,
                    87,
                    @"[In Ambiguous Name Resolution Minimal Entry IDs] The following table lists the possible values [MID_UNRESOLVED, MID_AMBIGUOUS and MID_RESOLVED].");
            }
        }
        /// <summary>
        /// Verify parameters related to method NspiGetMatches.
        /// </summary>
        /// <param name="result">A DWORD value that specifies the return status of the method.</param>
        /// <param name="outMIds">A PropertyTagArray_r value which holds a list of Minimal Entry IDs that comprise a restricted address book container.</param>
        /// <param name="rowsOfGetMatches">A PropertyRowSet_r value which contains the address book container rows that the server returns in response to the request.</param>
        /// <param name="stat">A reference to a STAT block describing a logical position in a specific address book container.</param>
        /// <param name="inputStat">The input parameter of STAT.</param>
        private void VerifyParametersRelatedWithNspiGetMatches(ErrorCodeValue result, PropertyTagArray_r? outMIds, PropertyRowSet_r? rowsOfGetMatches, STAT stat, STAT inputStat)
        {
            if (result != ErrorCodeValue.Success)
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXNSPI_R1635");

                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1635
                Site.CaptureRequirementIfIsNull(
                    outMIds,
                    1635,
                    @"[In NspiGetMatches] [Server Processing Rules: Upon receiving message NspiGetMatches, the server MUST process the data from the message subject to the following constraints:] [Constraint 4] If the server returns any return values other than ""Success"", the server MUST return a NULL for the output parameters ppOutMIds.");

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

                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1756
                Site.CaptureRequirementIfIsNull(
                    rowsOfGetMatches,
                    1756,
                    @"[In NspiGetMatches] [Server Processing Rules: Upon receiving message NspiGetMatches, the server MUST process the data from the message subject to the following constraints:] [Constraint 4] If the server returns any return values other than ""Success"", the server MUST return a NULL for the output parameters ppRows.");

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

                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1636
                bool isVerifyR1636 = (stat.SortType == inputStat.SortType)
                                    && (stat.ContainerID == inputStat.ContainerID)
                                    && (stat.CurrentRec == inputStat.CurrentRec)
                                    && (stat.Delta == inputStat.Delta)
                                    && (stat.NumPos == inputStat.NumPos)
                                    && (stat.TotalRecs == inputStat.TotalRecs)
                                    && (stat.CodePage == inputStat.CodePage)
                                    && (stat.TemplateLocale == inputStat.TemplateLocale)
                                    && (stat.SortLocale == inputStat.SortLocale);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR1636,
                    1636,
                    @"[In NspiGetMatches] [Server Processing Rules: Upon receiving message NspiGetMatches, the server MUST process the data from the message subject to the following constraints:] [Constraint 4] [If the server returns any return values other than ""Success"",] and [the server] MUST NOT modify the value of the parameter pStat.");
            }
        }
        /// <summary>
        /// The capture code in NspiSeekEntries.
        /// </summary>
        /// <param name="returnValue">The return value of NspiSeekEntries.</param>
        /// <param name="rows">The rows that the server returns.</param>
        /// <param name="inputStat">The input parameter STAT.</param>
        /// <param name="outputStat">The output parameter STAT.</param>
        private void VerifyNspiSeekEntries(ErrorCodeValue returnValue, PropertyRowSet_r? rows, STAT inputStat, STAT outputStat)
        {
            // The IDL code parses the return value. If the IDL code can return success, the server must return the right result.
            this.Site.CaptureRequirement(
                1012,
                @"[In NspiSeekEntries] Return Values: The server returns a long value specifying the return status of the method.");

            if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp")
            {
                // The following IDL definition is used to generate the stub class, which is used to communicate with server. So if the operation can be called successfully, the following requirement can be captured directly.
                this.Site.CaptureRequirement(
                    1681,
                    @"[In NspiSeekEntries] The interface definition is:
                long NspiSeekEntries(
                    [in] NSPI_HANDLE hRpc,
                    [in] DWORD Reserved,
                    [in, out] STAT* pStat,
                    [in] PropertyValue_r* pTarget,
                    [in, unique] PropertyTagArray_r* lpETable,
                    [in, unique] PropertyTagArray_r* pPropTags,
                    [out] PropertyRowSet_r** ppRows
                );");
            }

            if (rows != null)
            {
                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1010
                // This test suite parses code according to this definition. So if the codes can reach here, this requirement can be captured directly.
                this.Site.CaptureRequirement(
                    1010,
                    @"[In NspiSeekEntries] ppRows: A reference to a PropertyRowSet_r value.");

                this.VerifyPropertyRowSetStructure(rows.Value);

                foreach (PropertyRow_r propertyRow in rows.Value.ARow)
                {
                    this.VerifyStringOrString8Value(propertyRow);
                }
            }

            this.VerifyReturnValues(returnValue);
            this.VerifySTATStructure(returnValue, inputStat, outputStat, false);
            this.VerifyContainerIDCanNotBeModified(inputStat, outputStat);
        }
        /// <summary>
        /// The NspiSeekEntries method searches for and sets the logical position in a specific table
        /// to the first entry greater than or equal to a specified value. 
        /// </summary>
        /// <param name="reserved">A DWORD value that is reserved for future use. Ignored by the server.</param>
        /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param>
        /// <param name="target">A PropertyValue_r value holding the value that is being sought.</param>
        /// <param name="table">The value NULL or a PropertyTagArray_r value. 
        /// It holds a list of Minimal Entry IDs that comprise a restricted address book container.</param>
        /// <param name="propTags">It contains a list of the proptags of the columns 
        /// that client wants to be returned for each row returned.</param>
        /// <param name="rows">It contains the address book container rows the server returns in response to the request.</param>
        /// <param name="needRetry">A Boolean value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param>
        /// <returns>Status of NSPI method.</returns>
        public ErrorCodeValue NspiSeekEntries(uint reserved, ref STAT stat, PropertyValue_r target, PropertyTagArray_r? table, PropertyTagArray_r? propTags, out PropertyRowSet_r? rows, bool needRetry = true)
        {
            ErrorCodeValue result = 0;
            STAT inputStat = stat;

            if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp")
            {
                result = this.nspiRpcAdapter.NspiSeekEntries(reserved, ref stat, target, table, propTags, out rows, needRetry);
            }
            else
            {
                result = this.nspiMapiHttpAdapter.SeekEntries(reserved, ref stat, target, table, propTags, out rows);
            }

            this.VerifyNspiSeekEntries(result, rows, inputStat, stat);
            this.VerifyTransport();
            return result;
        }
        /// <summary>
        /// The NspiResolveNames method takes a set of string values in an 8-bit character set and performs ANR on those strings. 
        /// The NspiResolveNames method taking string values in an 8-bit character set is not supported when mapi_http transport is used. 
        /// </summary>
        /// <param name="reserved">A DWORD reserved for future use.</param>
        /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param>
        /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r value containing a list of the proptags of the columns 
        /// that the client requests to be returned for each row returned.</param>
        /// <param name="stringArray">A StringsArray_r value. It specifies the values on which the client is requesting the server to do ANR.</param>
        /// <param name="mids">A PropertyTagArray_r value. On return, it contains a list of Minimal Entry IDs that match the array of strings.</param>
        /// <param name="rows">A reference to a PropertyRowSet_r value. 
        /// It contains the address book container rows that the server returns in response to the request.</param>
        /// <param name="needRetry">A Boolean value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param>
        /// <returns>Status of NSPI method.</returns>
        public ErrorCodeValue NspiResolveNames(uint reserved, STAT stat, PropertyTagArray_r? propTags, StringsArray_r? stringArray, out PropertyTagArray_r? mids, out PropertyRowSet_r? rows, bool needRetry = true)
        {
            ErrorCodeValue result;
            result = this.nspiRpcAdapter.NspiResolveNames(reserved, stat, propTags, stringArray, out mids, out rows, needRetry);

            this.VerifyNspiResolveNames(result, mids, rows);
            this.VerifyTransport();
            return result;
        }
        /// <summary>
        /// The NspiSeekEntries method searches for and sets the logical position in a specific table
        /// to the first entry greater than or equal to a specified value. 
        /// </summary>
        /// <param name="reserved">A DWORD value that is reserved for future use. Ignored by the server.</param>
        /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param>
        /// <param name="target">A PropertyValue_r value holding the value that is being sought.</param>
        /// <param name="table">The value NULL or a PropertyTagArray_r value. 
        /// It holds a list of Minimal Entry IDs that comprise a restricted address book container.</param>
        /// <param name="propTags">It contains a list of the proptags of the columns 
        /// that client wants to be returned for each row returned.</param>
        /// <param name="rows">It contains the address book container rows the server returns in response to the request.</param>
        /// <returns>Status of NSPI method.</returns>
        public ErrorCodeValue SeekEntries(uint reserved, ref STAT stat, PropertyValue_r target, PropertyTagArray_r? table, PropertyTagArray_r? propTags, out PropertyRowSet_r? rows)
        {
            ErrorCodeValue result;
            SeekEntriesRequestBody seekEntriesRequestBody = new SeekEntriesRequestBody();
            TaggedPropertyValue targetValue = new TaggedPropertyValue();
            targetValue.PropertyTag = new PropertyTag((ushort)((target.PropTag & 0xFFFF0000) >> 16), (ushort)(target.PropTag & 0x0000FFFF));
            targetValue.Value = new byte[target.Serialize().Length - 8];
            Array.Copy(target.Serialize(), 8, targetValue.Value, 0, target.Serialize().Length - 8);

            // Reserved. The client MUST set this field to 0x00000000 and the server MUST ignore this field.
            seekEntriesRequestBody.Reserved = reserved;
            seekEntriesRequestBody.HasState = true;
            seekEntriesRequestBody.State = stat;
            seekEntriesRequestBody.HasTarget = true;
            seekEntriesRequestBody.Target = targetValue;
            if (table != null)
            {
                seekEntriesRequestBody.HasExplicitTable = true;
                seekEntriesRequestBody.ExplicitTable = table.Value.AulPropTag;
            }

            LargePropTagArray propetyTags = new LargePropTagArray();
            if (propTags != null)
            {
                propetyTags.PropertyTagCount = propTags.Value.CValues;
                propetyTags.PropertyTags = new PropertyTag[propetyTags.PropertyTagCount];
                for (int i = 0; i < propTags.Value.CValues; i++)
                {
                    propetyTags.PropertyTags[i].PropertyId = (ushort)((propTags.Value.AulPropTag[i] & 0xFFFF0000) >> 16);
                    propetyTags.PropertyTags[i].PropertyType = (ushort)(propTags.Value.AulPropTag[i] & 0x0000FFFF);
                }

                seekEntriesRequestBody.HasColumns = true;
                seekEntriesRequestBody.Columns = propetyTags;
            }

            seekEntriesRequestBody.AuxiliaryBufferSize = 0;
            seekEntriesRequestBody.AuxiliaryBuffer = new byte[] { };
            ChunkedResponse chunkedResponse = this.SendAddressBookRequest(seekEntriesRequestBody, RequestType.SeekEntries);
            SeekEntriesResponseBody seekEntriesResponseBody = SeekEntriesResponseBody.Parse(chunkedResponse.ResponseBodyRawData);
            result = (ErrorCodeValue)seekEntriesResponseBody.ErrorCode;
            if (seekEntriesResponseBody.HasColumnsAndRows)
            {
                PropertyRowSet_r newRows = AdapterHelper.ParsePropertyRowSet_r(seekEntriesResponseBody.Columns.Value, seekEntriesResponseBody.RowCount.Value, seekEntriesResponseBody.RowData);
                rows = newRows;
            }
            else
            {
                rows = null;
            }

            if (seekEntriesResponseBody.HasState)
            {
                stat = seekEntriesResponseBody.State.Value;
            }

            return result;
        }
        /// <summary>
        /// The NspiGetMatches method returns an Explicit Table. 
        /// </summary>
        /// <param name="reserved">A DWORD value reserved for future use.</param>
        /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param>
        /// <param name="proReserved">A PropertyTagArray_r reserved for future use.</param>
        /// <param name="reserved2">A DWORD value reserved for future use. Ignored by the server.</param>
        /// <param name="filter">The value NULL or a Restriction_r value. 
        /// It holds a logical restriction to apply to the rows in the address book container specified in the stat parameter.</param>
        /// <param name="propName">The value NULL or a PropertyName_r value. 
        /// It holds the property to be opened as a restricted address book container.</param>
        /// <param name="requested">A DWORD value. It contains the maximum number of rows to return in a restricted address book container.</param>
        /// <param name="outMids">A PropertyTagArray_r value. On return, it holds a list of Minimal Entry IDs that comprise a restricted address book container.</param>
        /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r value. 
        /// It contains a list of the proptags of the columns that client wants to be returned for each row returned.</param>
        /// <param name="rows">A reference to a PropertyRowSet_r value. It contains the address book container rows the server returns in response to the request.</param>
        /// <returns>Status of NSPI method.</returns>
        public ErrorCodeValue GetMatches(uint reserved, ref STAT stat, PropertyTagArray_r? proReserved, uint reserved2, Restriction_r? filter, PropertyName_r? propName, uint requested, out PropertyTagArray_r? outMids, PropertyTagArray_r? propTags, out PropertyRowSet_r? rows)
        {
            ErrorCodeValue result;
            byte[] auxIn = new byte[] { };
            GetMatchesRequestBody getMatchesRequestBody = new GetMatchesRequestBody()
            {
                Reserved = reserved,
                HasState = true,
                State = stat,
                InterfaceOptionFlags = reserved2,
                HasPropertyName = false,
                RowCount = requested,
                AuxiliaryBuffer = auxIn,
                AuxiliaryBufferSize = (uint)auxIn.Length
            };

            if (propTags != null)
            {
                LargePropTagArray propetyTags = new LargePropTagArray();
                propetyTags.PropertyTagCount = propTags.Value.CValues;
                propetyTags.PropertyTags = new PropertyTag[propetyTags.PropertyTagCount];
                for (int i = 0; i < propTags.Value.CValues; i++)
                {
                    propetyTags.PropertyTags[i].PropertyId = (ushort)((propTags.Value.AulPropTag[i] & 0xFFFF0000) >> 16);
                    propetyTags.PropertyTags[i].PropertyType = (ushort)(propTags.Value.AulPropTag[i] & 0x0000FFFF);
                }

                getMatchesRequestBody.HasColumns = true;
                getMatchesRequestBody.Columns = propetyTags;
            }

            if (proReserved != null)
            {
                getMatchesRequestBody.HasMinimalIds = true;
                getMatchesRequestBody.MinimalIdCount = proReserved.Value.CValues;
                getMatchesRequestBody.MinimalIds = proReserved.Value.AulPropTag;
            }

            if (filter != null)
            {
                getMatchesRequestBody.HasFilter = true;
                getMatchesRequestBody.Filter = AdapterHelper.ConvertRestriction_rToRestriction(filter.Value);
            }

            ChunkedResponse chunkedResponse = this.SendAddressBookRequest(getMatchesRequestBody, RequestType.GetMatches);
            GetMatchesResponseBody getMatchesResponseBody = GetMatchesResponseBody.Parse(chunkedResponse.ResponseBodyRawData);
            result = (ErrorCodeValue)getMatchesResponseBody.ErrorCode;
            if (getMatchesResponseBody.HasMinimalIds)
            {
                PropertyTagArray_r propertyTagArray = new PropertyTagArray_r();
                propertyTagArray.CValues = getMatchesResponseBody.MinimalIdCount.Value;
                propertyTagArray.AulPropTag = getMatchesResponseBody.MinimalIds;
                outMids = propertyTagArray;
            }
            else
            {
                outMids = null;
            }

            if (getMatchesResponseBody.RowCount != null)
            {
                PropertyRowSet_r newRows = AdapterHelper.ParsePropertyRowSet_r(getMatchesResponseBody.Columns.Value, getMatchesResponseBody.RowCount.Value, getMatchesResponseBody.RowData);
                rows = newRows;
            }
            else
            {
                rows = null;
            }

            if (getMatchesResponseBody.HasState)
            {
                stat = getMatchesResponseBody.State.Value;
            }

            return result;
        }
        /// <summary>
        /// The NspiGetSpecialTable method returns the rows of a special table to the client. 
        /// </summary>
        /// <param name="flags">A DWORD value that contains a set of bit flags.</param>
        /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param>
        /// <param name="version">A reference to a DWORD. On input, it holds the value of the version number of
        /// the address book hierarchy table that the client has. On output, it holds the version of the server's address book hierarchy table.</param>
        /// <param name="rows">A PropertyRowSet_r structure. On return, it holds the rows for the table that the client is requesting.</param>
        /// <returns>Status of NSPI method.</returns>
        public ErrorCodeValue GetSpecialTable(uint flags, ref STAT stat, ref uint version, out PropertyRowSet_r? rows)
        {
            ErrorCodeValue result;
            byte[] auxIn = new byte[] { };
            GetSpecialTableRequestBody getSpecialTableRequestBody = new GetSpecialTableRequestBody()
            {
                Flags = flags,
                HasState = true,
                State = stat,
                HasVersion = true,
                Version = version,
                AuxiliaryBuffer = auxIn,
                AuxiliaryBufferSize = (uint)auxIn.Length
            };

            ChunkedResponse chunkedResponse = this.SendAddressBookRequest(getSpecialTableRequestBody, RequestType.GetSpecialTable);
            GetSpecialTableResponseBody getSpecialTableResponseBody = GetSpecialTableResponseBody.Parse(chunkedResponse.ResponseBodyRawData);
            result = (ErrorCodeValue)getSpecialTableResponseBody.ErrorCode;
            if (getSpecialTableResponseBody.HasRows)
            {
                PropertyRowSet_r newRows = AdapterHelper.ParsePropertyRowSet_r(getSpecialTableResponseBody.RowCount.Value, getSpecialTableResponseBody.Rows);
                rows = newRows;
            }
            else
            {
                rows = null;
            }

            if (getSpecialTableResponseBody.HasVersion)
            {
                version = getSpecialTableResponseBody.Version.Value;
            }

            return result;
        }
        /// <summary>
        /// The NspiQueryRows method returns a number of rows from a specified table to the client.
        /// </summary>
        /// <param name="flags">A DWORD value that contains a set of bit flags.</param>
        /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param>
        /// <param name="tableCount">A DWORD value that contains the number values in the input parameter table. 
        /// This value is limited to 100,000.</param>
        /// <param name="table">An array of DWORD values, representing an Explicit Table.</param>
        /// <param name="count">A DWORD value that contains the number of rows the client is requesting.</param>
        /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r value, 
        /// containing a list of the proptags of the properties that the client requires to be returned for each row returned.</param>
        /// <param name="rows">A nullable PropertyRowSet_r value, it contains the address book container rows that the server returns in response to the request.</param>
        /// <returns>Status of NSPI method.</returns>
        public ErrorCodeValue QueryRows(uint flags, ref STAT stat, uint tableCount, uint[] table, uint count, PropertyTagArray_r? propTags, out PropertyRowSet_r? rows)
        {
            ErrorCodeValue result;
            QueryRowsRequestBody queryRowsRequestBody = new QueryRowsRequestBody();
            LargePropTagArray propetyTags = new LargePropTagArray();
            if (propTags != null)
            {
                propetyTags.PropertyTagCount = propTags.Value.CValues;
                propetyTags.PropertyTags = new PropertyTag[propetyTags.PropertyTagCount];
                for (int i = 0; i < propTags.Value.CValues; i++)
                {
                    propetyTags.PropertyTags[i].PropertyId = (ushort)((propTags.Value.AulPropTag[i] & 0xFFFF0000) >> 16);
                    propetyTags.PropertyTags[i].PropertyType = (ushort)(propTags.Value.AulPropTag[i] & 0x0000FFFF);
                }

                queryRowsRequestBody.HasColumns = true;
                queryRowsRequestBody.Columns = propetyTags;
            }

            queryRowsRequestBody.Flags = flags;
            queryRowsRequestBody.HasState = true;
            queryRowsRequestBody.State = stat;
            queryRowsRequestBody.ExplicitTableCount = tableCount;
            queryRowsRequestBody.ExplicitTable = table;
            queryRowsRequestBody.RowCount = count;
            byte[] auxIn = new byte[] { };
            queryRowsRequestBody.AuxiliaryBuffer = auxIn;
            queryRowsRequestBody.AuxiliaryBufferSize = (uint)auxIn.Length;

            ChunkedResponse chunkedResponse = this.SendAddressBookRequest(queryRowsRequestBody, RequestType.QueryRows);
            QueryRowsResponseBody queryRowsResponseBody = QueryRowsResponseBody.Parse(chunkedResponse.ResponseBodyRawData);
            result = (ErrorCodeValue)queryRowsResponseBody.ErrorCode;
            if (queryRowsResponseBody.RowCount != null)
            {
                PropertyRowSet_r newRows = AdapterHelper.ParsePropertyRowSet_r(queryRowsResponseBody.Columns.Value, queryRowsResponseBody.RowCount.Value, queryRowsResponseBody.RowData);
                rows = newRows;
            }
            else
            {
                rows = null;
            }

            if (queryRowsResponseBody.HasState)
            {
                stat = queryRowsResponseBody.State.Value;
            }

            return result;
        }
        /// <summary>
        /// Check whether PropertyRowSet_r is not null.
        /// </summary>
        /// <param name="rowOfResolveNames">Contain the address book container rows that the server returns in response to the request.</param>
        private void VerifyPropertyRowSetIsNotNullForNspiResolveNames(PropertyRowSet_r? rowOfResolveNames)
        {
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXNSPI_R1379");

            // Verify MS-OXNSPI requirement: MS-OXNSPI_R1379
            // The rowOfResolveNames which contains a PropertyRowSet_r structure is returned from the server. If it is not null, 
            // it illustrates that the server must have constructed it.
            Site.CaptureRequirementIfIsNotNull(
                rowOfResolveNames,
                1379,
                @"[In NspiResolveNames] [Server Processing Rules: Upon receiving message NspiResolveNames, the server MUST process the data from the message subject to the following constraints:] [Constraint 7] Subject to the prior constraints, the server MUST construct a PropertyRowSet_r to return to the client.");

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

            // Verify MS-OXNSPI requirement: MS-OXNSPI_R1354
            Site.CaptureRequirementIfIsNotNull(
                rowOfResolveNames,
                1354,
                @"[In NspiResolveNames] [ppRows: A reference to a PropertyRowSet_r structure (section 2.2.4), ] which contains the address book container rows that the server returns in response to the request. ");
        }
        /// <summary>
        /// Verify server used the list specified by the input parameter pPropTags.
        /// </summary>
        /// <param name="rowsOfQueryRows">Contains the address book container rows that the server returns in response to the request.</param>
        /// <param name="propTags">The input list specified by pPropTags.</param>
        private void VerifyServerUsedTheListInNspiQueryRows(PropertyRowSet_r? rowsOfQueryRows, PropertyTagArray_r? propTags)
        {
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXNSPI_R951");

            // Verify MS-OXNSPI requirement: MS-OXNSPI_R951
            Site.CaptureRequirementIfIsTrue(
                AdapterHelper.IsRowSetSubjectToPropTags(propTags, rowsOfQueryRows),
                951,
                @"[In NspiQueryRows] [Server Processing Rules: Upon receiving message NspiQueryRows, the server MUST process the data from the message subject to the following constraints:] [Constraint 6] [If the input parameter pPropTags is not NULL] The server MUST use this list [the list specified by pPropTags].");
        }
        /// <summary>
        /// Verify rows returned from NspiQueryRows is not null.
        /// </summary>
        /// <param name="rowsOfQueryRows">Contains the address book container rows that the server returns in response to the request.</param>
        private void VerifyRowsReturnedFromNspiQueryRowsIsNotNull(PropertyRowSet_r? rowsOfQueryRows)
        {
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXNSPI_R973");

            // Verify MS-OXNSPI requirement: MS-OXNSPI_R973
            // The rowsOfQueryRows is returned from the server which contains a RowSet, if it is not null, it illustrates that the server 
            // must have constructed it.
            Site.CaptureRequirementIfIsNotNull(
                rowsOfQueryRows,
                973,
                @"[In NspiQueryRows] [Server Processing Rules: Upon receiving message NspiQueryRows, the server MUST process the data from the message subject to the following constraints:] [Constraint 14] The server constructs a RowSet.");
        }
        /// <summary>
        /// The NspiGetSpecialTable method returns the rows of a special table to the client. 
        /// </summary>
        /// <param name="flags">A DWORD value that contains a set of bit flags.</param>
        /// <param name="stat">A pointer to a STAT block that describes a logical position in a specific address book container.</param>
        /// <param name="version">A reference to a DWORD. On input, it holds the value of the version number of
        /// the address book hierarchy table that the client has. On output, it holds the version of the server's address book hierarchy table.</param>
        /// <param name="rows">A PropertyRowSet_r structure. On return, it holds the rows for the table that the client is requesting.</param>
        /// <param name="needRetry">A Boolean value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param>
        /// <returns>Status of NSPI method.</returns>
        public ErrorCodeValue NspiGetSpecialTable(uint flags, ref STAT stat, ref uint version, out PropertyRowSet_r? rows, bool needRetry = true)
        {
            ErrorCodeValue result;
            if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp")
            {
                result = this.nspiRpcAdapter.NspiGetSpecialTable(flags, ref stat, ref version, out rows, needRetry);
            }
            else
            {
                result = this.nspiMapiHttpAdapter.GetSpecialTable(flags, ref stat, ref version, out rows);
            }

            this.VerifyNspiGetSpecialTable(result, rows);
            this.VerifyTransport();
            return result;
        }
        /// <summary>
        /// The NspiResolveNamesW method takes a set of string values in the Unicode character set 
        /// and performs ANR on those strings. 
        /// </summary>
        /// <param name="reserved">A DWORD value that is reserved for future use.</param>
        /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param>
        /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r containing a list of the proptags of the columns 
        /// that the client requests to be returned for each row returned.</param>
        /// <param name="wstr">A WStringsArray_r value. It specifies the values on which the client is requesting the server to perform ANR.</param>
        /// <param name="mids">A PropertyTagArray_r value. On return, it contains a list of Minimal Entry IDs that match the array of strings.</param>
        /// <param name="rows">A reference to a PropertyRowSet_r structure. It contains the address book container rows that the server returns in response to the request.</param>
        /// <returns>Status of NSPI method.</returns>
        public ErrorCodeValue ResolveNames(uint reserved, STAT stat, PropertyTagArray_r? propTags, WStringsArray_r? wstr, out PropertyTagArray_r? mids, out PropertyRowSet_r? rows)
        {
            ErrorCodeValue result;
            byte[] auxIn = new byte[] { };
            ResolveNamesRequestBody resolveNamesRequestBody = new ResolveNamesRequestBody()
            {
                Reserved = reserved,
                HasState = true,
                State = stat,
                AuxiliaryBuffer = auxIn,
                AuxiliaryBufferSize = (uint)auxIn.Length
            };

            if (propTags != null)
            {
                LargePropTagArray propetyTags = new LargePropTagArray();
                propetyTags.PropertyTagCount = propTags.Value.CValues;
                propetyTags.PropertyTags = new PropertyTag[propetyTags.PropertyTagCount];
                for (int i = 0; i < propTags.Value.CValues; i++)
                {
                    propetyTags.PropertyTags[i].PropertyId = (ushort)((propTags.Value.AulPropTag[i] & 0xFFFF0000) >> 16);
                    propetyTags.PropertyTags[i].PropertyType = (ushort)(propTags.Value.AulPropTag[i] & 0x0000FFFF);
                }

                resolveNamesRequestBody.HasPropertyTags = true;
                resolveNamesRequestBody.PropertyTags = propetyTags;
            }
            else
            {
                resolveNamesRequestBody.HasPropertyTags = false;
                resolveNamesRequestBody.PropertyTags = new LargePropTagArray();
            }

            if (wstr != null)
            {
                resolveNamesRequestBody.HasNames = true;
                resolveNamesRequestBody.Names = wstr.Value;
            }
            else
            {
                resolveNamesRequestBody.HasNames = false;
            }

            ChunkedResponse chunkedResponse = this.SendAddressBookRequest(resolveNamesRequestBody, RequestType.ResolveNames);
            ResolveNamesResponseBody resolveNamesResponseBody = ResolveNamesResponseBody.Parse(chunkedResponse.ResponseBodyRawData);
            result = (ErrorCodeValue)resolveNamesResponseBody.ErrorCode;
            if (resolveNamesResponseBody.RowCount != null)
            {
                PropertyRowSet_r newRows = AdapterHelper.ParsePropertyRowSet_r(resolveNamesResponseBody.PropertyTags.Value, resolveNamesResponseBody.RowCount.Value, resolveNamesResponseBody.RowData);
                rows = newRows;
            }
            else
            {
                rows = null;
            }

            if (resolveNamesResponseBody.HasMinimalIds)
            {
                PropertyTagArray_r propertyTagArray = new PropertyTagArray_r();
                propertyTagArray.CValues = resolveNamesResponseBody.MinimalIdCount.Value;
                propertyTagArray.AulPropTag = resolveNamesResponseBody.MinimalIds;
                mids = propertyTagArray;
            }
            else
            {
                mids = null;
            }

            return result;
        }
        /// <summary>
        /// The NspiQueryRows method returns a number of rows from a specified table to the client.
        /// </summary>
        /// <param name="flags">A DWORD value that contains a set of bit flags.</param>
        /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param>
        /// <param name="tableCount">A DWORD value that contains the number values in the input parameter table. 
        /// This value is limited to 100,000.</param>
        /// <param name="table">An array of DWORD values, representing an Explicit Table.</param>
        /// <param name="count">A DWORD value that contains the number of rows the client is requesting.</param>
        /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r value, 
        /// containing a list of the proptags of the properties that the client requires to be returned for each row returned.</param>
        /// <param name="rows">A nullable PropertyRowSet_r value, it contains the address book container rows that the server returns in response to the request.</param>
        /// <param name="needRetry">A Boolean value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param>
        /// <returns>Status of NSPI method.</returns>
        public ErrorCodeValue NspiQueryRows(uint flags, ref STAT stat, uint tableCount, uint[] table, uint count, PropertyTagArray_r? propTags, out PropertyRowSet_r? rows, bool needRetry = true)
        {
            ErrorCodeValue result;
            STAT inputStat = stat;

            if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp")
            {
                result = this.nspiRpcAdapter.NspiQueryRows(flags, ref stat, tableCount, table, count, propTags, out rows, needRetry);
            }
            else
            {
                result = this.nspiMapiHttpAdapter.QueryRows(flags, ref stat, tableCount, table, count, propTags, out rows);
            }

            this.VerifyNspiQueryRows(result, rows, inputStat, stat);
            this.VerifyTransport();
            return result;
        }
        /// <summary>
        /// Verify PropertyRowSet_r structure.
        /// </summary>
        /// <param name="propertyRowSet">A PropertyRowSet_r value to be verified.</param>
        private void VerifyPropertyRowSetStructure(PropertyRowSet_r propertyRowSet)
        {
            // Verify MS-OXNSPI requirement: MS-OXNSPI_R1575
            // Because the underlying parser code has parsed out the structure which contains it, this requirement can be captured directly.
            this.Site.CaptureRequirement(
                1575,
                @"[In PropertyRowSet_r Structure] [The type is defined as following:] typedef struct _PropertyRowSet_r {
                [range(0,100000)] DWORD cRows;
                [size_is(cRows)] PropertyRow_r aRow[];
            } PropertyRowSet_r;");

            // This test suite defines PropertyRowSet_r structure based on the meaning of PropertyRowSet data structure. So if the codes can reach here, it means that the semantic meaning is unchanged.
            this.Site.CaptureRequirement(
                234,
                @"[In PropertyRowSet_r Structure] The semantic meaning is otherwise unchanged from the PropertyRowSet data structure.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXNSPI_R236: [In PropertyRowSet_r Structure] [cRows] This value is {0}", propertyRowSet.CRows);

            // Verify MS-OXNSPI requirement: MS-OXNSPI_R236
            this.Site.CaptureRequirementIfIsTrue(
                propertyRowSet.CRows <= 100000,
                236,
                @"[In PropertyRowSet_r Structure] [cRows] This value MUST NOT exceed 100,000.");

            if (propertyRowSet.ARow != null)
            {
                foreach (PropertyRow_r propertyRow in propertyRowSet.ARow)
                {
                    if (propertyRow.CValues != 0)
                    {
                        this.VerifyPropertyRowStructure(propertyRow);
                    }
                }
            }

            // Verify MS-OXCDATA requirement: MS-OXCDATA_R95
            // This test suite parses code according to this definition. So if the codes can reach here, this requirement can be captured directly.
            this.Site.CaptureRequirement(
                "MS-OXCDATA",
                95,
                @"[In PropertyRowSet Structure] RowCount (2 bytes): RowCount (2 bytes): An unsigned integer specifying the number of PropertyRow structures in the Rows field.");

            // Verify MS-OXCDATA requirement: MS-OXCDATA_R97.
            // This test suite parses code according to this definition. So if the codes can reach here, this requirement can be captured directly.
            this.Site.CaptureRequirement(
                "MS-OXCDATA",
                97,
                @"[In PropertyRowSet_r Structure] RowCount (2 bytes):This value encodes the RowCount field of the PropertyRowSet structure, as specified in section 2.8.2.1.");

            // Verify MS-OXCDATA requirement: MS-OXCDATA_R99.
            // This test suite parses code according to this definition. So if the codes can reach here, this requirement can be captured directly.
            this.Site.CaptureRequirement(
                "MS-OXCDATA",
                99,
                @"[In PropertyRowSet_r Structure] Rows (variable): This value encodes the rows field of the PropertyRowSet structure.");
        }
        /// <summary>
        /// The NspiGetMatches method returns an Explicit Table. 
        /// </summary>
        /// <param name="reserved">A DWORD value reserved for future use.</param>
        /// <param name="stat">A STAT block describing a logical position in a specific address book container.</param>
        /// <param name="proReserved">A PropertyTagArray_r reserved for future use.</param>
        /// <param name="reserved2">A DWORD value reserved for future use. Ignored by the server.</param>
        /// <param name="filter">The value NULL or a Restriction_r value. 
        /// It holds a logical restriction to apply to the rows in the address book container specified in the stat parameter.</param>
        /// <param name="propName">The value NULL or a PropertyName_r value. 
        /// It holds the property to be opened as a restricted address book container.</param>
        /// <param name="requested">A DWORD value. It contains the maximum number of rows to return in a restricted address book container.</param>
        /// <param name="outMids">A PropertyTagArray_r value. On return, it holds a list of Minimal Entry IDs that comprise a restricted address book container.</param>
        /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r value. 
        /// It contains a list of the proptags of the columns that client wants to be returned for each row returned.</param>
        /// <param name="rows">A reference to a PropertyRowSet_r value. It contains the address book container rows the server returns in response to the request.</param>
        /// <param name="needRetry">A Boolean value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param>
        /// <returns>Status of NSPI method.</returns>
        public ErrorCodeValue NspiGetMatches(uint reserved, ref STAT stat, PropertyTagArray_r? proReserved, uint reserved2, Restriction_r? filter, PropertyName_r? propName, uint requested, out PropertyTagArray_r? outMids, PropertyTagArray_r? propTags, out PropertyRowSet_r? rows, bool needRetry = true)
        {
            ErrorCodeValue result = 0;
            STAT inputStat = stat;

            if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp")
            {
                result = this.nspiRpcAdapter.NspiGetMatches(reserved, ref stat, proReserved, reserved2, filter, propName, requested, out outMids, propTags, out rows, needRetry);
            }
            else
            {
                result = this.nspiMapiHttpAdapter.GetMatches(reserved, ref stat, proReserved, reserved2, filter, propName, requested, out outMids, propTags, out rows);
            }

            this.VerifyNspiGetMatches(result, rows, outMids, inputStat, stat);
            this.VerifyTransport();
            return result;
        }
        /// <summary>
        /// The capture code in NspiGetSpecialTable.
        /// </summary>
        /// <param name="returnValue">The return value of NspiGetSpecialTable.</param>
        /// <param name="rows">The search result of NspiGetSpecialTable.</param>
        private void VerifyNspiGetSpecialTable(ErrorCodeValue returnValue, PropertyRowSet_r? rows)
        {
            // The IDL code parses the return value. If the IDL code can return success, the server must return the right result.
            this.Site.CaptureRequirement(
                728,
                @"[In NspiGetSpecialTable] Return Values: The server returns a LONG [MS-DTYP] value that specifies the return status of the method.");

            if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp")
            {
                // The following IDL definition is used to generate the stub class, which is used to communicate with server. So if the operation can be called successfully, the following requirement can be captured directly.
                this.Site.CaptureRequirement(
                    1674,
                    @"[In NspiGetSpecialTable] The interface definition is:
                long NspiGetSpecialTable(
                    [in] NSPI_HANDLE hRpc,
                    [in] DWORD dwFlags,
                    [in] STAT* pStat,
                    [in, out] DWORD* lpVersion,
                    [out] PropertyRowSet_r** ppRows
                );");
            }

            // Verify MS-OXNSPI requirement: MS-OXNSPI_R726
            // This test suite parses code according to this definition. So if the codes can reach here, this requirement can be captured directly.
            this.Site.CaptureRequirement(
                726,
                @"[In NspiGetSpecialTable] ppRows: A PropertyRowSet_r structure.");

            // Verify MS-OXNSPI requirement: MS-OXNSPI_R724
            // This test suite parses code according to this definition. So if the codes can reach here, this requirement can be captured directly.
            this.Site.CaptureRequirement(
                724,
                @"[In NspiGetSpecialTable] lpVersion: A reference to a DWORD.");

            this.VerifyReturnValues(returnValue);
            if (rows != null && rows.Value.ARow != null)
            {
                this.VerifyPropertyRowSetStructure(rows.Value);

                foreach (PropertyRow_r propertyRow in rows.Value.ARow)
                {
                    this.VerifyStringOrString8Value(propertyRow);
                }
            }
        }
        /// <summary>
        /// The NspiResolveNamesW method takes a set of string values in the Unicode character set and performs ANR on those strings. 
        /// </summary>
        /// <param name="reserved">A DWORD value that is reserved for future use.</param>
        /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param>
        /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r containing a list of the proptags of the columns 
        /// that the client requests to be returned for each row returned.</param>
        /// <param name="wstr">A WStringsArray_r value. It specifies the values on which the client is requesting the server to perform ANR.</param>
        /// <param name="mids">A PropertyTagArray_r value. On return, it contains a list of Minimal Entry IDs that match the array of strings.</param>
        /// <param name="rowOfResolveNamesW">A reference to a PropertyRowSet_r structure. It contains the address book container rows that the server returns in response to the request.</param>
        /// <param name="needRetry">A Boolean value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param>
        /// <returns>Status of NSPI method.</returns>
        public ErrorCodeValue NspiResolveNamesW(uint reserved, STAT stat, PropertyTagArray_r? propTags, WStringsArray_r? wstr, out PropertyTagArray_r? mids, out PropertyRowSet_r? rowOfResolveNamesW, bool needRetry = true)
        {
            ErrorCodeValue result;

            if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp")
            {
                result = this.nspiRpcAdapter.NspiResolveNamesW(reserved, stat, propTags, wstr, out mids, out rowOfResolveNamesW, needRetry);
            }
            else
            {
                result = this.nspiMapiHttpAdapter.ResolveNames(reserved, stat, propTags, wstr, out mids, out rowOfResolveNamesW);
            }

            this.VerifyNspiResolveNamesW(result, mids, rowOfResolveNamesW);
            this.VerifyTransport();
            return result;
        }
        /// <summary>
        /// Verify parameters related to method NspiSeekEntries.
        /// </summary>
        /// <param name="result">A DWORD value that specifies the return status of the method.</param>
        /// <param name="rowsOfSeekEntries">A PropertyRowSet_r value which contains the address book container rows that the server returns in response to the request.</param>
        /// <param name="inputStat">The STAT parameter before calling NspiSeekEntries.</param>
        /// <param name="stat">The STAT parameter after calling NspiSeekEntries.</param>
        private void VerifyParametersRelatedWithNspiSeekEntries(ErrorCodeValue result, PropertyRowSet_r? rowsOfSeekEntries, STAT inputStat, STAT stat)
        {
            if (result != ErrorCodeValue.Success)
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXNSPI_R1630");

                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1630
                Site.CaptureRequirementIfIsNull(
                    rowsOfSeekEntries,
                    1630,
                    @"[In NspiSeekEntries] [Server Processing Rules: Upon receiving message NspiSeekEntries, the server MUST process the data from the message subject to the following constraints:] [Constraint 4] If the server returns any return values other than ""Success"", the server MUST return a NULL for the output parameter ppRows");

                // Add the debug information
                Site.Log.Add(
                    LogEntryKind.Debug,
                    "Verify MS-OXNSPI_R1631: the SortType of output stat is {0}, the ContainerID of output stat is {1}, the CurrentRec of output stat is {2}, the Delta of output stat is {3}, the NumPos of output stat is {4}, the TotalRecs of output stat is {5}, the CodePage of output stat is {6}, the TemplateLocale of output stat is {7}, the SortLocale of output stat is {8};" +
                    "the SortType of inputStat is {9}, the ContainerID of inputStat is {10}, the CurrentRec of inputStat is {11}, the Delta of inputStat is {12}, the NumPos of inputStat is {13}, the TotalRecs of inputStat is {13}, the CodePage of inputStat is {14}, the TemplateLocale of inputStat is {15}, the SortLocale of inputStat is {16}",
                    stat.SortType,
                    stat.ContainerID,
                    stat.CurrentRec,
                    stat.Delta,
                    stat.NumPos,
                    stat.TotalRecs,
                    stat.CodePage,
                    stat.TemplateLocale,
                    stat.SortLocale,
                    inputStat.SortType,
                    inputStat.ContainerID,
                    inputStat.CurrentRec,
                    inputStat.Delta,
                    inputStat.NumPos,
                    inputStat.TotalRecs,
                    inputStat.CodePage,
                    inputStat.TemplateLocale,
                    inputStat.SortLocale);

                // Verify MS-OXNSPI requirement: MS-OXNSPI_R1631
                bool isVerifyR1631 = (stat.SortType == inputStat.SortType)
                                    && (stat.ContainerID == inputStat.ContainerID)
                                    && (stat.CurrentRec == inputStat.CurrentRec)
                                    && (stat.Delta == inputStat.Delta)
                                    && (stat.NumPos == inputStat.NumPos)
                                    && (stat.TotalRecs == inputStat.TotalRecs)
                                    && (stat.CodePage == inputStat.CodePage)
                                    && (stat.TemplateLocale == inputStat.TemplateLocale)
                                    && (stat.SortLocale == inputStat.SortLocale);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR1631,
                    1631,
                    @"[In NspiSeekEntries] [Server Processing Rules: Upon receiving message NspiSeekEntries, the server MUST process the data from the message subject to the following constraints:] [Constraint 4] [If the server returns any return values other than ""Success"", the server] MUST NOT modify the value of the parameter pStat.");
            }
        }