The ContentRestriction structure.
Inheritance: Restriction
Example #1
0
        /// <summary>
        /// Deserialize the common field of restriction.
        /// </summary>
        /// <param name="restrictionData">The restriction data.</param>
        /// <returns>Return a new instance of a class extended from Restricts.</returns>
        public static Restriction Deserialize(byte[] restrictionData)
        {
            Restriction restricts    = null;
            int         index        = 0;
            byte        restrictType = restrictionData[index];

            switch (restrictType)
            {
            case (byte)RestrictType.AndRestriction:
                AndRestriction andRestriction = new AndRestriction();
                andRestriction.Deserialize(restrictionData);
                restricts = andRestriction;
                break;

            case (byte)RestrictType.NotRestriction:
                NotRestriction notRestriction = new NotRestriction();
                notRestriction.Deserialize(restrictionData);
                restricts = notRestriction;
                break;

            case (byte)RestrictType.ContentRestriction:
                ContentRestriction contentRestriction = new ContentRestriction();
                contentRestriction.Deserialize(restrictionData);
                restricts = contentRestriction;
                break;

            case (byte)RestrictType.PropertyRestriction:
                PropertyRestriction propertyRestriction = new PropertyRestriction();
                propertyRestriction.Deserialize(restrictionData);
                restricts = propertyRestriction;
                break;

            case (byte)RestrictType.ExistRestriction:
                ExistRestriction existRestriction = new ExistRestriction();
                existRestriction.Deserialize(restrictionData);
                restricts = existRestriction;
                break;

            default:
                throw new NotSupportedException("This restrict type '" + restrictType.ToString() + "'is not supported in this test suite.");
            }

            return(restricts);
        }
        /// <summary>
        /// Deserialize the common field of restriction.
        /// </summary>
        /// <param name="restrictionData">The restriction data.</param>
        /// <returns>Return a new instance of a class extended from Restricts.</returns>
        public static Restriction Deserialize(byte[] restrictionData)
        {
            Restriction restricts = null;
            int index = 0;
            byte restrictType = restrictionData[index];
            switch (restrictType)
            {
                case (byte)RestrictType.AndRestriction:
                    AndRestriction andRestriction = new AndRestriction();
                    andRestriction.Deserialize(restrictionData);
                    restricts = andRestriction;
                    break;
                case (byte)RestrictType.NotRestriction:
                    NotRestriction notRestriction = new NotRestriction();
                    notRestriction.Deserialize(restrictionData);
                    restricts = notRestriction;
                    break;
                case (byte)RestrictType.ContentRestriction:
                    ContentRestriction contentRestriction = new ContentRestriction();
                    contentRestriction.Deserialize(restrictionData);
                    restricts = contentRestriction;
                    break;
                case (byte)RestrictType.PropertyRestriction:
                    PropertyRestriction propertyRestriction = new PropertyRestriction();
                    propertyRestriction.Deserialize(restrictionData);
                    restricts = propertyRestriction;
                    break;
                case (byte)RestrictType.ExistRestriction:
                    ExistRestriction existRestriction = new ExistRestriction();
                    existRestriction.Deserialize(restrictionData);
                    restricts = existRestriction;
                    break;
                default:
                    throw new NotSupportedException("This restrict type '" + restrictType.ToString() + "'is not supported in this test suite.");
            }

            return restricts;
        }
        public void MSOXCFOLD_S03_TC01_StaticSearchVerification()
        {
            this.CheckWhetherSupportTransport();
            this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer);
            this.GenericFolderInitialization();

            #region Step 1. The client calls RopCreateFolder to create the general folder [MSOXCFOLDSubfolder1] under the root folder.

            RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest
            {
                RopId = (byte)RopId.RopCreateFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                FolderType = (byte)FolderType.Genericfolder,
                UseUnicodeStrings = 0x0,
                OpenExisting = 0x00,
                Reserved = 0x0,
                DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder1),
                Comment = Encoding.ASCII.GetBytes(Constants.Subfolder1)
            };
            RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!");
            uint subfolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex];
            ulong subfolderId1 = createFolderResponse.FolderId;

            #endregion

            #region Step 2. The client creates two general messages under the folder [MSOXCFOLDSubfolder1].

            uint messageHandle1 = 0;
            ulong messageId1 = 0;
            this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageId1, ref messageHandle1);

            uint messageHandle2 = 0;
            ulong messageId2 = 0;
            this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageId2, ref messageHandle2);
            #endregion

            #region Step 3. The client calls RopCreateFolder to create the search folder [MSOXCFOLDSearchFolder2] under the root folder.

            createFolderRequest.FolderType = (byte)FolderType.Searchfolder;
            createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.SearchFolder2);
            createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.SearchFolder2);
            createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!");
            uint searchFolderHandle2 = this.responseHandles[0][createFolderResponse.OutputHandleIndex];
            #endregion

            #region Step 4. The client calls RopSetSearchCriteria to establish search criteria for [MSOXCFOLDSearchFolder2].

            RopSetSearchCriteriaRequest setSearchCriteriaRequest = new RopSetSearchCriteriaRequest
            {
                RopId = (byte)RopId.RopSetSearchCriteria,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex
            };
            PropertyTag propertyTag = new PropertyTag
            {
                PropertyId = (ushort)MessagePropertyId.PidTagMessageClass,
                PropertyType = (ushort)PropertyType.PtypString
            };
            ExistRestriction existRestriction = new ExistRestriction
            {
                PropTag = propertyTag
            };
            setSearchCriteriaRequest.RestrictionDataSize = (ushort)existRestriction.Size();
            setSearchCriteriaRequest.RestrictionData = existRestriction.Serialize();
            setSearchCriteriaRequest.FolderIds = new ulong[] { subfolderId1 };
            setSearchCriteriaRequest.FolderIdCount = (ushort)setSearchCriteriaRequest.FolderIds.Length;
            setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.ContentIndexedSearch | (uint)SetSearchFlags.StaticSearch | (uint)SetSearchFlags.RestartSearch;
            RopSetSearchCriteriaResponse setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle2, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!");

            #endregion

            #region Step 5. The client calls RopGetSearchCriteria to obtain the search criteria and the status of the search folder [MSOXCFOLDSearchFolder2].
            RopGetSearchCriteriaRequest getSearchCriteriaRequest = new RopGetSearchCriteriaRequest
            {
                RopId = (byte)RopId.RopGetSearchCriteria,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                UseUnicode = 0x00,
                IncludeRestriction = 0x01,
                IncludeFolders = 0x01
            };
            RopGetSearchCriteriaResponse getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle2, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!");

            #region Verify the requirements: MS-OXCFOLD_R1200 and MS-OXCFOLD_R1233.
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1200");

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1200
            // SHALLOW_SEARCH bit in the RopSetSearchCriteria ROP request means the search includes only the search folder containers that are specified in the FolderIds field.
            // If the bit SEARCH_RECURSIVE in the RopGetSearchCriteria ROP response is not set means only the search folder containers that are specified in the last RopSetSearchCriteria ROP request are being searched.
            // So, if the bit SEARCH_RECURSIVE in getSearchCriteriaResponse is not set, R1200 can be verified. 
            Site.CaptureRequirementIfAreNotEqual<uint>(
                (uint)GetSearchFlags.Recursive,
                getSearchCriteriaResponse.SearchFlags & (uint)GetSearchFlags.Recursive,
                1200,
                @"[In RopSetSearchCriteria ROP Request Buffer] SearchFlags (4 bytes): If neither bit [RECURSIVE_SEARCH or SHALLOW_SEARCH] is set, the default is SHALLOW_SEARCH.");

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

            List<ulong> folderIdsInGetSearchCriteriaResponse = new List<ulong>();
            folderIdsInGetSearchCriteriaResponse.AddRange(getSearchCriteriaResponse.FolderIds);

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1233
            this.Site.CaptureRequirementIfIsFalse(
                folderIdsInGetSearchCriteriaResponse.Contains(createFolderResponse.FolderId),
                1233,
                @"[In Setting Up a Search Folder] [A search folder cannot be included in its own search scope] Therefore, the FolderIds field MUST NOT include the FID of the search folder.");
            #endregion

            #endregion

            #region Step 6. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder2].
            RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest();
            RopGetContentsTableResponse getContentsTableResponse;
            getContentsTableRequest.RopId = (byte)RopId.RopGetContentsTable;
            getContentsTableRequest.LogonId = Constants.CommonLogonId;
            getContentsTableRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
            getContentsTableRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex;
            getContentsTableRequest.TableFlags = (byte)FolderTableFlags.None;

            int count = 0;
            do
            {
                getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle2, ref this.responseHandles);
                Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!");
                if (getContentsTableResponse.RowCount != 2)
                {
                    Thread.Sleep(this.WaitTime);
                }
                else
                {
                    break;
                }

                count++;
            }
            while (count < this.RetryCount);

            uint rowCountBeforeHardDel = getContentsTableResponse.RowCount;
            Site.Assert.AreEqual<uint>(2, rowCountBeforeHardDel, "The two general messages created in step 2 were fetched in search folder.");

            #endregion

            #region Step 7. The client calls RopHardDeleteMessage ROP operation to hard delete a message in the general folder [MSOXCFOLDSubfolder1] under the root folder.

            ulong[] messageIds = new ulong[] { messageId1 };
            RopHardDeleteMessagesRequest hardDeleteMessagesRequest = new RopHardDeleteMessagesRequest
            {
                RopId = (byte)RopId.RopHardDeleteMessages,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                WantAsynchronous = 0x00,
                NotifyNonRead = 0x00,
                MessageIdCount = (ushort)messageIds.Length,
                MessageIds = messageIds
            };
            RopHardDeleteMessagesResponse hardDeleteMessagesResponse = this.Adapter.HardDeleteMessages(hardDeleteMessagesRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, hardDeleteMessagesResponse.ReturnValue, "RopHardDeleteMessages ROP operation performs successfully!");
            Site.Assert.AreEqual<uint>(0x00, hardDeleteMessagesResponse.PartialCompletion, "RopHardDeleteMessages ROP operation is complete!");

            #endregion

            #region Step 8. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder2].

            count = 0;
            bool searchFolderNotChange = false;
            do
            {
                getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle2, ref this.responseHandles);
                Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!");
                if (getContentsTableResponse.RowCount != rowCountBeforeHardDel)
                {
                    Thread.Sleep(this.WaitTime);
                }
                else
                {
                    searchFolderNotChange = true;
                    break;
                }

                count++;
            }
            while (count < this.RetryCount);

            #region Verify the requirements: MS-OXCFOLD_R795, MS-OXCFOLD_R784, MS-OXCFOLD_R1084, MS-OXCFOLD_R549, MS-OXCFOLD_R1093, MS-OXCFOLD_R1094.

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R795
            // The search folder contents didn't change after the message has been hard deleted, it indicates the current search is static search.
            Site.CaptureRequirementIfIsTrue(
                searchFolderNotChange,
                795,
                @"[In RopGetSearchCriteria ROP Response Buffer] SearchFlags (4 bytes): SEARCH_STATIC (0x00010000) means that the search is static.");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R784
            Site.CaptureRequirementIfIsTrue(
                searchFolderNotChange,
                784,
                @"[In RopSetSearchCriteria ROP Request Buffer] SearchFlags (4 bytes): STATIC_SEARCH (0x00040000) means that the search is static, if set.");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1084
            Site.CaptureRequirementIfIsTrue(
                searchFolderNotChange,
                1084,
                @"[In Processing a RopSetSearchCriteria ROP Request] For static search folders, the contents of the search folder are not updated after the initial population is complete.");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R549
            Site.CaptureRequirementIfIsTrue(
                searchFolderNotChange,
                549,
                @"[In Processing a RopSetSearchCriteria ROP Request] A static search causes the search folder to be populated once with all messages that match the search criteria at the point in time when the search is started or restarted.");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1093
            Site.CaptureRequirementIfIsTrue(
                searchFolderNotChange,
                1093,
                @"[In Processing a RopSetSearchCriteria ROP Request] The server MUST NOT update the search folder after the initial population when new messages that match the search criteria arrive in the search scope.");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1094
            Site.CaptureRequirementIfIsTrue(
                searchFolderNotChange,
                1094,
                @"[In Processing a RopSetSearchCriteria ROP Request] Or the server MUST NOT update the search folder after the initial population when existing messages that fit the search criteria are deleted.");

            #endregion

            #endregion

            #region Step 9. The client calls RopSetSearchCriteria to restart the search for [MSOXCFOLDSearchFolder2].

            setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.ContentIndexedSearch | (uint)SetSearchFlags.RestartSearch;
            setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle2, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!");

            #endregion

            #region Step 10. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder2].

            count = 0;
            do
            {
                getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle2, ref this.responseHandles);
                Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!");
                if (getContentsTableResponse.RowCount != 1)
                {
                    Thread.Sleep(this.WaitTime);
                }
                else
                {
                    break;
                }

                count++;
            }
            while (count < this.RetryCount);

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R551
            // There should be 1 message found and copy to the search folder, so the RowCount should be 1.
            Site.CaptureRequirementIfAreEqual<uint>(
                1,
                getContentsTableResponse.RowCount,
                551,
                @"[In Processing a RopSetSearchCriteria ROP Request] To trigger an update, another RopSetSearchCriteria ROP request with the RESTART_SEARCH bit set in the SearchFlags field, as specified in section 2.2.1.4.1, is required.");
            #endregion

            #region Step 11. The client calls RopSetSearchCriteria to establish search criteria for [MSOXCFOLDSearchFolder2] by a new RestrictionData.

            setSearchCriteriaRequest = new RopSetSearchCriteriaRequest();
            setSearchCriteriaRequest.RopId = (byte)RopId.RopSetSearchCriteria;
            setSearchCriteriaRequest.LogonId = Constants.CommonLogonId;
            setSearchCriteriaRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
            ContentRestriction contentRestriction = new ContentRestriction
            {
                FuzzyLevelLow = FuzzyLevelLowValues.FL_PREFIX,
                FuzzyLevelHigh = FuzzyLevelHighValues.FL_IGNORECASE
            };
            propertyTag = new PropertyTag
            {
                PropertyId = (ushort)MessagePropertyId.PidTagMessageClass,
                PropertyType = (ushort)PropertyType.PtypString
            };
            contentRestriction.PropertyTag = propertyTag;
            TaggedPropertyValue taggedProperty = new TaggedPropertyValue
            {
                PropertyTag = propertyTag,
                Value = Encoding.Unicode.GetBytes("IPM.Task" + Constants.StringNullTerminated)
            };
            contentRestriction.TaggedValue = taggedProperty;
            setSearchCriteriaRequest.RestrictionDataSize = (ushort)contentRestriction.Size();
            setSearchCriteriaRequest.RestrictionData = contentRestriction.Serialize();
            setSearchCriteriaRequest.FolderIds = new ulong[] { subfolderId1 };
            setSearchCriteriaRequest.FolderIdCount = (ushort)setSearchCriteriaRequest.FolderIds.Length;
            setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.ContentIndexedSearch | (uint)SetSearchFlags.RestartSearch | (uint)SetSearchFlags.StaticSearch;
            setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle2, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!");

            #endregion

            #region Step 12. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder2].

            count = 0;
            do
            {
                getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle2, ref this.responseHandles);
                Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!");
                if (getContentsTableResponse.RowCount != 0)
                {
                    Thread.Sleep(this.WaitTime);
                }
                else
                {
                    break;
                }

                count++;
            }
            while (count < this.RetryCount);

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R519
            // For no message should be found so the search folder should empty, which means the RowCount is 0.
            Site.CaptureRequirementIfAreEqual<uint>(
                0,
                getContentsTableResponse.RowCount,
                519,
                @"[In Processing a RopSetSearchCriteria ROP Request] When new search criteria are applied, the server modifies the search folder to include only the messages that match the new search criteria.");
            #endregion
        }
        public void MSOXCFOLD_S03_TC13_RestrictionDataValidation()
        {
            this.CheckWhetherSupportTransport();
            this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer);
            this.GenericFolderInitialization();

            #region Step 1. The client calls RopCreateFolder to create [MSOXCFOLDSubfolder1] under the root folder.

            RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest
            {
                RopId = (byte)RopId.RopCreateFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                FolderType = (byte)FolderType.Genericfolder,
                UseUnicodeStrings = 0x0,
                OpenExisting = 0x01,
                Reserved = 0x0,
                DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder1),
                Comment = Encoding.ASCII.GetBytes(Constants.Subfolder1)
            };

            RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!");
            ulong folderId = createFolderResponse.FolderId;
            uint folderHandle = this.responseHandles[0][createFolderResponse.OutputHandleIndex];

            #endregion

            #region Step 2. The client creates a non-FAI message under [MSOXCFOLDSubfolder1].

            ulong messageId1 = 0;
            uint messageHandle1 = 0;
            this.CreateSaveMessage(folderHandle, folderId, ref messageId1, ref messageHandle1);

            #endregion

            #region Step 3. The client calls RopCreateFolder to create a search folder [MSOXCFOLDSearchFolder1] under the root folder.

            createFolderRequest = new RopCreateFolderRequest
            {
                RopId = (byte)RopId.RopCreateFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                FolderType = (byte)FolderType.Searchfolder,
                UseUnicodeStrings = 0x0,
                OpenExisting = 0x01,
                Reserved = 0x0,
                DisplayName = Encoding.ASCII.GetBytes(Constants.SearchFolder),
                Comment = Encoding.ASCII.GetBytes(Constants.SearchFolder)
            };

            createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!");
            uint searchFolderHandle = this.responseHandles[0][createFolderResponse.OutputHandleIndex];

            #endregion

            #region Step 4. The client calls RopSetSearchCriteria to establish search criteria for [MSOXCFOLDSearchFolder1].

            ulong[] folderIds = new ulong[]
            {
                folderId
            };
            RopSetSearchCriteriaRequest setSearchCriteriaRequest = new RopSetSearchCriteriaRequest();
            setSearchCriteriaRequest.RopId = (byte)RopId.RopSetSearchCriteria;
            setSearchCriteriaRequest.LogonId = Constants.CommonLogonId;
            setSearchCriteriaRequest.InputHandleIndex = Constants.CommonInputHandleIndex;

            ContentRestriction contentRestriction = new ContentRestriction
            {
                FuzzyLevelLow = FuzzyLevelLowValues.FL_PREFIX,
                FuzzyLevelHigh = FuzzyLevelHighValues.FL_IGNORECASE
            };
            PropertyTag propertyTag = new PropertyTag
            {
                PropertyId = (ushort)MessagePropertyId.PidTagMessageClass,
                PropertyType = (ushort)PropertyType.PtypString
            };
            contentRestriction.PropertyTag = propertyTag;
            TaggedPropertyValue taggedProperty = new TaggedPropertyValue
            {
                PropertyTag = propertyTag,
                Value = Encoding.Unicode.GetBytes("IPM.Task" + Constants.StringNullTerminated)
            };
            contentRestriction.TaggedValue = taggedProperty;

            NotRestriction notRestriction = new NotRestriction
            {
                Restricts = contentRestriction
            };

            setSearchCriteriaRequest.RestrictionDataSize = (ushort)notRestriction.Size();
            byte[] restrictionData = notRestriction.Serialize();
            setSearchCriteriaRequest.RestrictionData = restrictionData;
            setSearchCriteriaRequest.FolderIdCount = (ushort)folderIds.Length;
            setSearchCriteriaRequest.FolderIds = folderIds;
            setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.RestartSearch;

            RopSetSearchCriteriaResponse setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSetSearchCriteria ROP operation performs successfully!");

            #endregion

            #region Step 5. The client calls RopGetSearchCriteria with the UseUnicode field set to 0x01 to obtain the search criteria and the status of the search folder [MSOXCFOLDSearchFolder1].

            RopGetSearchCriteriaRequest getSearchCriteriaRequest = new RopGetSearchCriteriaRequest
            {
                RopId = (byte)RopId.RopGetSearchCriteria,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                UseUnicode = 0x01,
                IncludeRestriction = 0x01,
                IncludeFolders = 0x01
            };

            RopGetSearchCriteriaResponse getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!");
            Restriction restrictTemp = RestrictsFactory.Deserialize(getSearchCriteriaResponse.RestrictionData);
            NotRestriction notRestrictionTemp = (NotRestriction)restrictTemp;
            ContentRestriction contentRestrictionTemp = (ContentRestriction)notRestrictionTemp.Restricts;
            contentRestrictionTemp = (ContentRestriction)notRestrictionTemp.Restricts;
            string str = Encoding.Unicode.GetString(contentRestrictionTemp.TaggedValue.Value);

            #region Verify the requirements: MS-OXCFOLD_R127, MS-OXCFOLD_R137.

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R127
            Site.CaptureRequirementIfAreEqual<string>(
                "IPM.Task" + Constants.StringNullTerminated,
                str,
                127,
                @"[In RopGetSearchCriteria ROP Request Buffer] UseUnicode (1 byte): A Boolean value that is nonzero (TRUE) if the value of the RestrictionData field of the ROP response is to be in Unicode format.");

            #endregion

            #endregion

            #region Step 6. The client calls RopGetSearchCriteria with the UseUnicode field set to 0x00 to obtain the search criteria and the status of the search folder [MSOXCFOLDSearchFolder1].

            getSearchCriteriaRequest.UseUnicode = 0x00;

            getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!");
            restrictTemp = RestrictsFactory.Deserialize(getSearchCriteriaResponse.RestrictionData);
            notRestrictionTemp = (NotRestriction)restrictTemp;
            contentRestrictionTemp = (ContentRestriction)notRestrictionTemp.Restricts;
            str = Encoding.Unicode.GetString(contentRestrictionTemp.TaggedValue.Value);

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R128
            Site.CaptureRequirementIfAreNotEqual<string>(
                "IPM.Task" + Constants.StringNullTerminated,
                str,
                128,
                @"[In RopGetSearchCriteria ROP Request Buffer] UseUnicode (1 byte): [A Boolean value that is] zero (FALSE) otherwise [if the value of the RestrictionData field of the ROP response is not to be in Unicode format].");
            #endregion

            #region Step 7. The client calls RopSetSearchCriteria to restart searching criteria for [MSOXCFOLDSearchFolder1].

            setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.RestartSearch;
            setSearchCriteriaRequest.RestrictionDataSize = 0;
            setSearchCriteriaRequest.RestrictionData = null;
            setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSetSearchCriteria ROP operation performs successfully!");

            #endregion

            #region Step 8. The client calls RopGetSearchCriteria with the UseUnicode field set to 0x00 to obtain the search criteria and the status of the search folder [MSOXCFOLDSearchFolder1].

            getSearchCriteriaRequest.UseUnicode = 0x01;

            getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!");
            restrictTemp = RestrictsFactory.Deserialize(getSearchCriteriaResponse.RestrictionData);
            notRestrictionTemp = (NotRestriction)restrictTemp;
            contentRestrictionTemp = (ContentRestriction)notRestrictionTemp.Restricts;
            str = Encoding.Unicode.GetString(contentRestrictionTemp.TaggedValue.Value);

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

            // Get the portion information of RestrictionData field is this data is same as the data set by the previous RopSetSearchCriteria request, this requirement can be verified. 
            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R105
            Site.CaptureRequirementIfAreEqual<string>(
                "IPM.Task" + Constants.StringNullTerminated,
                str,
                105,
                @"[In RopSetSearchCriteria ROP Request Buffer] RestrictionDataSize (2 bytes): If the value of the RestrictionDataSize field is zero, the search criteria that were used most recently for the search folder container are used again.");
            #endregion
        }