/// <summary>
        /// Verify if the asynchronous ROP is complete
        /// </summary>
        /// <param name="getStatusResponse">RopGetStatusResponse structure data that needs verification</param>
        private void VerifyAsynchronousROPComplete(RopGetStatusResponse getStatusResponse)
        {
            if (Common.IsRequirementEnabled(891, this.Site))
            {
                if (this.globalIsRestrictAsynchronous || this.globalIsSortTableAsynchronous || this.globalIsSetColumnsAsynchronous)
                {
                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCTABL_R891");

                    // Verify MS-OXCTABL requirement: MS-OXCTABL_R891
                    // TableStatus in response with value 0x00 means the ROP is finished  
                    Site.CaptureRequirementIfAreEqual<byte>(
                        0x00,
                        getStatusResponse.TableStatus,
                        891,
                        @"[In Appendix A: Product Behavior] The RopGetStatus ROP of the implementation ([MS-OXCROPS] section 2.2.5.6) MUST send TBLSTAT_COMPLETE when the current asynchronous was finished on the table in the response, as specified in section 3.2.5.1. (Microsoft Exchange Server 2007 follows this behavior.)");
                }
            }
        }
        /// <summary>
        /// Verify GetStatus Response
        /// </summary>
        /// <param name="getStatusResponse">RopGetStatusResponse structure data that needs verification</param>
        private void VerifyGetStatusResponse(RopGetStatusResponse getStatusResponse)
        {
            this.VerifyRPCLayerRequirement();

            if (Common.IsRequirementEnabled(792, this.Site))
            {
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCTABL_R792");

                // Verify MS-OXCTABL requirement: MS-OXCTABL_R792
                Site.CaptureRequirementIfAreEqual<Type>(
                    typeof(byte),
                    getStatusResponse.TableStatus.GetType(),
                    792,
                    @"[In Appendix A: Product Behavior] TableStatus (1 byte): An enumeration that indicates the status of asynchronous operations being performed on the table on the implementation. (Microsoft Exchange Server 2007 follows this behavior.)");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCTABL_R132: the value of the TableStatus field in the response for RopGetStatus is set to {0}", getStatusResponse.TableStatus);

                // Verify MS-OXCTABL requirement: MS-OXCTABL_R132
                bool isVerifyR132 = (getStatusResponse.TableStatus == 0x00) ||
                                    (getStatusResponse.TableStatus == 0x09) ||
                                    (getStatusResponse.TableStatus == 0x0A) ||
                                    (getStatusResponse.TableStatus == 0x0B) ||
                                    (getStatusResponse.TableStatus == 0x0D) ||
                                    (getStatusResponse.TableStatus == 0x0E) ||
                                    (getStatusResponse.TableStatus == 0x0F);

                Site.CaptureRequirementIfIsTrue(
                    isVerifyR132,
                    132,
                    @"[In RopGetStatus ROP Response Buffer] Its [TableStatus'] value MUST be one of the table status values [0x00,0x09,0x0A,0x0B,0x0D,0x0E,0x0F] that are specified in section 2.2.2.1.3.");
            }
        }
        /// <summary>
        /// Verify RopGetStatus Failure Response
        /// </summary>
        /// <param name="ropGetStatusResponse">The response of RopGetStatus request</param>
        /// <param name="inputHandleIndex">The field of InputHandleIndex in RopGetStatus request</param>
        private void VerifyRopGetStatusFailureResponse(RopGetStatusResponse ropGetStatusResponse, byte inputHandleIndex)
        {
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R1250");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1250
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropGetStatusResponse.RopId.GetType(),
                1250,
                @"[In RopGetStatus ROP Failure Response Buffer] RopId (1 byte): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1252
            Site.CaptureRequirementIfAreEqual<byte>(
                (byte)RopId.RopGetStatus,
                ropGetStatusResponse.RopId,
                1252,
                @"[In RopGetStatus ROP Failure Response Buffer] RopId (1 byte): For this operation[RopGetStatus], this field is set to 0x16.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1253
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropGetStatusResponse.InputHandleIndex.GetType(),
                1253,
                @"[In RopGetStatus ROP Failure Response Buffer] InputHandleIndex (1 byte): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1254
            Site.CaptureRequirementIfAreEqual<byte>(
                inputHandleIndex,
                ropGetStatusResponse.InputHandleIndex,
                1254,
                @"[In RopGetStatus ROP Failure Response Buffer] InputHandleIndex (1 byte): This index MUST be set to the value specified in the InputHandleIndex field in the request.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1255
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(uint),
                ropGetStatusResponse.ReturnValue.GetType(),
                1255,
                @"[In RopGetStatus ROP Failure Response Buffer] ReturnValue (4 bytes): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1257
            Site.CaptureRequirementIfAreNotEqual<uint>(
                SuccessReturnValue,
                ropGetStatusResponse.ReturnValue,
                1257,
                @"[In RopGetStatus ROP Failure Response Buffer] ReturnValue (4 bytes): For this response[Failure Response], this field is set to a value other than 0x00000000.");
        }
        /// <summary>
        /// Verify RopGetStatus Success Response
        /// </summary>
        /// <param name="ropGetStatusResponse">The response of RopGetStatus request</param>
        /// <param name="inputHandleIndex">The field of InputHandleIndex in RopGetStatus request</param>
        private void VerifyRopGetStatusSuccessResponse(RopGetStatusResponse ropGetStatusResponse, byte inputHandleIndex)
        {
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R1239");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1239
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropGetStatusResponse.RopId.GetType(),
                1239,
                @"[In RopGetStatus ROP Success Response Buffer] RopId (1 byte): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1241
            Site.CaptureRequirementIfAreEqual<byte>(
                (byte)RopId.RopGetStatus,
                ropGetStatusResponse.RopId,
                1241,
                @"[In RopGetStatus ROP Success Response Buffer] RopId (1 byte): For this operation[RopGetStatus], this field[RopId (1 byte)] is set to 0x16.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1242
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropGetStatusResponse.InputHandleIndex.GetType(),
                1242,
                @"[In RopGetStatus ROP Success Response Buffer] InputHandleIndex (1 byte): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1243
            Site.CaptureRequirementIfAreEqual<byte>(
                inputHandleIndex,
                ropGetStatusResponse.InputHandleIndex,
                1243,
                @"[In RopGetStatus ROP Success Response Buffer] InputHandleIndex (1 byte): This index MUST be set to the value specified in the InputHandleIndex field in the request.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1244
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(uint),
                ropGetStatusResponse.ReturnValue.GetType(),
                1244,
                @"[In RopGetStatus ROP Success Response Buffer] ReturnValue (4 bytes): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1246
            Site.CaptureRequirementIfAreEqual<uint>(
                SuccessReturnValue,
                ropGetStatusResponse.ReturnValue,
                1246,
                @"[In RopGetStatus ROP Success Response Buffer] ReturnValue (4 bytes): For this response[Success Response], this field is set to 0x00000000.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1247
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropGetStatusResponse.TableStatus.GetType(),
                1247,
                @"[In RopGetStatus ROP Success Response Buffer] TableStatus (1 byte): An enumeration.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R1248,TableStatus:{0}", ropGetStatusResponse.TableStatus);

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R1248
            bool isVerifyR1248 = ((ropGetStatusResponse.TableStatus & ((byte)TableStatus.TblstatComplete)) == ((byte)TableStatus.TblstatComplete))
                                 || ((ropGetStatusResponse.TableStatus & ((byte)TableStatus.TblstatSorting)) == ((byte)TableStatus.TblstatSorting))
                                 || ((ropGetStatusResponse.TableStatus & ((byte)TableStatus.TblstatSortError)) == ((byte)TableStatus.TblstatSortError))
                                 || ((ropGetStatusResponse.TableStatus & ((byte)TableStatus.TblstatSettingCols)) == ((byte)TableStatus.TblstatSettingCols))
                                 || ((ropGetStatusResponse.TableStatus & ((byte)TableStatus.TblstatSetColError)) == ((byte)TableStatus.TblstatSetColError))
                                 || ((ropGetStatusResponse.TableStatus & ((byte)TableStatus.TblstatRestricting)) == ((byte)TableStatus.TblstatRestricting))
                                 || ((ropGetStatusResponse.TableStatus & ((byte)TableStatus.TblstatRestrictError)) == ((byte)TableStatus.TblstatRestrictError));

            Site.CaptureRequirementIfIsTrue(
                isVerifyR1248,
                1248,
                @"[In RopGetStatus ROP Success Response Buffer] TableStatus (1 byte): The possible values[the value of TBLSTAT_COMPLETE is 0x00, the value of TBLSTAT_SORTING is 0x09, the value of TBLSTAT_SORT_ERROR is 0x0A, the value of TBLSTAT_SETTING_COLS is 0x0B, the value of TBLSTAT_SETCOL_ERROR is 0x0D, the value of TBLSTAT_RESTRICTING is 0x0E and the value of TBLSTAT_RESTRICT_ERROR is 0x0F] for this enumeration are specified in [MS-OXCTABL] section 2.2.2.1.3.");
        }
        /// <summary>
        /// This method is used to restrict for a table
        /// </summary>
        /// <param name="reqId">Identify the request ID</param>
        /// <param name="validHandle">Identify whether the InputHandleIndex is valid, this is used to trigger the error code in Restrict</param>
        /// <param name="newRestrict">A identify whether new restriction is required</param>
        /// <param name="isRestrictAsynchronous">Indicate whether RopRestrict Rop is to be performed asynchronously</param>
        /// <returns>Table ROP return value</returns>
        public TableRopReturnValues RopRestrict(uint reqId, bool validHandle, bool newRestrict, bool isRestrictAsynchronous)
        {
            RopRestrictRequest restrictRequest;
            RopRestrictResponse restrictResponse;

            restrictRequest.RopId = 0x14;
            restrictRequest.LogonId = 0x00;
            restrictRequest.InputHandleIndex = (byte)0x00; 
            if (isRestrictAsynchronous)
            {
                restrictRequest.RestrictFlags = 0x01; // Async
            }
            else
            {
                restrictRequest.RestrictFlags = 0x00; // Sync
            }

            this.globalIsRestrictAsynchronous = isRestrictAsynchronous;
            byte[] data;
            if (this.tableType == TableType.CONTENT_TABLE)
            {
                if (!newRestrict && this.sign)
                {
                    byte[] tempData = Encoding.Unicode.GetBytes(Common.GetConfigurationPropertyValue("Sender1Name", this.Site) + "\0");
                    data = new byte[tempData.Length + 13];
                    int index = 0;
                    data[index++] = 0x03;
                    data[index++] = 0x02;
                    data[index++] = 0x00;
                    data[index++] = 0x04;
                    data[index++] = 0x00;
                    data[index++] = 0x1f;
                    data[index++] = 0x00;
                    data[index++] = 0x1a;
                    data[index++] = 0x0c;
                    data[index++] = 0x1f;
                    data[index++] = 0x00;
                    data[index++] = 0x1a;
                    data[index++] = 0x0c;
                    Array.Copy(tempData, 0, data, index, tempData.Length);

                    this.latestRestrict = RestrictFlag.SenderIsTest1Restrict;
                }
                else
                {
                    byte[] tempData = Encoding.Unicode.GetBytes(Common.GetConfigurationPropertyValue("Sender2Name", this.Site) + "\0");
                    data = new byte[tempData.Length + 13];
                    int index = 0;
                    data[index++] = 0x03;
                    data[index++] = 0x02;
                    data[index++] = 0x00;
                    data[index++] = 0x04;
                    data[index++] = 0x00;
                    data[index++] = 0x1f;
                    data[index++] = 0x00;
                    data[index++] = 0x1a;
                    data[index++] = 0x0c;
                    data[index++] = 0x1f;
                    data[index++] = 0x00;
                    data[index++] = 0x1a;
                    data[index++] = 0x0c;
                    Array.Copy(tempData, 0, data, index, tempData.Length);

                    this.latestRestrict = RestrictFlag.SenderIsTest2Restriction;
                }

                this.sign = this.sign == !newRestrict;
            }
            else if (this.tableType == TableType.HIERARCHY_TABLE || this.tableType == TableType.RULES_TABLE)
            {
                data = AdapterHelper.GenerateValidRestrictData(this.Site, this.tableType);
            }
            else
            {
                data = null;
            }

            restrictRequest.RestrictionDataSize = data == null ? (ushort)0 : (ushort)data.Length;
            restrictRequest.RestrictionData = data;

            uint inputObjHandle;
            if (validHandle)
            {
                inputObjHandle = this.tableHandle;
            }
            else
            {
                inputObjHandle = 0xFFFFFFFF; // Cause the request failed when set to invalid handle
            }

            this.DoSingleCallROP(restrictRequest, inputObjHandle, ref this.response, ref this.rawData);
            restrictResponse = (RopRestrictResponse)this.response;

            this.ropType = TableRopType.RESTRICT;

            if ((TableRopReturnValues)restrictResponse.ReturnValue == TableRopReturnValues.success)
            {
                this.latestSuccessRestrict = this.latestRestrict;

                this.GetRowsCount(false);
            }

            // If the RopRestrict ROP is not complete (the returned TableStatus is set to 0x0E), wait for the RopGetStatus ROP to return TableStatus set 0x00 (which indicates the RopRestrict ROP is complete).
            if ((TableRopReturnValues)restrictResponse.ReturnValue == TableRopReturnValues.success && isRestrictAsynchronous && (TableStatus)restrictResponse.TableStatus == TableStatus.TblstatRestricting)
            {
                int getStatusRetryCount = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));
                RopGetStatusResponse getStatusResponse = new RopGetStatusResponse();
                while (getStatusRetryCount >= 0)
                {
                    Thread.Sleep(this.waitTime);
                    TableStatus tableStatus;
                    this.RopGetStatus(out tableStatus);
                    if (tableStatus == TableStatus.TblstatComplete)
                    {
                        break;
                    }

                    getStatusRetryCount--;
                }

                if (getStatusRetryCount < 0)
                {
                    Site.Assert.Fail("The RopRestrict ROP should complete!");
                }

                this.VerifyAsynchronousROPComplete(getStatusResponse);
            }

            return (TableRopReturnValues)restrictResponse.ReturnValue;
        }
        /// <summary>
        /// This method is used to sort table
        /// </summary>
        /// <param name="reqId">Identify the request ID</param>
        /// <param name="validHandle">Identify whether the InputHandleIndex is valid, this is used to trigger the error code in sort table</param>
        /// <param name="multipleSortOrders">Indicate whether the sort order array contains more than one SortOrder structure</param>
        /// <param name="isMaximumCategory">Indicate whether the sort order array contains a SortOrder structure with the order set to MaximumCategory</param>
        /// <param name="allSortOrdersUsedAsCategory">Identify whether all sort orders used as category</param>
        /// <param name="allCategoryExpanded">Identify whether all categories are expanded</param>
        /// <param name="newOrder">Identify whether to change the current sort order</param>
        /// <param name="isSortTableAsynchronous">Indicate whether RopSortTable Rop is to be performed asynchronously</param>
        /// <returns>Table ROP return value</returns>
        public TableRopReturnValues RopSortTable(uint reqId, bool validHandle, bool multipleSortOrders, bool isMaximumCategory, bool allSortOrdersUsedAsCategory, bool allCategoryExpanded, bool newOrder, bool isSortTableAsynchronous)
        {
            RopSortTableRequest sortTableRequest;
            RopSortTableResponse sortTableResponse;
            SortOrder[] sortOrders;

            if (!newOrder && this.sign)
            {
                sortOrders = this.CreateSampleSortOrdersAscending(multipleSortOrders, isMaximumCategory);
            }
            else
            {
                sortOrders = this.CreateSampleSortOrdersDescending(multipleSortOrders);
            }

            this.sign = this.sign == !newOrder;
            this.latestSortOrder = sortOrders[0].Order == 0x00 ? SortOrderFlag.SortOrderASC : SortOrderFlag.SortOrderDESC;
            sortTableRequest.RopId = 0x13;
            sortTableRequest.LogonId = 0x00;
            sortTableRequest.InputHandleIndex = (byte)0x00; 
            this.areAllSortOrdersUsedAsCategory = allSortOrdersUsedAsCategory;
            this.areAllCategoryExpanded = allCategoryExpanded;
            this.areMultipleSortOrders = multipleSortOrders;
            sortTableRequest.SortOrderCount = (ushort)sortOrders.Length;
            if (allSortOrdersUsedAsCategory)
            {
                sortTableRequest.CategoryCount = (ushort)sortOrders.Length;
                if (allCategoryExpanded)
                {
                    sortTableRequest.ExpandedCount = (ushort)sortOrders.Length; // All rows expanded
                }
                else
                {
                    sortTableRequest.ExpandedCount = (ushort)(sortOrders.Length - 1); // Not all rows expanded
                }
            }
            else
            {
                sortTableRequest.CategoryCount = (ushort)(sortOrders.Length - 1);
                if (allCategoryExpanded)
                {
                    sortTableRequest.ExpandedCount = (ushort)(sortOrders.Length - 1); // All rows expanded
                }
                else
                {
                    sortTableRequest.ExpandedCount = 0;
                }
            }

            sortTableRequest.SortOrders = sortOrders;
            if (isSortTableAsynchronous)
            {
                sortTableRequest.SortTableFlags = 0x01; // Async
            }
            else
            {
                sortTableRequest.SortTableFlags = 0x00; // Sync
            }

            uint inputObjHandle;
            if (validHandle)
            {
                inputObjHandle = this.tableHandle;
            }
            else
            {
                inputObjHandle = 0xFFFFFFFF; // Cause the request failed when set to invalid handle
            }

            this.globalIsSortTableAsynchronous = isSortTableAsynchronous;
            this.DoSingleCallROP(sortTableRequest, inputObjHandle, ref this.response, ref this.rawData);
            sortTableResponse = (RopSortTableResponse)this.response;

            this.ropType = TableRopType.SORTTABLE;

            if ((TableRopReturnValues)sortTableResponse.ReturnValue == TableRopReturnValues.success)
            {
                this.latestSuccessSortOrder = this.latestSortOrder;
                if (sortTableRequest.ExpandedCount != 0)
                {
                    this.isExpanded = true; // The first header row is expanded when the request succeeds.
                }

                this.GetRowsCount(false); // Update the field rowCount
            }

            // If the RopSortTable ROP is not complete (the returned TableStatus is set to 0x09), wait for the RopGetStatus ROP to return TableStatus set 0x00 (which indicates the RopSortTable ROP is complete).
            if ((TableRopReturnValues)sortTableResponse.ReturnValue == TableRopReturnValues.success && isSortTableAsynchronous && (TableStatus)sortTableResponse.TableStatus == TableStatus.TblstatSorting)
            {
                int getStatusRetryCount = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));
                RopGetStatusResponse getStatusResponse = new RopGetStatusResponse();
                while (getStatusRetryCount >= 0)
                {
                    Thread.Sleep(this.waitTime);
                    TableStatus tableStatus;
                    this.RopGetStatus(out tableStatus);
                    if (tableStatus == TableStatus.TblstatComplete)
                    {
                        break;
                    }

                    getStatusRetryCount--;
                }

                if (getStatusRetryCount < 0)
                {
                    Site.Assert.Fail("The RopSortTable ROP should complete!");
                }

                this.VerifyAsynchronousROPComplete(getStatusResponse);
            }

            return (TableRopReturnValues)sortTableResponse.ReturnValue;
        }
        /// <summary>
        /// This method is used to SetColumns for a table
        /// </summary>
        /// <param name="reqId">Identify the request ID</param>
        /// <param name="invalidPropertyTag">Indicate whether there are invalid property tags in the column set </param>
        /// <param name="newColumnSet">Indicate whether to change the current column set with new one</param>
        /// <param name="isSetColumnsAsynchronous">Indicate whether RopsetColumns Rop is to be performed asynchronously</param>
        /// <returns>Table ROP return value</returns>
        public TableRopReturnValues RopSetColumns(uint reqId, bool invalidPropertyTag, bool newColumnSet, bool isSetColumnsAsynchronous)
        {
            RopSetColumnsRequest setColumnsRequest;
            RopSetColumnsResponse setColumnsResponse;
            PropertyTag[] propertyTags;

            if (invalidPropertyTag)
            {
                propertyTags = this.CreateInvalidContentsTablePropertyTags();
            }
            else
            {
                switch (this.tableType)
                {
                    case TableType.CONTENT_TABLE:
                        if (!newColumnSet && this.sign)
                        {
                            propertyTags = this.CreateSampleContentsTablePropertyTags();
                        }
                        else
                        {
                            propertyTags = this.CreateSampleContentsTablePropertyTagsWithNoError();
                        }

                        break;
                    case TableType.HIERARCHY_TABLE:
                        propertyTags = this.CreateSampleHierarchyTablePropertyTags();
                        break;
                    case TableType.RULES_TABLE:
                        propertyTags = this.CreateRulesTablePropertyTags();
                        break;
                    default:
                        propertyTags = this.CreateSampleContentsTablePropertyTags();
                        break;
                }

                this.sign = this.sign == !newColumnSet;
            }

            setColumnsRequest.RopId = 0x12;
            setColumnsRequest.LogonId = 0x00;
            setColumnsRequest.InputHandleIndex = 0x00;
            setColumnsRequest.PropertyTagCount = (ushort)propertyTags.Length;
            setColumnsRequest.PropertyTags = propertyTags;
            if (isSetColumnsAsynchronous)
            {
                setColumnsRequest.SetColumnsFlags = 0x01; // Async
            }
            else
            {
                setColumnsRequest.SetColumnsFlags = 0x00; // Sync
            }

            this.globalIsSetColumnsAsynchronous = isSetColumnsAsynchronous;
            this.DoSingleCallROP(setColumnsRequest, this.tableHandle, ref this.response, ref this.rawData);
            setColumnsResponse = (RopSetColumnsResponse)this.response;

            this.ropType = TableRopType.SETCOLUMNS;
            this.latestPropertyTags = propertyTags;
            if ((TableRopReturnValues)setColumnsResponse.ReturnValue == TableRopReturnValues.success)
            {
                this.latestSuccessPropertyTages = propertyTags;
            }

            // If the RopSetColumns ROP is not complete (the returned TableStatus is set to 0x0B), wait for the RopGetStatus ROP to return TableStatus set 0x00 (which indicates the RopSetColumns ROP is complete).
            if ((TableRopReturnValues)setColumnsResponse.ReturnValue == TableRopReturnValues.success && isSetColumnsAsynchronous && (TableStatus)setColumnsResponse.TableStatus == TableStatus.TblstatSettingCols)
            {
                int getStatusRetryCount = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));
                RopGetStatusResponse getStatusResponse = new RopGetStatusResponse();
                while (getStatusRetryCount >= 0)
                {
                    Thread.Sleep(this.waitTime);
                    TableStatus tableStatus;
                    this.RopGetStatus(out tableStatus);
                    if (tableStatus == TableStatus.TblstatComplete)
                    {
                        break;
                    }

                    getStatusRetryCount--;
                }

                if (getStatusRetryCount < 0)
                {
                    Site.Assert.Fail("The RopSetColumns ROP should complete!");
                }

                this.VerifyAsynchronousROPComplete(getStatusResponse);
            }

            return (TableRopReturnValues)setColumnsResponse.ReturnValue;
        }