A class indicates the QueryRows request type.
Inheritance: AddressBookRequestBodyBase
Beispiel #1
0
        /// <summary>
        /// This method is used by the client to get a number of rows from the specified Explicit Table.
        /// </summary>
        /// <param name="queryRowsRequestBody">The QueryRows request type request body.</param>
        /// <returns>The response body of QueryRows request type</returns>
        public QueryRowsResponseBody QueryRows(QueryRowsRequestBody queryRowsRequestBody)
        {
            CommonResponse        commonResponse        = this.SendAddressBookRequest(queryRowsRequestBody, RequestType.QueryRows);
            QueryRowsResponseBody queryRowsResponseBody = QueryRowsResponseBody.Parse(commonResponse.ResponseBodyRawData);

            this.VerifyQueryRowsResponseBody(queryRowsResponseBody, queryRowsRequestBody);
            if (queryRowsResponseBody.HasColumnsAndRows)
            {
                foreach (AddressBookPropertyRow row in queryRowsResponseBody.RowData)
                {
                    this.VerifyAddressBookPropertyRowStructure(row);
                }

                this.VerifyLargePropTagArrayStructure(queryRowsResponseBody.Columns.Value);
            }

            return(queryRowsResponseBody);
        }
        /// <summary>
        /// This method is used by the client to get a number of rows from the specified Explicit Table.
        /// </summary>
        /// <param name="queryRowsRequestBody">The QueryRows request type request body.</param>
        /// <returns>The response body of QueryRows request type</returns>
        public QueryRowsResponseBody QueryRows(QueryRowsRequestBody queryRowsRequestBody)
        {
            CommonResponse        commonResponse        = this.SendAddressBookRequest(queryRowsRequestBody, RequestType.QueryRows);
            QueryRowsResponseBody queryRowsResponseBody = QueryRowsResponseBody.Parse(commonResponse.ResponseBodyRawData);

            this.VerifyQueryRowsResponseBody(queryRowsResponseBody, queryRowsRequestBody);
            if (queryRowsResponseBody.HasColumnsAndRows)
            {
                foreach (AddressBookPropertyRow row in queryRowsResponseBody.RowData)
                {
                    this.VerifyAddressBookPropertyRowStructure(row);

                    if (row.Flag == 0x0)
                    {
                        for (int i = 0; i < row.ValueArray.Length; i++)
                        {
                            if (queryRowsRequestBody.Columns.PropertyTags[i].PropertyType != 0x0000)
                            {
                                this.VerifyAddressBookPropertyValueStructure(row.ValueArray[i]);
                            }
                        }
                    }
                    else
                    {
                        for (int j = 0; j < row.ValueArray.Length; j++)
                        {
                            this.VerifyAddressBookFlaggedPropertyValueStructure((AddressBookFlaggedPropertyValue)row.ValueArray[j]);
                        }
                    }
                }

                this.VerifyLargePropertyTagArrayStructure(queryRowsResponseBody.Columns.Value);
            }

            return(queryRowsResponseBody);
        }
        /// <summary>
        /// Verify the QueryRows request type response body related requirements.
        /// </summary>
        /// <param name="queryRowsResponseBody">The QueryRowsResponseBody to be verified.</param>
        /// <param name="queryRowsRequestBody">The QueryRowsRequestBody to be verified.</param>
        private void VerifyQueryRowsResponseBody(QueryRowsResponseBody queryRowsResponseBody, QueryRowsRequestBody queryRowsRequestBody)
        {
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R843");
        
            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R843
            this.Site.CaptureRequirementIfIsInstanceOfType(
                queryRowsResponseBody.StatusCode,
                typeof(uint),
                843,
                @"[In QueryRows Request Type Success Response Body] StatusCode (4 bytes): An unsigned integer that specifies the status of the request.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R844");
        
            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R844
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0,
                queryRowsResponseBody.StatusCode,
                844,
                @"[In QueryRows Request Type Success Response Body] [StatusCode] This field MUST be set to 0x00000000.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R845");
        
            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R845
            this.Site.CaptureRequirementIfIsInstanceOfType(
                queryRowsResponseBody.ErrorCode,
                typeof(uint),
                845,
                @"[In QueryRows Request Type Success Response Body] ErrorCode (4 bytes): An unsigned integer that specifies the return status of the operation.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R846");
        
            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R846
            this.Site.CaptureRequirementIfIsInstanceOfType(
                queryRowsResponseBody.HasState,
                typeof(bool),
                846,
                @"[In QueryRows Request Type Success Response Body] HasState (1 byte): A Boolean value that specifies whether the State field is present.");

            if (queryRowsResponseBody.HasState)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R850");

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R850
                this.Site.CaptureRequirementIfIsNotNull(
                    queryRowsResponseBody.State,
                    850,
                    @"[In QueryRows Request Type Success Response Body] [State] This field is present when the HasState field is nonzero.");

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

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R847
                this.Site.CaptureRequirementIfIsInstanceOfType(
                    queryRowsResponseBody.State,
                    typeof(STAT),
                    847,
                    @"[In QueryRows Request Type Success Response Body] State (optional) (36bytes): A STAT structure ([MS-OXNSPI] section 2.3.7) that specifies the state of a specific address book container.");
            }
            else
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R851.");

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R851
                this.Site.CaptureRequirementIfIsNull(
                    queryRowsResponseBody.State,
                    851,
                    @"[In QueryRows Request Type Success Response Body] [State] This field is not present when the HasState field is zero.");
            }

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R852");
        
            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R852
            this.Site.CaptureRequirementIfIsInstanceOfType(
                queryRowsResponseBody.HasColumnsAndRows,
                typeof(bool),
                852,
                @"[In QueryRows Request Type Success Response Body] HasColumnsAndRows (1 byte): A Boolean value that specifies whether the Columns, RowCount, and RowData fields are present.");

            if (queryRowsResponseBody.HasColumnsAndRows)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R853");

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R853
                this.Site.CaptureRequirementIfIsInstanceOfType(
                    queryRowsResponseBody.Columns,
                    typeof(LargePropertyTagArray),
                    853,
                    @"[In QueryRows Request Type Success Response Body] Columns (optional) (variable): A LargePropTagArray structure (section 2.2.1.3) that specifies the columns for the rows returned.");

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

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R854
                this.Site.CaptureRequirementIfIsNotNull(
                    queryRowsResponseBody.Columns,
                    854,
                    @"[In QueryRows Request Type Success Response Body] [Columns] This field is present when the value of the HasColumnsAndRows field is nonzero.");

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

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R856
                this.Site.CaptureRequirementIfIsInstanceOfType(
                    queryRowsResponseBody.RowCount,
                    typeof(uint),
                    856,
                    @"[In QueryRows Request Type Success Response Body] RowCount (optional) (4 bytes): An unsigned integer that specifies the number of structures in the RowData field.");

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

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R857
                this.Site.CaptureRequirementIfIsNotNull(
                    queryRowsResponseBody.RowCount,
                    857,
                    @"[In QueryRows Request Type Success Response Body] [RowCount] This field is present when the value of the HasColumnsAndRows field is nonzero.");

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

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R859
                this.Site.CaptureRequirementIfIsInstanceOfType(
                    queryRowsResponseBody.RowData,
                    typeof(AddressBookPropertyRow[]),
                    859,
                    @"[In QueryRows Request Type Success Response Body] RowData (optional) (variable): An array of AddressBookPropertyRow structures (section 2.2.1.2), each of which specifies the row data of the Explicit Table.");

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

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R860
                this.Site.CaptureRequirementIfIsNotNull(
                    queryRowsResponseBody.RowData,
                    860,
                    @"[In QueryRows Request Type Success Response Body] [RowData] This field is present when the HasColumnsAndRows field is nonzero.");

                //// Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R825, the value of RowCount for queryRowsResponseBody is {0}.", queryRowsResponseBody.RowCount.Value);

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R825
                // If the row count server maintained is bigger than the requested row number, the server will return the number of rows it maintained, 
                // otherwise, server will return the rows according to the requested row count.
                this.Site.CaptureRequirementIfIsTrue(
                    queryRowsRequestBody.RowCount >= queryRowsResponseBody.RowCount.Value,
                    825,
                    @"[In QueryRows Request Type Request Body] RowCount (4 bytes): An unsigned integer that specifies the number of rows the client is requesting.");
            }
            else
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R855.");

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R855
                this.Site.CaptureRequirementIfIsNull(
                    queryRowsResponseBody.Columns,
                    855,
                    @"[In QueryRows Request Type Success Response Body] [Columns] This field is not present when the value of the HasColumnsAndRows field is zero.");

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

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R858
                this.Site.CaptureRequirementIfIsNull(
                    queryRowsResponseBody.RowCount,
                    858,
                    @"[In QueryRows Request Type Success Response Body] [RowCount] This field is not present when the value of the HasColumnsAndRows field is zero.");

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

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R861
                this.Site.CaptureRequirementIfIsNull(
                    queryRowsResponseBody.RowData,
                    861,
                    @"[In QueryRows Request Type Success Response Body] [RowData] This field is not present when the HasColumnsAndRows field is zero.");
            }
            
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R862");
        
            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R862
            this.Site.CaptureRequirementIfIsInstanceOfType(
                queryRowsResponseBody.AuxiliaryBufferSize,
                typeof(uint),
                862,
                @"[In QueryRows Request Type Success Response Body] AuxiliaryBufferSize (4 bytes): An unsigned integer that specifies the size, in bytes, of the AuxiliaryBuffer field.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R863");
        
            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R863
            this.Site.CaptureRequirementIfIsInstanceOfType(
                queryRowsResponseBody.AuxiliaryBuffer,
                typeof(byte[]),
                863,
                @"[In QueryRows Request Type Success Response Body] AuxiliaryBuffer (variable): An array of bytes that constitute the auxiliary payload data returned from the server.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R864");
        
            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R864
            this.Site.CaptureRequirementIfAreEqual<uint>(
                queryRowsResponseBody.AuxiliaryBufferSize,
                (uint)queryRowsResponseBody.AuxiliaryBuffer.Length,
                864,
                @"[In QueryRows Request Type Success Response Body] [AuxiliaryBuffer] The size of this field, in bytes, is specified by the AuxiliaryBufferSize field.");
        }
        /// <summary>
        /// Build the QueryRows request body.
        /// </summary>
        /// <param name="hasState">A Boolean value that specifies whether the State field is present.</param>
        /// <param name="state">A STAT structure that specifies the state of a specific address book container.</param>
        /// <param name="explicitTableCount">An unsigned integer that specifies the number of structures present in the ExplicitTable field.</param>
        /// <param name="explicitTable">An array of MinimalEntryID structures that constitute the Explicit Table.</param>
        /// <param name="rowCount">An unsigned integer that specifies the number of rows the client is requesting.</param>
        /// <param name="hasColumns">A Boolean value that specifies whether the Columns field is present.</param>
        /// <param name="columns">A LargePropTagArray structure that specifies the properties that the client requires for each row returned.</param>
        /// <returns>Returns the QueryRows request body.</returns>
        private QueryRowsRequestBody BuildQueryRowsRequestBody(bool hasState, STAT state, uint explicitTableCount, uint[] explicitTable, uint rowCount, bool hasColumns, LargePropertyTagArray columns)
        {
            QueryRowsRequestBody queryRowsRequestBody = new QueryRowsRequestBody();

            queryRowsRequestBody.Flags = (uint)RetrievePropertyFlags.fSkipObjects;
            queryRowsRequestBody.HasState = hasState;
            if (hasState)
            {
                queryRowsRequestBody.State = state;
            }

            queryRowsRequestBody.ExplicitTableCount = explicitTableCount;
            queryRowsRequestBody.ExplicitTable = explicitTable;
            queryRowsRequestBody.RowCount = rowCount;

            queryRowsRequestBody.HasColumns = hasColumns;
            if (hasColumns)
            {
                queryRowsRequestBody.Columns = columns;
            }

            byte[] auxIn = new byte[] { };
            queryRowsRequestBody.AuxiliaryBuffer = auxIn;
            queryRowsRequestBody.AuxiliaryBufferSize = (uint)auxIn.Length;

            return queryRowsRequestBody;
        }
        public void MSOXCMAPIHTTP_S02_TC21_TestHasValueWithPropertyTypePtypMultipleString()
        {
            this.CheckMapiHttpIsSupported();

            byte[] auxIn = new byte[] { };

            #region Call Bind request type to established a session context with the address book server.
            this.Bind();
            #endregion

            #region Call QueryRows request type to get a set of valid rows used to matched entry ID as the input paramter of ModLinkAtt method.
            STAT stat = new STAT();
            stat.InitiateStat();

            uint tableCount = 0;
            uint[] table = null;
            LargePropertyTagArray largePropTagArray = new LargePropertyTagArray()
            {
                PropertyTagCount = 4,
                PropertyTags = new PropertyTag[]
                {
                    new PropertyTag
                    {
                        PropertyType = (ushort)PropertyTypeValues.PtypString,
                        PropertyId = (ushort)PropertyID.PidTagDisplayName
                    }, 
                    new PropertyTag
                    {
                        PropertyType = (ushort)PropertyTypeValues.PtypBinary,
                        PropertyId = (ushort)PropertyID.PidTagEntryId
                    },
                    new PropertyTag
                    {
                        PropertyType = (ushort)PropertyTypeValues.PtypInteger32,
                        PropertyId = (ushort)PropertyID.PidTagDisplayType
                    },
                    new PropertyTag
                    {
                        PropertyType = (ushort)PropertyTypeValues.PtypMultipleString,
                        PropertyId = (ushort)PropertyID.PidTagAddressBookMember
                    }
                }
            };

            QueryRowsRequestBody queryRowsRequestBody = new QueryRowsRequestBody();
            queryRowsRequestBody.Flags = (uint)RetrievePropertyFlags.fSkipObjects;
            queryRowsRequestBody.HasState = true;
            queryRowsRequestBody.State = stat;
            queryRowsRequestBody.ExplicitTableCount = tableCount;
            queryRowsRequestBody.ExplicitTable = table;
            queryRowsRequestBody.RowCount = ConstValues.QueryRowsRequestedRowNumber;
            queryRowsRequestBody.HasColumns = true;
            queryRowsRequestBody.Columns = largePropTagArray;
            queryRowsRequestBody.AuxiliaryBuffer = auxIn;
            queryRowsRequestBody.AuxiliaryBufferSize = (uint)auxIn.Length;

            QueryRowsResponseBody queryRowsResponseBody = this.Adapter.QueryRows(queryRowsRequestBody);
            Site.Assert.AreEqual<uint>(0, queryRowsResponseBody.ErrorCode, "QueryRows request should be executed successfully, the returned value {0}.", queryRowsResponseBody.ErrorCode);
            #endregion

            #region Call ModLinkAtt with flags 0x00000000 to add the specified PidTagAddressBookMember value.
            uint flagsOfModLinkAtt = 0;
            PropertyTag propTagOfModLinkAtt = new PropertyTag
            {
                PropertyType = (ushort)PropertyTypeValues.PtypEmbeddedTable,
                PropertyId = (ushort)PropertyID.PidTagAddressBookMember
            };
            uint midOfModLinkAtt = 0;
            byte[] entryId = null;
            GetPropsRequestBody getPropsRequestBodyForAddressBookMember = null;
            uint lengthOfErrorCodeValue = sizeof(uint);
            string dlistName = Common.GetConfigurationPropertyValue("DistributionListName", this.Site);
            string memberName = Common.GetConfigurationPropertyValue("GeneralUserName", this.Site);

            for (int i = 0; i < queryRowsResponseBody.RowCount; i++)
            {
                string name = System.Text.Encoding.Unicode.GetString(queryRowsResponseBody.RowData[i].ValueArray[0].Value);
                if (name.ToLower().Contains(dlistName.ToLower()))
                {
                    PermanentEntryID entryID = AdapterHelper.ParsePermanentEntryIDFromBytes(queryRowsResponseBody.RowData[i].ValueArray[1].Value);

                    DNToMinIdRequestBody requestBodyOfDNToMId = new DNToMinIdRequestBody()
                    {
                        Reserved = 0,
                        HasNames = true,
                        Names = new StringArray_r
                        {
                            CValues = 1,
                            LppzA = new string[]
                            {
                                entryID.DistinguishedName
                            }
                        },
                        AuxiliaryBuffer = auxIn,
                        AuxiliaryBufferSize = (uint)auxIn.Length
                    };
                    DnToMinIdResponseBody responseBodyOfDNToMinId = this.Adapter.DnToMinId(requestBodyOfDNToMId);
                    midOfModLinkAtt = responseBodyOfDNToMinId.MinimalIds[0];

                    stat.CurrentRec = midOfModLinkAtt;
                    STAT? statForGetProps = stat;
                    LargePropertyTagArray propertyTagForGetProps = new LargePropertyTagArray()
                    {
                        PropertyTagCount = 2,
                        PropertyTags = new PropertyTag[] 
                        {
                            new PropertyTag
                            {
                                PropertyType = (ushort)PropertyTypeValues.PtypInteger32,
                                PropertyId = (ushort)PropertyID.PidTagDisplayType
                            },
                            new PropertyTag
                            {
                                PropertyType = (ushort)PropertyTypeValues.PtypMultipleString,
                                PropertyId = (ushort)PropertyID.PidTagAddressBookMember
                            },
                        }
                    };

                    getPropsRequestBodyForAddressBookMember = this.BuildGetPropsRequestBody((uint)0, true, statForGetProps, true, propertyTagForGetProps);
                    GetPropsResponseBody getPropsResponseBody = this.Adapter.GetProps(getPropsRequestBodyForAddressBookMember);
                    this.Site.Assert.AreEqual<uint>(0, getPropsResponseBody.StatusCode, "The GetProps request should be executed successfully, the returned status code is {0}", getPropsResponseBody.StatusCode);
                    this.Site.Assert.AreEqual<uint>(lengthOfErrorCodeValue, (uint)getPropsResponseBody.PropertyValues.Value.PropertyValues[1].Value.Length, "The length of the property value should be equal the ErrorCodeValue: Not Found(0x8004010F)");
                    uint propertyValue = BitConverter.ToUInt32(getPropsResponseBody.PropertyValues.Value.PropertyValues[1].Value, 0);
                    this.Site.Assert.AreEqual<uint>((uint)ErrorCodeValue.NotFound, propertyValue, "The property value of AddressBookMember should be Not Found(0x8004010F), actual value is {0}", propertyValue);
                }
                else if (name.ToLower().Contains(memberName.ToLower()))
                {
                    entryId = queryRowsResponseBody.RowData[i].ValueArray[1].Value;
                }

                if (midOfModLinkAtt != 0 && entryId != null)
                {
                    break;
                }
            }

            ModLinkAttRequestBody modLinkAttRequestBody = new ModLinkAttRequestBody();
            modLinkAttRequestBody.Flags = flagsOfModLinkAtt;
            modLinkAttRequestBody.PropertyTag = propTagOfModLinkAtt;
            modLinkAttRequestBody.MinimalId = midOfModLinkAtt;
            modLinkAttRequestBody.HasEntryIds = true;
            modLinkAttRequestBody.EntryIdCount = 1;
            modLinkAttRequestBody.EntryIDs = new byte[][] { entryId };
            modLinkAttRequestBody.AuxiliaryBuffer = auxIn;
            modLinkAttRequestBody.AuxiliaryBufferSize = (uint)auxIn.Length;
            this.minimalIDForDeleteAddressBookMember = midOfModLinkAtt;
            this.entryIDBufferForDeleteAddressBookMember = entryId;
            this.isAddressBookMemberDeleted = false;

            ModLinkAttResponseBody modLinkAttResponseBodyOfAdd = this.Adapter.ModLinkAtt(modLinkAttRequestBody);
            GetPropsResponseBody getPropsResponseBodyForAddAddressBookMember = this.Adapter.GetProps(getPropsRequestBodyForAddressBookMember);
            uint modifyDisplayType = BitConverter.ToUInt32(getPropsResponseBodyForAddAddressBookMember.PropertyValues.Value.PropertyValues[0].Value, 0);
            int propertyValuelength = getPropsResponseBodyForAddAddressBookMember.PropertyValues.Value.PropertyValues[1].Value.Length;

            if (getPropsResponseBodyForAddAddressBookMember.PropertyValues.Value.PropertyValues[1].PropertyType == 0x101F)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R2257");

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R2257
                this.Site.CaptureRequirementIfIsInstanceOfType(
                getPropsResponseBodyForAddAddressBookMember.PropertyValues.Value.PropertyValues[1].HasValue,
                typeof(byte),
                2257,
                @"[In AddressBookPropertyValue Structure] HasValue (optional) (1 byte): An unsigned integer when the PropertyType ([MS-OXCDATA] section 2.11.1) is known to be PtypMultipleString ([MS-OXCDATA] section 2.11.1).");
            }
            #endregion

            #region Call ModLinkAtt to delete the specified PidTagAddressBookMember value.
            modLinkAttRequestBody.Flags = 1;
            ModLinkAttResponseBody modLinkAttResponseBodyOfDelete = this.Adapter.ModLinkAtt(modLinkAttRequestBody);
            Site.Assert.AreEqual<uint>(0, modLinkAttResponseBodyOfDelete.ErrorCode, "ModLinkAtt request should be executed successfully, the returned error code is {0}.", modLinkAttResponseBodyOfDelete.ErrorCode);
            this.isAddressBookMemberDeleted = true;
            #endregion

            #region Call Unbind request to destroy the session between the client and the server.
            this.Unbind();
            #endregion
        }
        public void MSOXCMAPIHTTP_S02_TC18_ModLinkAttRequestType()
        {
            this.CheckMapiHttpIsSupported();

            byte[] auxIn = new byte[] { };
   
            #region Call Bind request type to established a session context with the address book server.
            this.Bind();
            #endregion

            #region Call QueryRows request type to get a set of valid rows used to matched entry ID as the input paramter of ModLinkAtt method.
            STAT stat = new STAT();
            stat.InitiateStat();

            uint tableCount = 0;
            uint[] table = null;
            LargePropertyTagArray largePropTagArray = new LargePropertyTagArray()
            {
                PropertyTagCount = 4,
                PropertyTags = new PropertyTag[]
                {
                    new PropertyTag
                    {
                        PropertyType = (ushort)PropertyTypeValues.PtypString,
                        PropertyId = (ushort)PropertyID.PidTagDisplayName
                    }, 
                    new PropertyTag
                    {
                        PropertyType = (ushort)PropertyTypeValues.PtypBinary,
                        PropertyId = (ushort)PropertyID.PidTagEntryId
                    },
                    new PropertyTag
                    {
                        PropertyType = (ushort)PropertyTypeValues.PtypInteger32,
                        PropertyId = (ushort)PropertyID.PidTagDisplayType
                    },
                    new PropertyTag
                    {
                        PropertyType = (ushort)PropertyTypeValues.PtypMultipleString8,
                        PropertyId = (ushort)PropertyID.PidTagAddressBookMember
                    }
                }
            };

            QueryRowsRequestBody queryRowsRequestBody = new QueryRowsRequestBody();
            queryRowsRequestBody.Flags = (uint)RetrievePropertyFlags.fSkipObjects;
            queryRowsRequestBody.HasState = true;
            queryRowsRequestBody.State = stat;
            queryRowsRequestBody.ExplicitTableCount = tableCount;
            queryRowsRequestBody.ExplicitTable = table;
            queryRowsRequestBody.RowCount = ConstValues.QueryRowsRequestedRowNumber;
            queryRowsRequestBody.HasColumns = true;
            queryRowsRequestBody.Columns = largePropTagArray;
            queryRowsRequestBody.AuxiliaryBuffer = auxIn;
            queryRowsRequestBody.AuxiliaryBufferSize = (uint)auxIn.Length;

            QueryRowsResponseBody queryRowsResponseBody = this.Adapter.QueryRows(queryRowsRequestBody);
            Site.Assert.AreEqual<uint>(0, queryRowsResponseBody.ErrorCode, "QueryRows request should be executed successfully, the returned value {0}.", queryRowsResponseBody.ErrorCode);
            #endregion

            #region Capture code
            AddressBookPropertyRow[] rowData = queryRowsResponseBody.RowData;
            for (int i = 0; i < rowData.Length; i++)
            {
                List<AddressBookPropertyValue> valueArray = new List<AddressBookPropertyValue>(rowData[i].ValueArray);

                for (int j = 0; j < valueArray.Count; j++)
                {
                    if (largePropTagArray.PropertyTags[j].PropertyType == 0x001F)
                    {
                        // Add the debug information
                        this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R2001");

                        // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R2001
                        this.Site.CaptureRequirementIfIsInstanceOfType(
                            valueArray[j].HasValue,
                            typeof(byte),
                            2001,
                            @"[In AddressBookPropertyValue Structure] HasValue (optional) (1 byte): An unsigned integer when the PropertyType ([MS-OXCDATA] section 2.11.1) is known to be PtypString.");
                    }

                    if (largePropTagArray.PropertyTags[j].PropertyType == 0x0102)
                    {
                        // Add the debug information
                        this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R2003");

                        // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R2003
                        this.Site.CaptureRequirementIfIsInstanceOfType(
                            valueArray[j].HasValue,
                            typeof(byte),
                            2003,
                            @"[In AddressBookPropertyValue Structure] HasValue (optional) (1 byte): An unsigned integer when the PropertyType ([MS-OXCDATA] section 2.11.1) is known to be PtypBinary.");
                    }
                }
            }
            #endregion

            #region Call ModLinkAtt with flags 0x00000000 to add the specified PidTagAddressBookMember value.
            uint flagsOfModLinkAtt = 0;
            PropertyTag propTagOfModLinkAtt = new PropertyTag
            {
                PropertyType = (ushort)PropertyTypeValues.PtypEmbeddedTable,
                PropertyId = (ushort)PropertyID.PidTagAddressBookMember
            };
            uint midOfModLinkAtt = 0;
            byte[] entryId = null;
            GetPropsRequestBody getPropsRequestBodyForAddressBookMember = null;
            uint lengthOfErrorCodeValue = sizeof(uint);
            string dlistName = Common.GetConfigurationPropertyValue("DistributionListName", this.Site);
            string memberName = Common.GetConfigurationPropertyValue("GeneralUserName", this.Site);

            for (int i = 0; i < queryRowsResponseBody.RowCount; i++)
            {
                string name = System.Text.Encoding.Unicode.GetString(queryRowsResponseBody.RowData[i].ValueArray[0].Value);
                if (name.ToLower().Contains(dlistName.ToLower()))
                {
                    PermanentEntryID entryID = AdapterHelper.ParsePermanentEntryIDFromBytes(queryRowsResponseBody.RowData[i].ValueArray[1].Value);

                    DNToMinIdRequestBody requestBodyOfDNToMId = new DNToMinIdRequestBody()
                    {
                        Reserved = 0,
                        HasNames = true,
                        Names = new StringArray_r
                        {
                            CValues = 1,
                            LppzA = new string[]
                            {
                                entryID.DistinguishedName
                            }
                        },
                        AuxiliaryBuffer = auxIn,
                        AuxiliaryBufferSize = (uint)auxIn.Length
                    };
                    DnToMinIdResponseBody responseBodyOfDNToMinId = this.Adapter.DnToMinId(requestBodyOfDNToMId);
                    midOfModLinkAtt = responseBodyOfDNToMinId.MinimalIds[0];

                    stat.CurrentRec = midOfModLinkAtt;
                    STAT? statForGetProps = stat;
                    LargePropertyTagArray propertyTagForGetProps = new LargePropertyTagArray()
                    {
                        PropertyTagCount = 2,
                        PropertyTags = new PropertyTag[] 
                        {
                            new PropertyTag
                            {
                                PropertyType = (ushort)PropertyTypeValues.PtypInteger32,
                                PropertyId = (ushort)PropertyID.PidTagDisplayType
                            },
                            new PropertyTag
                            {
                                PropertyType = (ushort)PropertyTypeValues.PtypMultipleString8,
                                PropertyId = (ushort)PropertyID.PidTagAddressBookMember
                            },
                        }
                    };

                    getPropsRequestBodyForAddressBookMember = this.BuildGetPropsRequestBody((uint)0, true, statForGetProps, true, propertyTagForGetProps);
                    GetPropsResponseBody getPropsResponseBody = this.Adapter.GetProps(getPropsRequestBodyForAddressBookMember);
                    this.Site.Assert.AreEqual<uint>(0, getPropsResponseBody.StatusCode, "The GetProps request should be executed successfully, the returned status code is {0}", getPropsResponseBody.StatusCode);
                    this.Site.Assert.AreEqual<uint>(lengthOfErrorCodeValue, (uint)getPropsResponseBody.PropertyValues.Value.PropertyValues[1].Value.Length, "The length of the property value should be equal the ErrorCodeValue: Not Found(0x8004010F)");
                    uint propertyValue = BitConverter.ToUInt32(getPropsResponseBody.PropertyValues.Value.PropertyValues[1].Value, 0);
                    this.Site.Assert.AreEqual<uint>((uint)ErrorCodeValue.NotFound, propertyValue, "The property value of AddressBookMember should be Not Found(0x8004010F), actual value is {0}", propertyValue);
                }
                else if (name.ToLower().Contains(memberName.ToLower()))
                {
                    entryId = queryRowsResponseBody.RowData[i].ValueArray[1].Value;
                }

                if (midOfModLinkAtt != 0 && entryId != null)
                {
                    break;
                }
            }

            ModLinkAttRequestBody modLinkAttRequestBody = new ModLinkAttRequestBody();
            modLinkAttRequestBody.Flags = flagsOfModLinkAtt;
            modLinkAttRequestBody.PropertyTag = propTagOfModLinkAtt;
            modLinkAttRequestBody.MinimalId = midOfModLinkAtt;
            modLinkAttRequestBody.HasEntryIds = true;
            modLinkAttRequestBody.EntryIdCount = 1;
            modLinkAttRequestBody.EntryIDs = new byte[][] { entryId };
            modLinkAttRequestBody.AuxiliaryBuffer = auxIn;
            modLinkAttRequestBody.AuxiliaryBufferSize = (uint)auxIn.Length;
            this.minimalIDForDeleteAddressBookMember = midOfModLinkAtt;
            this.entryIDBufferForDeleteAddressBookMember = entryId;
            this.isAddressBookMemberDeleted = false;

            ModLinkAttResponseBody modLinkAttResponseBodyOfAdd = this.Adapter.ModLinkAtt(modLinkAttRequestBody);
            GetPropsResponseBody getPropsResponseBodyForAddAddressBookMember = this.Adapter.GetProps(getPropsRequestBodyForAddressBookMember);
            uint modifyDisplayType = BitConverter.ToUInt32(getPropsResponseBodyForAddAddressBookMember.PropertyValues.Value.PropertyValues[0].Value, 0);
            int propertyValuelength = getPropsResponseBodyForAddAddressBookMember.PropertyValues.Value.PropertyValues[1].Value.Length;

            if (getPropsResponseBodyForAddAddressBookMember.PropertyValues.Value.PropertyValues[1].PropertyType == 0x101E)
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R2258");

                // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R2258
                this.Site.CaptureRequirementIfIsInstanceOfType(
                getPropsResponseBodyForAddAddressBookMember.PropertyValues.Value.PropertyValues[1].HasValue,
                typeof(byte),
                2258,
                @"[In AddressBookPropertyValue Structure] HasValue (optional) (1 byte): An unsigned integer when the PropertyType ([MS-OXCDATA] section 2.11.1) is known to be PtypMultipleString8 ([MS-OXCDATA] section 2.11.1).");
            }

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

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R724
            this.Site.CaptureRequirementIfAreEqual<uint>(
                0,
                modLinkAttResponseBodyOfAdd.ErrorCode,
                724,
                @"[In ModLinkAtt Request Type] The ModLinkAtt request type is used by the client to modify a specific property of a row in the address book.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1333, the DisplayTypeValues should be {0}, the length of the property value was changed from {1} to {2}.", DisplayTypeValues.DT_DISTLIST.ToString(), lengthOfErrorCodeValue, propertyValuelength);

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1333
            bool isVerifiedR1333 = (modifyDisplayType == (uint)DisplayTypeValues.DT_DISTLIST) && (propertyValuelength != lengthOfErrorCodeValue);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR1333,
                1333,
                @"[In ModLinkAtt Request Type Request Body] The PidTagAddressBookMember property ([MS-OXOABK] section 2.2.6.1) can be modified on an Address Book object that has a display type of DT_DISTLIST.");
            #endregion

            #region Call ModLinkAtt to delete the specified PidTagAddressBookMember value.
            modLinkAttRequestBody.Flags = 1;
            ModLinkAttResponseBody modLinkAttResponseBodyOfDelete = this.Adapter.ModLinkAtt(modLinkAttRequestBody);
            Site.Assert.AreEqual<uint>(0, modLinkAttResponseBodyOfDelete.ErrorCode, "ModLinkAtt request should be executed successfully, the returned error code is {0}.", modLinkAttResponseBodyOfDelete.ErrorCode);
            this.isAddressBookMemberDeleted = true;
            #endregion

            #region Call ModLinkAtt with flags 0x00000002 to add the specified PidTagAddressBookMember value.
            this.Site.Assert.IsTrue(this.isAddressBookMemberDeleted, "The previous added address book member should be deleted, actual is {0}", this.isAddressBookMemberDeleted);
            modLinkAttRequestBody.Flags = 2;
            ModLinkAttResponseBody modLinkAttResponseBodyFlags2 = this.Adapter.ModLinkAtt(modLinkAttRequestBody);
            Site.Assert.AreEqual<uint>(0, modLinkAttResponseBodyFlags2.ErrorCode, "ModLinkAtt request should be executed successfully, the returned error code is {0}.", modLinkAttResponseBodyFlags2.ErrorCode);
            this.isAddressBookMemberDeleted = false;

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

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1325
            this.Site.CaptureRequirementIfAreEqual<uint>(
                modLinkAttResponseBodyFlags2.ErrorCode,
                modLinkAttResponseBodyOfAdd.ErrorCode,
                1325,
                @"[In ModLinkAtt Request Type Request Body] If this field [Flags] is set to different values other than the bit flag fDelete (0x00000001), the server will return the same result.");
            #endregion

            #region Call ModLinkAtt to delete the specified PidTagAddressBookMember value.
            modLinkAttRequestBody.Flags = 1;
            ModLinkAttResponseBody modLinkAttResponseBodyOfDeleteWithFlags2 = this.Adapter.ModLinkAtt(modLinkAttRequestBody);
            Site.Assert.AreEqual<uint>(0, modLinkAttResponseBodyOfDeleteWithFlags2.ErrorCode, "The ModLinkAtt request to delete the address book member should be executed successfully, the actual returned error code is {0}.", modLinkAttResponseBodyOfDeleteWithFlags2.ErrorCode);
            this.isAddressBookMemberDeleted = true;
            #endregion

            #region Call ModLinkAtt request to add the specified PidTagAddressBookPublicDelegates value
            midOfModLinkAtt = 0;
            entryId = null;
            GetPropsRequestBody getPropsRequestBodyForPublicDelegates = null;
            memberName = Common.GetConfigurationPropertyValue("GeneralUserName", this.Site);

            PropertyTag pidTagAddressBookPublicDelegates = new PropertyTag();
            pidTagAddressBookPublicDelegates.PropertyType = (ushort)PropertyTypeValues.PtypMultipleString8;
            pidTagAddressBookPublicDelegates.PropertyId = (ushort)PropertyID.PidTagAddressBookPublicDelegates;

            for (int i = 0; i < queryRowsResponseBody.RowCount; i++)
            {
                string name = System.Text.Encoding.Unicode.GetString(queryRowsResponseBody.RowData[i].ValueArray[0].Value);
                if (name.ToLower().Contains(memberName.ToLower()))
                {
                    PermanentEntryID entryID = AdapterHelper.ParsePermanentEntryIDFromBytes(queryRowsResponseBody.RowData[i].ValueArray[1].Value);

                    DNToMinIdRequestBody requestBodyOfDNToMId = new DNToMinIdRequestBody()
                    {
                        Reserved = 0,
                        HasNames = true,
                        Names = new StringArray_r
                        {
                            CValues = 1,
                            LppzA = new string[]
                            {
                                entryID.DistinguishedName
                            }
                        },
                        AuxiliaryBuffer = auxIn,
                        AuxiliaryBufferSize = (uint)auxIn.Length
                    };

                    DnToMinIdResponseBody responseBodyOfDNToMinId = this.Adapter.DnToMinId(requestBodyOfDNToMId);
                    midOfModLinkAtt = responseBodyOfDNToMinId.MinimalIds[0];

                    stat.CurrentRec = midOfModLinkAtt;
                    STAT? statForGetProps = stat;
                    LargePropertyTagArray propertyTagForGetProps = new LargePropertyTagArray()
                    {
                        PropertyTagCount = 2,
                        PropertyTags = new PropertyTag[] 
                        {
                            new PropertyTag
                            {
                                PropertyType = (ushort)PropertyTypeValues.PtypInteger32,
                                PropertyId = (ushort)PropertyID.PidTagDisplayType
                            },
                            new PropertyTag
                            {
                                PropertyType = (ushort)PropertyTypeValues.PtypMultipleString8,
                                PropertyId = (ushort)PropertyID.PidTagAddressBookPublicDelegates
                            },
                        }
                    };

                    getPropsRequestBodyForPublicDelegates = this.BuildGetPropsRequestBody((uint)0, true, statForGetProps, true, propertyTagForGetProps);
                    GetPropsResponseBody getPropsResponseBody = this.Adapter.GetProps(getPropsRequestBodyForPublicDelegates);
                    this.Site.Assert.AreEqual<uint>(0, getPropsResponseBody.StatusCode, "The GetProps request should be executed successfully, the returned status code is {0}", getPropsResponseBody.StatusCode);
                    this.Site.Assert.AreEqual<uint>(lengthOfErrorCodeValue, (uint)getPropsResponseBody.PropertyValues.Value.PropertyValues[1].Value.Length, "The length of the property value should be equal the ErrorCodeValue: Not Found(0x8004010F)");
                    uint propertyValue = BitConverter.ToUInt32(getPropsResponseBody.PropertyValues.Value.PropertyValues[1].Value, 0);
                    this.Site.Assert.AreEqual<uint>((uint)ErrorCodeValue.NotFound, propertyValue, "The property value of AddressBookPublicDelegates should be Not Found(0x8004010F), actual value is {0}", propertyValue);
                }
                else if (name.ToLower().Contains(this.AdminUserName.ToLower()))
                {
                    entryId = queryRowsResponseBody.RowData[i].ValueArray[1].Value;
                }

                if (midOfModLinkAtt != 0 && entryId != null)
                {
                    break;
                }
            }

            ModLinkAttRequestBody modLinkAttRequestBodyForPublicDelegates = new ModLinkAttRequestBody();
            modLinkAttRequestBodyForPublicDelegates.Flags = 0;
            modLinkAttRequestBodyForPublicDelegates.PropertyTag = pidTagAddressBookPublicDelegates;
            modLinkAttRequestBodyForPublicDelegates.MinimalId = midOfModLinkAtt;
            modLinkAttRequestBodyForPublicDelegates.HasEntryIds = true;
            modLinkAttRequestBodyForPublicDelegates.EntryIdCount = 1;
            modLinkAttRequestBodyForPublicDelegates.EntryIDs = new byte[][] { entryId };
            modLinkAttRequestBodyForPublicDelegates.AuxiliaryBuffer = auxIn;
            modLinkAttRequestBodyForPublicDelegates.AuxiliaryBufferSize = (uint)auxIn.Length;
            this.minimalIDForDeleteAddressBookPublicDelegate = midOfModLinkAtt;
            this.entryIDBufferForDeleteAddressBookPublicDelegate = entryId;
            this.isAddressBookPublicDelegateDeleted = false;

            ModLinkAttResponseBody modLinkAttResponseBodyForAddPublicDelegates = this.Adapter.ModLinkAtt(modLinkAttRequestBodyForPublicDelegates);

            GetPropsResponseBody getPropsResponseBodyForAddPublicDelegates = this.Adapter.GetProps(getPropsRequestBodyForPublicDelegates);
            modifyDisplayType = BitConverter.ToUInt32(getPropsResponseBodyForAddPublicDelegates.PropertyValues.Value.PropertyValues[0].Value, 0);
            propertyValuelength = getPropsResponseBodyForAddPublicDelegates.PropertyValues.Value.PropertyValues[1].Value.Length;

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R1335, the DisplayTypeValues should be {0}, the length of the property value was changed from {1} to {2}.", DisplayTypeValues.DT_MAILUSER.ToString(), lengthOfErrorCodeValue, propertyValuelength);

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R1335
            bool isVerifiedR1335 = (modifyDisplayType == (uint)DisplayTypeValues.DT_MAILUSER) && (propertyValuelength != lengthOfErrorCodeValue);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR1335,
                1335,
                @"[In ModLinkAtt Request Type Request Body] The PidTagAddressBookPublicDelegates property ([MS-OXOABK] section 2.2.5.5) can be modified on an Address Book object that has a display type of DT_MAILUSER.");

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMAPIHTTP_R740, the minimal ID should be {0}, the length of the property value was changed from {1} to {2}.", midOfModLinkAtt, lengthOfErrorCodeValue, propertyValuelength);

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R740
            bool isVerifiedR740 = (midOfModLinkAtt == (uint)getPropsRequestBodyForPublicDelegates.State.CurrentRec) && ((uint)propertyValuelength != lengthOfErrorCodeValue);

            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR740,
                740,
                @"[In ModLinkAtt Request Type Request Body] MinimalId (4 bytes): A MinimalEntryID structure ([MS-OXNSPI] section 2.3.8.1) that specifies the Minimal Entry ID of the address book row to be modified.");

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

            // Verify MS-OXCMAPIHTTP requirement: MS-OXCMAPIHTTP_R746, the length of the property value is different, means the property was modified.
            this.Site.CaptureRequirementIfAreNotEqual<uint>(
                lengthOfErrorCodeValue,
                (uint)propertyValuelength,
                746,
                @"[In ModLinkAtt Request Type Request Body] EntryIds: Each entry ID in the array specifies an address book row in which the specified property is to be modified.");
            #endregion

            #region Call ModLinkAtt request to delete the specified PidTagAddressBookPublicDelegates value
            modLinkAttRequestBodyForPublicDelegates.Flags = 1;
            ModLinkAttResponseBody modLinkAttResponseBodyForDeletePublicDelegates = this.Adapter.ModLinkAtt(modLinkAttRequestBodyForPublicDelegates);
            this.Site.Assert.AreEqual<uint>((uint)0, modLinkAttResponseBodyForDeletePublicDelegates.ErrorCode, "The ModLinkAtt request to delete address book public delegates should be executed successfully, the returned value is {0}", modLinkAttResponseBodyForDeletePublicDelegates.ErrorCode);
            this.isAddressBookPublicDelegateDeleted = true;
            #endregion

            #region Call Unbind request to destroy the session between the client and the server.
            this.Unbind();
            #endregion
        }
        /// <summary>
        /// This method is used by the client to get a number of rows from the specified Explicit Table.
        /// </summary>
        /// <param name="queryRowsRequestBody">The QueryRows request type request body.</param>
        /// <returns>The response body of QueryRows request type</returns>
        public QueryRowsResponseBody QueryRows(QueryRowsRequestBody queryRowsRequestBody)
        {
            CommonResponse commonResponse = this.SendAddressBookRequest(queryRowsRequestBody, RequestType.QueryRows);
            QueryRowsResponseBody queryRowsResponseBody = QueryRowsResponseBody.Parse(commonResponse.ResponseBodyRawData);

            this.VerifyQueryRowsResponseBody(queryRowsResponseBody, queryRowsRequestBody);
            if (queryRowsResponseBody.HasColumnsAndRows)
            {
                foreach (AddressBookPropertyRow row in queryRowsResponseBody.RowData)
                {
                    this.VerifyAddressBookPropertyRowStructure(row);
                   
                    if (row.Flag == 0x0)
                    {
                        for (int i = 0; i < row.ValueArray.Length; i++)
                        {
                            if (queryRowsRequestBody.Columns.PropertyTags[i].PropertyType != 0x0000)
                            {
                                this.VerifyAddressBookPropertyValueStructure(row.ValueArray[i]);
                            }
                        }
                    }
                    else
                    {
                        for (int j = 0; j < row.ValueArray.Length; j++)
                        {
                            this.VerifyAddressBookFlaggedPropertyValueStructure((AddressBookFlaggedPropertyValue)row.ValueArray[j]);
                        }
                    }
                }

                this.VerifyLargePropertyTagArrayStructure(queryRowsResponseBody.Columns.Value);
            }
            
            return queryRowsResponseBody;
        }