/// <summary>
        /// Verify whether the specified folder was soft deleted.
        /// </summary>
        /// <param name="folderId">The specified folder ID.</param>
        /// <returns>Return a Boolean value indicates whether the specified folder was soft deleted.</returns>
        protected bool IsFolderSoftDeleted(ulong folderId)
        {
            bool folderDeleted = this.IsFolderDeleted(folderId);
            bool folderSoftDeleted = false;

            if (folderDeleted)
            {
                RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
                {
                    RopId = (byte)RopId.RopOpenFolder,
                    LogonId = Constants.CommonLogonId,
                    InputHandleIndex = Constants.CommonInputHandleIndex,
                    OutputHandleIndex = Constants.CommonOutputHandleIndex,
                    OpenModeFlags = (byte)FolderOpenModeFlags.OpenSoftDeleted,
                    FolderId = folderId
                };
                RopOpenFolderResponse openFolderResponse = this.Adapter.OpenFolder(openFolderRequest, this.LogonHandle, ref this.responseHandles);

                if (openFolderResponse.ReturnValue == 0)
                {
                    folderSoftDeleted = true;
                }
            }

            return folderSoftDeleted;
        }
 /// <summary>
 /// Opens an existing folder.
 /// </summary>
 /// <param name="inputHandle">The input Server object for this operation is a Logon object or a Folder object that represents the object to be opened.</param>
 /// <param name="folderId">The folder ID specifies the folder to be opened.</param>
 /// <param name="folderHandle">A Folder object that represents the folder that was opened.</param>
 /// <returns>The RopOpenFolder ROP response buffer.</returns>
 protected RopOpenFolderResponse OpenFolder(uint inputHandle, ulong folderId, ref uint folderHandle)
 {
     RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
     {
         RopId = (byte)RopId.RopOpenFolder,
         LogonId = Constants.CommonLogonId,
         InputHandleIndex = Constants.CommonInputHandleIndex,
         OutputHandleIndex = Constants.CommonOutputHandleIndex,
         OpenModeFlags = (byte)FolderOpenModeFlags.None,
         FolderId = folderId
     };
     RopOpenFolderResponse openFolderResponse = this.Adapter.OpenFolder(openFolderRequest, inputHandle, ref this.responseHandles);
     folderHandle = this.responseHandles[0][openFolderResponse.OutputHandleIndex];
     return openFolderResponse;
 }
        /// <summary>
        /// Open a specified message in specified folder.
        /// </summary>
        /// <param name="messageId">The specified message ID.</param>
        /// <param name="folderId">The specified folder ID.</param>
        /// <param name="openModeFlags">OpenModeFlags for RopOpenMessage.</param>
        /// <returns>The response of RopOpenMessage ROP operation.</returns>
        protected RopOpenMessageResponse OpenMessage(ulong messageId, ulong folderId, MessageOpenModeFlags openModeFlags)
        {
            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
            {
                RopId = (byte)RopId.RopOpenFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                OpenModeFlags = (byte)FolderOpenModeFlags.None,
                FolderId = folderId
            };
            RopOpenFolderResponse openFolderResponse = this.Adapter.OpenFolder(openFolderRequest, this.LogonHandle, ref this.responseHandles);
            uint folderHandle = this.responseHandles[0][openFolderResponse.OutputHandleIndex];

            RopOpenMessageRequest openMessageRequest = new RopOpenMessageRequest();
            object ropResponse = null;
            openMessageRequest.RopId = (byte)RopId.RopOpenMessage;
            openMessageRequest.LogonId = Constants.CommonLogonId;
            openMessageRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
            openMessageRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex;
            openMessageRequest.OpenModeFlags = (byte)openModeFlags;
            openMessageRequest.FolderId = folderId;
            openMessageRequest.MessageId = messageId;
            openMessageRequest.CodePageId = 0x0fff;
            this.Adapter.DoRopCall(openMessageRequest, folderHandle, ref ropResponse, ref this.responseHandles);
            return (RopOpenMessageResponse)ropResponse;
        }
        /// <summary>
        /// Open specific folder.
        /// </summary>
        /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param>
        /// <param name="objHandleIndex">The server object handle index.</param>
        /// <param name="folderIdIndex">The folder id index.</param>
        /// <param name="folderHandleIndex">The folder handle index.</param>
        /// <returns>Indicate the result of this ROP operation.</returns>
        public RopResult OpenFolder(int serverId, int objHandleIndex, int folderIdIndex, out int folderHandleIndex)
        {
            // Initialize return value.
            RopResult result = RopResult.InvalidParameter;
            folderHandleIndex = -1;

            // Form ROP request.
            uint objHandle = this.handleContainer[objHandleIndex];
            ulong folderId = this.objectIdContainer[folderIdIndex];
            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
            {
                RopId = 0x02,
                LogonId = 0x00,
                InputHandleIndex = 0x00,
                OutputHandleIndex = 0x01,
                FolderId = folderId,

                // ReadOnly
                OpenModeFlags = 0x00
            };

            // Send request and get response.
            RopOpenFolderResponse openFolderResponse = (RopOpenFolderResponse)this.Process(serverId, openFolderRequest, objHandle);
            result = (RopResult)openFolderResponse.ReturnValue;

            if (result == RopResult.Success)
            {
                folderHandleIndex = AdapterHelper.GetHandleIndex();
                this.handleContainer.Add(folderHandleIndex, this.responseSOHs[openFolderResponse.OutputHandleIndex]);
            }

            return result;
        }
        /// <summary>
        /// Initialize a generic folder under inbox as a root folder for test.
        /// </summary>
        protected void GenericFolderInitialization()
        {
            RopLogonResponse logonResponse = this.Logon(LogonFlags.Private, out this.logonHandle);

            #region Open the inbox folder.
            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
            {
                RopId = (byte)RopId.RopOpenFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                FolderId = logonResponse.FolderIds[Constants.InboxIndex],
                OpenModeFlags = (byte)FolderOpenModeFlags.OpenSoftDeleted
            };

            // Use the logon object as input handle here.
            RopOpenFolderResponse openFolderResponse = this.Adapter.OpenFolder(openFolderRequest, this.LogonHandle, ref this.responseHandles);
            this.inboxFolderHandle = this.responseHandles[0][openFolderResponse.OutputHandleIndex];
            #endregion

            #region Create a generic folder for test.
            RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest();
            RopCreateFolderResponse createFolderResponse = new RopCreateFolderResponse();
            createFolderRequest.RopId = (byte)RopId.RopCreateFolder;
            createFolderRequest.LogonId = Constants.CommonLogonId;
            createFolderRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
            createFolderRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex;
            createFolderRequest.FolderType = 0x01;
            createFolderRequest.UseUnicodeStrings = 0x0;
            createFolderRequest.OpenExisting = 0x01;
            createFolderRequest.Reserved = 0x0;
            createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(this.RootFolder);
            createFolderRequest.Comment = Encoding.ASCII.GetBytes(this.RootFolder);
            createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.inboxFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, createFolderResponse.ReturnValue, "Creating Folder should succeed.");
            this.rootFolderHandle = this.responseHandles[0][createFolderResponse.OutputHandleIndex];
            this.rootFolderId = createFolderResponse.FolderId;
            this.isRootFolderCreated = true;
            #endregion
        }
        public void MSOXCFOLD_S03_TC16_GetPropertyPidTagFolderFlags()
        {
            this.CheckWhetherSupportTransport();
            this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer);
            this.GenericFolderInitialization();

            #region Step 1. Call RopCreateFolder to create [MSOXCFOLDSubfolder1] under the root folder.
            uint subfolderHandle1 = 0;
            ulong subfolderId1 = 0;
            this.CreateFolder(this.RootFolderHandle, Constants.Subfolder1, ref subfolderId1, ref subfolderHandle1);
            #endregion

            #region Step 2. Creates a none-FAI message in [MSOXCFOLDSubfolder1].
            ulong messageId = 0;
            uint messageHandle = 0;
            this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageId, ref messageHandle);
            #endregion

            #region Step 3. Create a FAI message and saves it in [MSOXCFOLDSubfolder1].
            uint messageHandle2 = 0;
            ulong messageId2 = 0;
            this.CreateSaveMessage(subfolderHandle1, subfolderId1, 0x01, ref messageId2, ref messageHandle2);
            #endregion

            #region Step 4. The client calls RopCreateFolder to create the search folder [MSOXCFOLDSearchFolder1] under the root folder.
            RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest
            {
                RopId = (byte)RopId.RopCreateFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                FolderType = (byte)FolderType.Searchfolder,
                UseUnicodeStrings = 0x0,
                OpenExisting = 0x00,
                Reserved = 0x0,
                DisplayName = Encoding.ASCII.GetBytes(Constants.SearchFolder),
                Comment = Encoding.ASCII.GetBytes(Constants.SearchFolder)
            };
            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 searchFolderHandle = this.responseHandles[0][createFolderResponse.OutputHandleIndex];
            #endregion            

            #region Step 5. The client calls RopSetSearchCriteria to establish search criteria for [MSOXCFOLDSearchFolder1].
            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.NonContentIndexedSearch | (uint)SetSearchFlags.RestartSearch;
            RopSetSearchCriteriaResponse setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!");
            #endregion

            #region Step 6. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder1].
            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, searchFolderHandle, 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);
            #endregion

            #region Step 7. The client creates rules on [MSOXCFOLDSubfolder1] folder.
            RuleData[] sampleRuleDataArray;
            object ropResponse = null;
            sampleRuleDataArray = this.CreateSampleRuleDataArrayForAdd();

            RopModifyRulesRequest modifyRulesRequest = new RopModifyRulesRequest()
            {
                RopId = (byte)RopId.RopModifyRules,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                ModifyRulesFlags = 0x00,
                RulesCount = (ushort)sampleRuleDataArray.Length,
                RulesData = sampleRuleDataArray,
            };

            modifyRulesRequest.RopId = (byte)RopId.RopModifyRules;
            modifyRulesRequest.LogonId = Constants.CommonLogonId;
            modifyRulesRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
            sampleRuleDataArray = this.CreateSampleRuleDataArrayForAdd();
            modifyRulesRequest.ModifyRulesFlags = 0x00;
            modifyRulesRequest.RulesCount = (ushort)sampleRuleDataArray.Length;
            modifyRulesRequest.RulesData = sampleRuleDataArray;
            this.Adapter.DoRopCall(modifyRulesRequest, subfolderHandle1, ref ropResponse, ref this.responseHandles);
            RopModifyRulesResponse modifyRulesResponse = (RopModifyRulesResponse)ropResponse;
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, modifyRulesResponse.ReturnValue, "RopModifyRules ROP operation performs successfully!");           
            #endregion

            #region Step 8. The client calls RopOpenFolder to open [MSOXCFOLDSubfolder1] folder.

            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
            {
                RopId = (byte)RopId.RopOpenFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                FolderId = subfolderId1,
                OpenModeFlags = (byte)FolderOpenModeFlags.None
            };
            RopOpenFolderResponse openFolderResponse = this.Adapter.OpenFolder(openFolderRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, openFolderResponse.ReturnValue, "RopOpenFolder ROP operation performs successfully!");
            #endregion
            
            #region Step 9. The client gets the PidTagFolderFlags propertie from [MSOXCFOLDSubfolder1].
            PropertyTag[] propertyTagArray = new PropertyTag[1];
            propertyTag = new PropertyTag
            {
                PropertyId = (ushort)FolderPropertyId.PidTagFolderFlags,
                PropertyType = (ushort)PropertyType.PtypInteger32
            };
            propertyTagArray[0] = propertyTag;
                        
            RopGetPropertiesSpecificRequest getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest();
            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse;
            getPropertiesSpecificRequest.RopId = (byte)RopId.RopGetPropertiesSpecific;
            getPropertiesSpecificRequest.LogonId = Constants.CommonLogonId;
            getPropertiesSpecificRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
            getPropertiesSpecificRequest.PropertySizeLimit = 0xFFFF;
            getPropertiesSpecificRequest.PropertyTagCount = (ushort)propertyTagArray.Length;
            getPropertiesSpecificRequest.PropertyTags = propertyTagArray;

            getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!");
            uint pidTagFolderFlags = BitConverter.ToUInt32(getPropertiesSpecificResponse.RowData.PropertyValues[0].Value, 0);

            #region Verify MS-OXCFOLD_R1035110, MS-OXCFOLD_R1035111, MS-OXCFOLD_R1035103 and MS-OXCFOLD_R1035107
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, @"Verify MS-OXCFOLD_R1035110: [In PidTagFolderFlags Property] The PidTagFolderId property ([MS-OXPROPS] section 2.692) contains a computed value that specifies the type or state of a folder.");

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1035110
            Site.CaptureRequirement(
                1035110,
                @"[In PidTagFolderFlags Property] The PidTagFolderId property ([MS-OXPROPS] section 2.692) contains a computed value that specifies the type or state of a folder.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, @"Verify MS-OXCFOLD_R1035111: [In PidTagFolderFlags Property] The value is a bitwise OR of zero or more values [1: IPM, 2: SEARCH, 4: NORMAL, 8: RULES] from the following table.");

            bool isR1035111Verified = false;
            if (((pidTagFolderFlags & 1) == 1) || ((pidTagFolderFlags & 2) == 2) || ((pidTagFolderFlags & 4) == 4) || ((pidTagFolderFlags & 8) == 8))
            {
                isR1035111Verified = true;
            }

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1035111
            Site.CaptureRequirementIfIsTrue(
                isR1035111Verified,
                1035111,
                @"[In PidTagFolderFlags Property] The value is a bitwise OR of zero or more values [1: IPM, 2: SEARCH, 4: NORMAL, 8: RULES] from the following table.");
            

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, @"Verify MS-OXCFOLD_R1035103: [In PidTagFolderFlags Property] [The folder flag named ""IPM"" specified] the folder belongs to the IPM subtree portion of the mailbox.");

            bool isR1035103Verified = false;
            if ((pidTagFolderFlags & 1) == 1)
            {
                isR1035103Verified = true;
            }

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1035103
            Site.CaptureRequirementIfIsTrue(
                isR1035103Verified,
                1035103,
                @"[In PidTagFolderFlags Property] [The folder flag named ""IPM"" specified] the folder belongs to the IPM subtree portion of the mailbox.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, @"Verify MS-OXCFOLD_R1035107: [In PidTagFolderFlags Property] [The folder flag named ""NORMAL"" specified] the folder is a generic folder that contains messages and other folders.");

            bool isR1035107Verified = false;
            if ((pidTagFolderFlags & 4) == 4)
            {
                isR1035107Verified = true;
            }

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1035107
            Site.CaptureRequirementIfIsTrue(
                isR1035107Verified,
                1035107,
                @"[In PidTagFolderFlags Property] [The folder flag named ""NORMAL"" specified] the folder is a generic folder that contains messages and other folders.");
            #endregion
            #endregion
        }
        /// <summary>
        /// Delete the message created by the owner of the mailbox or other user in Inbox.
        /// </summary>
        /// <param name="messageId">The message Id to delete.</param>
        /// <returns>The return value from the server. 0x00000000 indicates success, others indicate error occurs.</returns>
        private uint DeleteMessage(ulong messageId)
        {
            // Open the Inbox folder.
            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
            {
                RopId = 0x02,
                LogonId = 0x00,
                InputHandleIndex = 0x00,
                OutputHandleIndex = 0x01,
                FolderId = this.ropLogonResponse.FolderIds[4],
                OpenModeFlags = 0x00
            };
            this.responseSOHs = this.DoRopCall(openFolderRequest, this.inobjHandle, ref this.response, ref this.rawData);
            RopOpenFolderResponse openFolderResponse = (RopOpenFolderResponse)this.response;
            if (UINT32SUCCESS != openFolderResponse.ReturnValue)
            {
                return openFolderResponse.ReturnValue;
            }

            uint inboxFolderHandle = this.responseSOHs[0][((RopOpenFolderResponse)this.response).OutputHandleIndex];

            ulong[] messageIdsArrayToDelete = new ulong[1];

            // Delete the message created.
            messageIdsArrayToDelete[0] = messageId;
            RopDeleteMessagesRequest deleteMessagesRequest;
            RopDeleteMessagesResponse deleteMessagesResponse;
            deleteMessagesRequest.RopId = 0x1E;
            deleteMessagesRequest.LogonId = 0x00;
            deleteMessagesRequest.InputHandleIndex = 0x00;
            deleteMessagesRequest.WantAsynchronous = 0x00; // Synchronously
            deleteMessagesRequest.NotifyNonRead = 0x00; // The server does not generate a non-read receipt for the deleted messages
            deleteMessagesRequest.MessageIdCount = (ushort)messageIdsArrayToDelete.Length;
            deleteMessagesRequest.MessageIds = messageIdsArrayToDelete;
            this.DoRopCall(deleteMessagesRequest, inboxFolderHandle, ref this.response, ref this.rawData);
            deleteMessagesResponse = (RopDeleteMessagesResponse)this.response;

            if (deleteMessagesResponse.ReturnValue == UINT32SUCCESS && deleteMessagesResponse.PartialCompletion == 0)
            {
                if (this.ownedMessageIds.Contains(messageId))
                {
                    this.ownedMessageIds.Remove(messageId);
                }
                else
                {
                    this.messageIdsCreatedByOther.Remove(messageId);
                }

                return UINT32SUCCESS;
            }
            else
            {
                if (deleteMessagesResponse.ReturnValue != 0x00000000)
                {
                    return deleteMessagesResponse.ReturnValue;
                }
                else
                {
                    Site.Log.Add(LogEntryKind.Debug, "PartialCompletion of the response to RopDeleteMessages is not 0");
                    return UINT32FAILED;
                }
            }
        }
        /// <summary>
        /// This ROP opens an existing folder in a mailbox.  
        /// </summary>
        /// <param name="handle">The handle to operate</param>
        /// <param name="openFolderResponse">The response of this ROP</param>
        /// <param name="folderId">The identifier of the folder to be opened.</param>
        /// <param name="needVerify">Whether need to verify the response</param>
        /// <returns>The handle of the opened folder</returns>
        private uint RopOpenFolder(uint handle, out RopOpenFolderResponse openFolderResponse, ulong folderId, bool needVerify)
        {
            this.rawDataValue = null;
            this.responseValue = null;
            this.responseSOHsValue = null;

            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest()
            {
                RopId = (byte)RopId.RopOpenFolder,
                LogonId = LogonId,
                InputHandleIndex = (byte)HandleIndex.FirstIndex,
                OutputHandleIndex = (byte)HandleIndex.SecondIndex,
                FolderId = folderId,

                // Open an existing folder with None value for OpenModeFlags flag.
                OpenModeFlags = (byte)FolderOpenModeFlags.None
            };

            this.responseSOHsValue = this.ProcessSingleRop(openFolderRequest, handle, ref this.responseValue, ref this.rawDataValue, RopResponseType.SuccessResponse);
            openFolderResponse = (RopOpenFolderResponse)this.responseValue;
            if (needVerify)
            {
                this.Site.Assert.AreEqual((uint)RopResponseType.SuccessResponse, openFolderResponse.ReturnValue, string.Format("RopOpenFolderResponse Failed! Error: 0x{0:X8}", openFolderResponse.ReturnValue));
            }

            return this.responseSOHsValue[0][openFolderResponse.OutputHandleIndex];
        }
        public void MSOXCFOLD_S03_TC08_SetAndGetProperties()
        {
            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 = 0x01,
                UseUnicodeStrings = 0x1,
                OpenExisting = 0x00,
                Reserved = 0x0,
                DisplayName = Encoding.Unicode.GetBytes(Constants.Subfolder1),
                Comment = Encoding.Unicode.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 subfolderId1 = createFolderResponse.FolderId;
            uint subfolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex];

            #endregion

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

            createFolderRequest.FolderType = 0x02;
            createFolderRequest.DisplayName = Encoding.Unicode.GetBytes(Constants.Subfolder2);
            createFolderRequest.Comment = Encoding.Unicode.GetBytes(Constants.StringNullTerminated);

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

            #endregion

            #region Step 3. The client creates a Non-FAI message and saves it in [MSOXCFOLDSubfolder1].

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

            #endregion

            #region Step 4. The client create a FAI message and saves it in [MSOXCFOLDSubfolder2].

            uint messageHandle2 = 0;
            ulong messageId2 = 0;
            this.CreateSaveMessage(subfolderHandle2, subfolderId1, 0x01, ref messageId2, ref messageHandle2);

            #endregion

            #region Step 5. The client get the properties from the [MSOXCFOLDSubfolder1] under the root folder.

            PropertyTag[] tags = new PropertyTag[7];
            PropertyTag tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagAttributeHidden;
            tag.PropertyType = (ushort)PropertyType.PtypBoolean;
            tags[0] = tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagComment;
            tag.PropertyType = (ushort)PropertyType.PtypString;
            tags[1] = tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagContainerClass;
            tag.PropertyType = (ushort)PropertyType.PtypString;
            tags[2] = tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagDisplayName;
            tag.PropertyType = (ushort)PropertyType.PtypString;
            tags[3] = tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagFolderType;
            tag.PropertyType = (ushort)PropertyType.PtypInteger32;
            tags[4] = tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagRights;
            tag.PropertyType = (ushort)PropertyType.PtypInteger32;
            tags[5] = tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagAccessControlListData;
            tag.PropertyType = (ushort)PropertyType.PtypBinary;
            tags[6] = tag;

            RopGetPropertiesSpecificRequest getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest();
            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse = new RopGetPropertiesSpecificResponse();
            getPropertiesSpecificRequest.RopId = (byte)RopId.RopGetPropertiesSpecific;
            getPropertiesSpecificRequest.LogonId = Constants.CommonLogonId;
            getPropertiesSpecificRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
            getPropertiesSpecificRequest.PropertySizeLimit = 0xFFFF;
            getPropertiesSpecificRequest.PropertyTagCount = (ushort)tags.Length;
            getPropertiesSpecificRequest.PropertyTags = tags;
            getPropertiesSpecificRequest.WantUnicode = 0x01;
            getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!");
            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse1 = getPropertiesSpecificResponse;

            #region Verify the requirements: MS_OXCFOLD_R1033, MS-OXCFOLD_R10359, and MS-OXCFOLD_R811.

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1033.
            Site.CaptureRequirementIfAreEqual<byte>(
                0,
                getPropertiesSpecificResponse.RowData.PropertyValues[0].Value[0],
                1033,
                @"[In PidTagAttributeHidden Property] The value is zero otherwise [If the folder is not hidden].");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R10359
            Site.CaptureRequirementIfAreEqual<string>(
                Constants.Subfolder1,
                Encoding.Unicode.GetString(getPropertiesSpecificResponse.RowData.PropertyValues[1].Value),
                10359,
                @"[In PidTagComment Property] The PidTagComment property ([MS-OXPROPS] section 2.628) contains a comment about the purpose or content of the folder.");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R811
            Site.CaptureRequirementIfAreEqual<int>(
                1,
                BitConverter.ToInt32(getPropertiesSpecificResponse.RowData.PropertyValues[4].Value, 0),
                811,
                @"[In PidTagFolderType Property] FOLDER_GENERIC (1): A generic folder that contains messages and other folders.");
            #endregion

            #endregion

            #region Step 6. The client set the read/write properties for the folder.

            TaggedPropertyValue[] taggedPropertyValueArray = new TaggedPropertyValue[6];
            PropertyTag tempPropertyTag = new PropertyTag();
            int size = 0;

            // Set PidTagAttributeHidden property for the folder.
            taggedPropertyValueArray[0] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagAttributeHidden;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypBoolean;
            taggedPropertyValueArray[0].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[0].Value = new byte[1] { 0x01 };

            // Set PidTagComment property for the folder.
            taggedPropertyValueArray[1] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagComment;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypString;
            taggedPropertyValueArray[1].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[1].Value = Encoding.Unicode.GetBytes(Constants.Subfolder3);

            // Set PidTagContainerClass property for the folder.
            taggedPropertyValueArray[2] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagContainerClass;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypString;
            taggedPropertyValueArray[2].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[2].Value = Encoding.Unicode.GetBytes("IPF.Note\0");

            // Set PidTagDisplayName property for the folder.
            taggedPropertyValueArray[3] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagDisplayName;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypString;
            taggedPropertyValueArray[3].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[3].Value = Encoding.Unicode.GetBytes(Constants.Subfolder3);

            // Set PidTagFolderType property for the folder.
            taggedPropertyValueArray[4] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagFolderType;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypInteger32;
            taggedPropertyValueArray[4].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[4].Value = BitConverter.GetBytes(0x00000001);

            // Set PidTagRights property for the folder.
            taggedPropertyValueArray[5] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagRights;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypInteger32;
            taggedPropertyValueArray[5].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[5].Value = BitConverter.GetBytes(0x00000400);

            for (int i = 0; i < taggedPropertyValueArray.Length; i++)
            {
                size += taggedPropertyValueArray[i].Size();
            }

            RopSetPropertiesRequest setPropertiesRequest = new RopSetPropertiesRequest
            {
                RopId = (byte)RopId.RopSetProperties,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                PropertyValueSize = (ushort)(size + 2),
                PropertyValueCount = (ushort)taggedPropertyValueArray.Length,
                PropertyValues = taggedPropertyValueArray
            };

            RopSetPropertiesResponse setPropertiesResponse = this.Adapter.SetFolderObjectProperties(setPropertiesRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, setPropertiesResponse.ReturnValue, "RopSetProperties ROP operation performs successfully!");

            #endregion

            #region Step 7. The client get the properties from the [MSOXCFOLDSubfolder1] under the root folder after execute the RopSetProperties operation.

            getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!");

            #region Verify the requirements: MS_OXCFOLD_R1032, MS-OXCFOLD_R10356.

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1032.
            Site.CaptureRequirementIfAreNotEqual<byte>(
                0,
                getPropertiesSpecificResponse.RowData.PropertyValues[0].Value[0],
                1032,
                @"[In PidTagAttributeHidden Property] The value of this property [PidTagAttributeHidden] is nonzero if the folder is hidden.");

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

            // MS-OXCFOLD_R1032 and MS-OXCFOLD_R1033 were verified, MS-OXCFOLD_R10356 can be verified directly.
            Site.CaptureRequirement(
                10356,
                @"[In PidTagAttributeHidden Property] The PidTagAttributeHidden property ([MS-OXPROPS] section 2.602) specifies whether the folder is hidden.");

            string pidTagContainerClass = System.Text.Encoding.Unicode.GetString(getPropertiesSpecificResponse.RowData.PropertyValues[2].Value);
            
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1038: the PidTagContainerClass property value is {0}", pidTagContainerClass.Replace("\0", string.Empty));
        
            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1038
            this.Site.CaptureRequirementIfIsTrue(
                pidTagContainerClass.StartsWith("IPF."),
                1038,
                @"[In PidTagContainerClass Property] The value of this property [PidTagContainerClass] MUST begin with ""IPF."".");

            // According to step above, the folder object includes the PidTagContainerClass property and the value of the PidTagContainerClass property follow the definition in Open Specification.
            // So R10036 will be verfied.
            this.Site.CaptureRequirement(
                10036,
                @"[In PidTagContainerClass Property] The PidTagContainerClass property ([MS-OXPROPS] section 2.633) specifies the type of Message object that the folder contains.");
            #endregion

            #endregion

            #region Step 8. The client get the properties from the [MSOXCFOLDSubfolder2] under the root folder.

            getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, subfolderHandle2, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!");
            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse3 = getPropertiesSpecificResponse;

            #region Verify the requirement: MS-OXCFOLD_R812 and  MS-OXCFOLD_R1034.

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R812
            Site.CaptureRequirementIfAreEqual<int>(
                2,
                BitConverter.ToInt32(getPropertiesSpecificResponse.RowData.PropertyValues[4].Value, 0),
                812,
                @"[In PidTagFolderType Property] FOLDER_SEARCH (2): A folder that contains the results of a search, in the form of links to messages that meet search criteria.");

            bool isVerifyR1034 = Encoding.Unicode.GetString(getPropertiesSpecificResponse1.RowData.PropertyValues[1].Value) == Constants.Subfolder1 &&
                Encoding.Unicode.GetString(getPropertiesSpecificResponse3.RowData.PropertyValues[1].Value) == Constants.StringNullTerminated;

            // Add the debug information.
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1034, the property [PidTagComment] is present {0} only if the client sets it.", isVerifyR1034 ? string.Empty : "not");

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1034.
            Site.CaptureRequirementIfIsTrue(
                isVerifyR1034,
                1034,
                @"[In PidTagComment Property] This property [PidTagComment] is present only if the client sets it when the folder is created.");

            #endregion

            #endregion

            #region Step 8. The client set the same read/write properties for the [MSOXCFOLDSubfolder2] as [MSOXCFOLDSubfolder1].
            taggedPropertyValueArray = new TaggedPropertyValue[1];
            tempPropertyTag = new PropertyTag();

            // Set PidTagDisplayName property for the folder.
            taggedPropertyValueArray[0] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagDisplayName;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypString;
            taggedPropertyValueArray[0].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[0].Value = Encoding.Unicode.GetBytes(Constants.Subfolder3);

            setPropertiesRequest = new RopSetPropertiesRequest
            {
                RopId = (byte)RopId.RopSetProperties,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                PropertyValueSize = (ushort)(taggedPropertyValueArray[0].Size() + 2),
                PropertyValueCount = (ushort)taggedPropertyValueArray.Length,
                PropertyValues = taggedPropertyValueArray
            };
            setPropertiesResponse = this.Adapter.SetFolderObjectProperties(setPropertiesRequest, subfolderHandle2, ref this.responseHandles);

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

            // Only set one property in RopSetProperties ROP request, use 0 as index here.
            int expectedIndex = 0;
            bool isVerifiedR1039 = false;
            if (setPropertiesResponse.PropertyProblems != null)
            {
                Site.Log.Add(
                    LogEntryKind.Debug,
                    "The PropertyProblems of index {0} in RopSetProperties ROP response return value is: {1}",
                    expectedIndex,
                    setPropertiesResponse.PropertyProblems[expectedIndex].ErrorCode);
                isVerifiedR1039 = setPropertiesResponse.PropertyProblems[expectedIndex].ErrorCode != Constants.SuccessCode;
            }
            else
            {
                Site.Log.Add(LogEntryKind.Debug, "The RopSetProperties ROP response return value is: {0}", setPropertiesResponse.ReturnValue);
                isVerifiedR1039 = setPropertiesResponse.ReturnValue != Constants.SuccessCode;
            }

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1039.
            Site.CaptureRequirementIfIsTrue(
                isVerifiedR1039,
                1039,
                @"[In PidTagDisplayName Property] Sibling folders MUST have unique display names.");
            #endregion

            #region Step 9. The client calls RopOpenFolder to get the Root folder handle.

            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
            {
                RopId = (byte)RopId.RopOpenFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                FolderId = this.DefaultFolderIds[0],
                OpenModeFlags = (byte)FolderOpenModeFlags.OpenSoftDeleted
            };

            RopOpenFolderResponse openFolderResponse = this.Adapter.OpenFolder(openFolderRequest, this.LogonHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, openFolderResponse.ReturnValue, "RopOpenFolder ROP operation performs successfully!");
            uint rootFolderHandle = this.responseHandles[0][openFolderResponse.OutputHandleIndex];

            #endregion

            #region Step 10. The client get the properties from the Root folder.

            getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, rootFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R810.
            Site.CaptureRequirementIfAreEqual<int>(
                0,
                BitConverter.ToInt32(getPropertiesSpecificResponse.RowData.PropertyValues[4].Value, 0),
                810,
                @"[In PidTagFolderType Property] FOLDER_ROOT (0): The Root folder of the folder hierarchy table; that is, a folder that has no parent folder.");

            RopGetPropertiesAllResponse getPropertiesAllResponse = this.Adapter.GetFolderPropertiesAll(this.RootFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, getPropertiesAllResponse.ReturnValue, "RopGetPropertiesAllResponse ROP operation performs successfully!");
            #endregion

            #region Step 11. The client get property PidTagAddressBookEntryId
            if (Common.IsRequirementEnabled(350002, this.Site))
            {
                PropertyTag[] propertyTagArray = new PropertyTag[1];
                PropertyTag propertyTag = new PropertyTag
                {
                    PropertyId = (ushort)FolderPropertyId.PidTagAddressBookEntryId,
                    PropertyType = (ushort)PropertyType.PtypBinary
                };
                propertyTagArray[0] = propertyTag;

                getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest();
                getPropertiesSpecificRequest.RopId = (byte)RopId.RopGetPropertiesSpecific;
                getPropertiesSpecificRequest.LogonId = Constants.CommonLogonId;
                getPropertiesSpecificRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
                getPropertiesSpecificRequest.PropertySizeLimit = 0xFFFF;
                getPropertiesSpecificRequest.PropertyTagCount = (ushort)propertyTagArray.Length;
                getPropertiesSpecificRequest.PropertyTags = propertyTagArray;

                getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, subfolderHandle1, ref this.responseHandles);
                Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!");

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

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R350.
                // Flag value 0x01 indicates there is error.
                Site.CaptureRequirementIfAreEqual<byte>(
                    0x01,
                    getPropertiesSpecificResponse.RowData.Flag,
                    350,
                    @"[In PidTagAddressBookEntryId Property] This property is set only for public folders.");
            }
            #endregion
        }
        public void MSOXCFOLD_S04_TC02_PublicFolderGhostedFolderValidation()
        {
            this.CheckWhetherSupportTransport();
            this.Logon();
            this.PublicFolderInitialization();
            string ghostedPublicFolder = Common.GetConfigurationPropertyValue("GhostedPublicFolder", this.Site) + Constants.StringNullTerminated;

            // The ghosted folder is only supported when the 2nd SUT exists.
            if (Common.GetConfigurationPropertyValue("Sut2ComputerName", this.Site) == string.Empty)
            {
                Site.Assert.Inconclusive("This case runs only when the second system under test exists.");
            }
            else
            {
                #region Step 1. The client calls OpenFolder to open the ghosted public folder.
                ulong ghostedFolderId = this.GetSubfolderIDByName(this.DefaultFolderIds[1], this.publicLogonHandle, ghostedPublicFolder);

                RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
                {
                    RopId = 0x02,
                    LogonId = Constants.CommonLogonId,
                    InputHandleIndex = Constants.CommonInputHandleIndex,
                    OutputHandleIndex = Constants.CommonOutputHandleIndex,
                    FolderId = ghostedFolderId
                };
                RopOpenFolderResponse openFolderResponse = this.Adapter.OpenFolder(openFolderRequest, this.publicLogonHandle, ref this.responseHandles);
                Site.Assert.AreEqual<uint>(0, openFolderResponse.ReturnValue, "The open folder operation should succeed.");

                #region Verify requirements.

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

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R907
                Site.CaptureRequirementIfAreNotEqual<byte?>(
                    0x00,
                    openFolderResponse.IsGhosted,
                    907,
                    @"[In RopOpenFolder ROP Response Buffer] If the server does not host an active replica of the folder, this field [IsGhosted] is set to a nonzero (TRUE) value.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R909, the value of ServerCount is {0}.", openFolderResponse.ServerCount);

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R909.
                // MS-OXCFOLD_R907 was verified and the IsGhosted field is set to a nonzero (TRUE) value, if the ServerCount is not null, MS-OXCFOLD_R909 can be verified.
                Site.CaptureRequirementIfIsNotNull(
                    openFolderResponse.ServerCount,
                    909,
                    @"[In RopOpenFolder ROP Response Buffer] This field [ServerCount] is present only if the IsGhosted field is set to a nonzero (TRUE) value.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R912, the value of CheapServerCount is {0}.", openFolderResponse.CheapServerCount);

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R912
                // The CheapServerCount is not null indicates that it presents.
                Site.CaptureRequirementIfIsNotNull(
                    openFolderResponse.CheapServerCount,
                    912,
                    @"[In RopOpenFolder ROP Response Buffer] This field [CheapServerCount] is present only if the IsGhosted field is set to a nonzero (TRUE) value.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R915, the count of Servers is {0}.", openFolderResponse.Servers.Length);

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R915
                // The Servers is not null indicates that it presents.
                Site.CaptureRequirementIfIsNotNull(
                    openFolderResponse.Servers,
                    915,
                    @"[In RopOpenFolder ROP Response Buffer] This field [Servers] is present only if the IsGhosted field is set to a nonzero (TRUE) value.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R913: The server that has a replica of the folder {0} is {1}", ghostedPublicFolder.Trim(Constants.StringNullTerminated.ToCharArray()), openFolderResponse.Servers[0].Trim(Constants.StringNullTerminated.ToCharArray()));

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R913.
                // The RopOpenFolder ROP response deserialized successfully, MS-OXCFOLD_R913 can be verified directly.
                Site.CaptureRequirement(
                    913,
                    @"[In RopOpenFolder ROP Response Buffer] Servers (variable): An array of null-terminated ASCII strings, each of which specifies a server that has a replica of the folder.");

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

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R908.
                Site.CaptureRequirementIfAreEqual<int>(
                    openFolderResponse.Servers.Length,
                    (int)openFolderResponse.ServerCount,
                    908,
                    @"[In RopOpenFolder ROP Response Buffer] ServerCount (2 bytes): An integer that specifies the number of servers that have a replica of the folder.");
                #endregion
                #endregion

                #region Step 2. The client calls RopCreateFolder to create a ghosted public folder under the root folder.

                // IsGhosted filed is present only if the IsExistingFolder field is set to a nonzero (TRUE) value and only for folders that are in a public store.
                // If implementation return zero (FALSE) in the IsExistingFolder field when the named folder already exists,
                // IsGhosted field related requirements can't be verified.
                if (Common.IsRequirementEnabled(60002, this.Site))
                {
                    RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest
                    {
                        RopId = (byte)RopId.RopCreateFolder,
                        LogonId = Constants.CommonLogonId,
                        InputHandleIndex = Constants.CommonInputHandleIndex,
                        OutputHandleIndex = Constants.CommonOutputHandleIndex,
                        FolderType = (byte)FolderType.Genericfolder,
                        UseUnicodeStrings = 0x0,
                        OpenExisting = 0xff,
                        Reserved = 0x0,
                        DisplayName = Encoding.ASCII.GetBytes(ghostedPublicFolder),
                        Comment = Encoding.ASCII.GetBytes(ghostedPublicFolder)
                    };
                    RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.publicFoldersHandle, ref this.responseHandles);
                    Site.Assert.AreEqual<uint>(0, createFolderResponse.ReturnValue, "The open folder operation should succeed.");

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

                    // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R929.
                    Site.CaptureRequirementIfAreNotEqual<byte?>(
                        0x00,
                        createFolderResponse.IsGhosted,
                        929,
                        @"[In RopCreateFolder ROP Response Buffer] If the server does not host an active replica of the folder, this field [IsGhosted] is set to a nonzero (TRUE) value.");

                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R933, the value of ServerCount is {0}.", createFolderResponse.ServerCount);

                    // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R933.
                    // MS-OXCFOLD_R929 was verified and the IsGhosted field is set to a nonzero (TRUE) value, if the ServerCount is not null, MS-OXCFOLD_R933 can be verified.
                    Site.CaptureRequirementIfIsNotNull(
                        createFolderResponse.ServerCount,
                        933,
                        @"[In RopCreateFolder ROP Response Buffer] This field [ServerCount] is present only if the IsGhosted field is set to a nonzero (TRUE) value.");

                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R938, the value of CheapServerCount is {0}.", createFolderResponse.CheapServerCount);

                    // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R938.
                    // MS-OXCFOLD_R929 was verified and the IsGhosted field is set to a nonzero (TRUE) value, if the ServerCount is not null, MS-OXCFOLD_R933 can be verified.
                    Site.CaptureRequirementIfIsNotNull(
                        createFolderResponse.CheapServerCount,
                        938,
                        @"[In RopCreateFolder ROP Response Buffer] This field [CheapServerCount] is present only if the IsGhosted field is set to a nonzero (TRUE) value.");

                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R941, the count of Servers is {0}.", createFolderResponse.Servers.Length);

                    // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R941
                    // The Servers is not null indicates that it presents.
                    Site.CaptureRequirementIfIsNotNull(
                        createFolderResponse.Servers,
                        941,
                        @"[In RopCreateFolder ROP Response Buffer] This field [Servers] is present only if the IsGhosted field is set to a nonzero (TRUE) value.");

                    // Add the debug information
                    Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R939: The server that has a replica of the folder {0} is {1}", ghostedPublicFolder.Trim(Constants.StringNullTerminated.ToCharArray()), createFolderResponse.Servers[0].Trim(Constants.StringNullTerminated.ToCharArray()));

                    // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R939.
                    // The RopCreateFolder ROP response deserialized successfully, MS-OXCFOLD_R939 can be verified directly.
                    Site.CaptureRequirement(
                        939,
                        @"[In RopCreateFolder ROP Response Buffer] Servers (variable): An array of null-terminated ASCII strings, each of which specifies a server that has a replica of the folder.");

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

                    // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R932.
                    Site.CaptureRequirementIfAreEqual<int>(
                        createFolderResponse.Servers.Length,
                        (int)createFolderResponse.ServerCount,
                        932,
                        @"[In RopCreateFolder ROP Response Buffer] ServerCount (2 bytes): An integer that specifies the number of servers that have a replica of the folder.");
                    #endregion
                }
                #endregion
            }
        }
        public void MSOXCFOLD_S04_TC01_PublicFolderNonGhostedFolderValidation()
        {
            this.CheckWhetherSupportTransport();
            this.Logon();
            this.PublicFolderInitialization();

            RopCreateFolderRequest createFolderRequest;
            RopCreateFolderResponse createFolderResponse;

            #region Step 1. The client calls RopCreateFolder to create a search folder named [MSOXCFOLDSearchFolder1] under the root public 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)
            };
            object response = null;
            uint result = this.Adapter.DoRopCall(createFolderRequest, this.publicRootFolderHandle, ref response, ref this.responseHandles);

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

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R10660201
                Site.CaptureRequirementIfAreEqual<uint>(
                    0x80004005,
                    result,
                    10660201,
                    @"[In Appendix A: Product Behavior] If the ROP was called to create a search folder on a public folders message store, the implemetation does return ecError <12> Section 3.2.5.2:  Exchange 2010 and Exchange 2007 return ecError.");
            }

            if (Common.IsRequirementEnabled(10660202, this.Site))
            {
                createFolderResponse = (RopCreateFolderResponse)response;

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

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R10660202
                Site.CaptureRequirementIfAreEqual<uint>(
                    0x80040102,
                    createFolderResponse.ReturnValue,
                    10660202,
                    @"[In Appendix A: Product Behavior] If the ROP was called to create a search folder on a public folders message store, the implemetation does return ecNotSupported. <12> Exchange 2013 and Exchange 2016 return ecNotSupported.");
            }
            #endregion

            #region Step 2. The client calls RopCreateFolder to create a generic folder named [MSOXCFOLDSubfolder1].

            uint subfolderHandle1 = 0;
            ulong subfolderId1 = 0;
            createFolderResponse = this.CreateFolder(this.publicRootFolderHandle, Constants.Subfolder1, ref subfolderId1, ref subfolderHandle1);

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R3802
            Site.CaptureRequirementIfAreEqual<uint>(
                Constants.SuccessCode,
                createFolderResponse.ReturnValue,
                3802,
                @"[In RopCreateFolder ROP] The folder can be either a public folder [or a private mailbox folder].");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R61.
            Site.CaptureRequirementIfAreEqual<byte>(
                0x00,
                createFolderResponse.IsExistingFolder,
                61,
                @"[RopCreateFolder ROP Response Buffer] IsExistingFolder (1 byte): The value is zero (FALSE) if a public folder with that name does not exist.");

            byte isExistingFolder = createFolderResponse.IsExistingFolder;
            bool isHasRulesInExistingFolder = createFolderResponse.HasRules == null;
            bool isIsGhostedInExistingFolder = createFolderResponse.IsGhosted == null;
            #endregion

            #region Step 3. The client calls RopOpenFolder to open folder named [MSOXCFOLDSubfolder1].
            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
            {
                RopId = (byte)RopId.RopOpenFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                OpenModeFlags = (byte)FolderOpenModeFlags.None,
                FolderId = subfolderId1
            };
            RopOpenFolderResponse openFolderResponse = this.Adapter.OpenFolder(openFolderRequest, this.publicLogonHandle, ref this.responseHandles);

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R90002
            Site.CaptureRequirementIfAreEqual<uint>(
                Constants.SuccessCode,
                openFolderResponse.ReturnValue,
                90002,
                @"[In RopOpenFolder ROP] The folder can be either a public folder [or a private mailbox folder].");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R30
            Site.CaptureRequirementIfIsNotNull(
                openFolderResponse.IsGhosted,
                30,
                @"[In RopOpenFolder ROP Response Buffer] IsGhosted (1 byte): This field [IsGhosted] is present only for folders that are in a public store.");

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

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R29.
            Site.CaptureRequirementIfAreEqual<byte?>(
                0x00,
                openFolderResponse.IsGhosted,
                29,
                @"[In RopOpenFolder ROP Response Buffer] IsGhosted (1 byte): otherwise [If the server hosts an active replica of the folder], this field [IsGhosted] is set to zero (FALSE).");
            #endregion

            #region Step 4. The client calls RopCreateFolder to create [MSOXCFOLD_PublicFolderMailEnabled] which is an existing folder with 'OpeningExisting' flag set to non-zero.

            string folderDisplayName = Common.GetConfigurationPropertyValue("MailEnabledPublicFolder", this.Site) + Constants.StringNullTerminated;
            createFolderRequest = new RopCreateFolderRequest()
            {
                RopId = (byte)RopId.RopCreateFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                FolderType = (byte)FolderType.Genericfolder,
                UseUnicodeStrings = 0x1,
                OpenExisting = 0x01,
                Reserved = 0x0,
                DisplayName = Encoding.Unicode.GetBytes(folderDisplayName),
                Comment = Encoding.Unicode.GetBytes(folderDisplayName)
            };

            // Invoke the CreateFolder operation with valid parameters, use root folder handle to indicate that the new folder will be created under the root folder.
            createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.publicFoldersHandle, ref this.responseHandles);

            Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!");

            subfolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex];
 
            if (Common.IsRequirementEnabled(60001, this.Site))
            {
                // Regardless of the existence of the named public folder, if the IsExistingFolder in response is always set to zero, R60001 can be verified.
                bool isR60001Verified = isExistingFolder == 0 && createFolderResponse.IsExistingFolder == 0;
                
                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R60001, regardless of the existence of the public folder, the IsExistingFolder in response should be always set to {0}, actually, when public folder exists the IsExistingFolder in response is {1}, when public folder does not exist the IsExistingFolder in response is {2}.", 0, createFolderResponse.IsExistingFolder, isExistingFolder);

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R60001
                Site.CaptureRequirementIfIsTrue(
                    isR60001Verified,
                    60001,
                    @"[In Appendix A: Product Behavior] Implementation does return zero (FALSE) in the IsExistingFolder field regardless of the existence of the named public folder. <3> Section 2.2.1.2.2: Exchange 2010 Exchange 2013 and Exchange 2016 always return zero (FALSE) in the IsExistingFolder field regardless of the existence of the named public folder.");
            }

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

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R60002.
                Site.CaptureRequirementIfAreNotEqual<byte>(
                    0x00,
                    createFolderResponse.IsExistingFolder,
                    60002,
                    @"[In Appendix A: Product Behavior] If a public folder with the name given by the DisplayName field of the request buffer already exists, implementation does set a nonzero (TRUE) value to IsExistingFolder field. (Microsoft Exchange Server 2007 follows this behavior.)");

                bool isHasRules = createFolderResponse.HasRules != null;
                bool isIsGhosted = createFolderResponse.IsGhosted != null;
                bool isR926Verified = isHasRules && isHasRulesInExistingFolder;
                bool isR931Verified = isIsGhosted && isIsGhostedInExistingFolder;

                // Add the debug information.
                Site.Log.Add(
                    LogEntryKind.Debug,
                    @"Verify MS-OXCFOLD_R926: When the IsExistingFolder field is set to a zero, the compare result of HasRules and null is {0}; When the IsExistingFolder field is set to a nonzero, the compare result of HasRules and null is {1}",
                    isHasRulesInExistingFolder,
                    isHasRules);

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R926.
                Site.CaptureRequirementIfIsTrue(
                    isR926Verified,
                    926,
                    @"[In RopCreateFolder ROP Response Buffer] This field [HasRules] is present only if the IsExistingFolder field is set to a nonzero (TRUE) value.");

                // Add the debug information.
                Site.Log.Add(
                    LogEntryKind.Debug,
                    @"Verify MS-OXCFOLD_R931: When the IsExistingFolder field is set to a zero, the compare result of IsGhosted and null is {0}; When the IsExistingFolder field is set to a nonzero, the compare result of IsGhosted and null is {1}",
                    isIsGhostedInExistingFolder,
                    isIsGhosted);

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R931.
                Site.CaptureRequirementIfIsTrue(
                    isR931Verified,
                    931,
                    @"[In RopCreateFolder ROP Response Buffer] This field [IsGhosted] is present only if the IsExistingFolder field is set to a nonzero (TRUE) value and only for folders that are in a public message store.");

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

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R68.
                Site.CaptureRequirementIfAreEqual<byte?>(
                    0x00,
                    createFolderResponse.IsGhosted,
                    68,
                    @"[In RopCreateFolder ROP Response Buffer] IsGhosted (1 byte): otherwise [If the server hosts an active replica of the folder], this field [IsGhosted] is set to zero (FALSE).");
            }
            #endregion

            #region Step 5. The client gets the PidTagAddressBookEntryId property of the [MSOXCFOLD_PublicFolderMailEnabled].
            if (Common.IsRequirementEnabled(350002, this.Site))
            {
                PropertyTag[] propertyTagArray = new PropertyTag[1];
                PropertyTag propertyTag = new PropertyTag
                {
                    PropertyId = (ushort)FolderPropertyId.PidTagAddressBookEntryId,
                    PropertyType = (ushort)PropertyType.PtypBinary
                };
                propertyTagArray[0] = propertyTag;

                RopGetPropertiesSpecificRequest getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest();
                RopGetPropertiesSpecificResponse getPropertiesSpecificResponse;
                getPropertiesSpecificRequest.RopId = (byte)RopId.RopGetPropertiesSpecific;
                getPropertiesSpecificRequest.LogonId = Constants.CommonLogonId;
                getPropertiesSpecificRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
                getPropertiesSpecificRequest.PropertySizeLimit = 0xFFFF;
                getPropertiesSpecificRequest.PropertyTagCount = (ushort)propertyTagArray.Length;
                getPropertiesSpecificRequest.PropertyTags = propertyTagArray;

                getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, subfolderHandle1, ref this.responseHandles);
                Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!");

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

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R350002.
                // The property value is returned if Flag value is 0x00.
                Site.CaptureRequirementIfAreEqual<byte>(
                    0x00,
                    getPropertiesSpecificResponse.RowData.Flag,
                    350002,
                    @"[In Appendix A: Product Behavior] The implementation does support the PidTagAddressBookEntryId property. (Exchange 2007 and Exchange 2010 follow this behavior).");

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

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R350.
                // The property value is returned if Flag value is 0x00.
                Site.CaptureRequirementIfAreEqual<byte>(
                    0x00,
                    getPropertiesSpecificResponse.RowData.Flag,
                    350,
                    @"[In PidTagAddressBookEntryId Property] This property is set only for public folders.");
            }
            #endregion

            #region Step 6. The client calls RopGetPropertiesAll on [MSOXCFOLD_PublicFolderGhosted].
            RopGetPropertiesAllResponse getAllPropertiesResponse = this.Adapter.GetFolderPropertiesAll(subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, getAllPropertiesResponse.ReturnValue, "RopGetPropertiesAllResponse ROP operation performs successfully!");
            #endregion
        }
        /// <summary>
        /// Initialize a generic folder under the Inbox folder as a root folder for test.
        /// </summary>
        private void PublicFolderInitialization()
        {
            #region Open the public folder.
            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
            {
                RopId = (byte)RopId.RopOpenFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                FolderId = this.logonResponse.FolderIds[Constants.PublicFolderIndex],
                OpenModeFlags = (byte)FolderOpenModeFlags.None
            };

            // Use the logon object as input handle here.
            RopOpenFolderResponse openFolderResponse = this.Adapter.OpenFolder(openFolderRequest, this.publicLogonHandle, ref this.responseHandles);
            this.publicFoldersHandle = this.responseHandles[0][openFolderResponse.OutputHandleIndex];
            #endregion

            #region Create a generic folder for test.
            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(this.RootFolder),
                Comment = Encoding.ASCII.GetBytes(this.RootFolder)
            };
            RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.publicFoldersHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, createFolderResponse.ReturnValue, "Creating Folder should succeed.");
            this.publicRootFolderHandle = this.responseHandles[0][createFolderResponse.OutputHandleIndex];
            this.publicRootFolderId = createFolderResponse.FolderId;
            #endregion
        }
        /// <summary>
        /// Opens an existing folder.
        /// </summary>
        /// <param name="ropOpenFolderRequest">RopOpenFolderRequest object.</param>
        /// <param name="insideObjHandle">Server object handle in RopOpenFolderRequest.</param>
        /// <param name="responseSOHTable">Server objects handles in RopOpenFolderResponse.</param>
        /// <returns>RopOpenFolderResponse object.</returns>
        public RopOpenFolderResponse OpenFolder(RopOpenFolderRequest ropOpenFolderRequest, uint insideObjHandle, ref List<List<uint>> responseSOHTable)
        {
            object temp = new object();
            ropOpenFolderRequest.RopId = (byte)RopId.RopOpenFolder;
            ropOpenFolderRequest.LogonId = Constants.CommonLogonId;
            ropOpenFolderRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
            ropOpenFolderRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex;
            this.ExcuteRopCall((ISerializable)ropOpenFolderRequest, insideObjHandle, ref temp, ref responseSOHTable, ref this.rawData);
            RopOpenFolderResponse ropOpenFolderResponse = (RopOpenFolderResponse)temp;

            #region Capture Code
            // The ReturnValue equal to 0x00000000 indicate ROP operation success
            if (0x00000000 == ropOpenFolderResponse.ReturnValue)
            {
                this.VerifyRopOpenFolder(ropOpenFolderResponse);
            }
            #endregion

            return ropOpenFolderResponse;
        }
        /// <summary>
        /// The method is used to clean up the inbox folder. 
        /// </summary>
        private void CleanInbox()
        {
            RopLogonResponse logonResponse = this.Logon(out this.inputObjHandle);
            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
            {
                RopId = 0x02,
                LogonId = 0x00,
                InputHandleIndex = 0x00,
                OutputHandleIndex = 0x01,
                FolderId = logonResponse.FolderIds[4],
                OpenModeFlags = 0x00
            };
            this.responseSOHs = this.DoSingleCallROP(openFolderRequest, this.inputObjHandle, ref this.response, ref this.rawData);
            Site.Assert.AreEqual<uint>(0, ((RopOpenFolderResponse)this.response).ReturnValue, "Return value should be 0");
            this.inboxFolderHandle = this.responseSOHs[0][((RopOpenFolderResponse)this.response).OutputHandleIndex];

            RopHardDeleteMessagesAndSubfoldersRequest hardDeleteMessagesAndSubfoldersRequest;
            hardDeleteMessagesAndSubfoldersRequest.RopId = 0x92;
            hardDeleteMessagesAndSubfoldersRequest.LogonId = 0x00;
            hardDeleteMessagesAndSubfoldersRequest.InputHandleIndex = 0x00;
            hardDeleteMessagesAndSubfoldersRequest.WantAsynchronous = 0x00; // Synchronously
            hardDeleteMessagesAndSubfoldersRequest.WantDeleteAssociated = 0xFF; // TRUE: delete all messages and subfolders
            object temp = new object();
            this.DoSingleCallROP(hardDeleteMessagesAndSubfoldersRequest, this.inboxFolderHandle, ref temp, ref this.rawData);
            Site.Assert.AreEqual<uint>(0, ((RopHardDeleteMessagesAndSubfoldersResponse)temp).ReturnValue, "Return value should be 0");

            // Waiting for the server to solve the delete request.
            Thread.Sleep(this.waitTime);
            this.VerifyMailCount(0);
        }
        /// <summary>
        /// Get Opened Folder Handle
        /// </summary>
        /// <param name="folderId">The folder id be used to open folder</param>
        /// <param name="logonHandle">The RopLogon handle</param>
        /// <returns>Return created Message Handle</returns>
        protected uint OpenSpecificFolder(ulong folderId, uint logonHandle)
        {
            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest()
            {
                RopId = (byte)RopId.RopOpenFolder,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                OutputHandleIndex = CommonOutputHandleIndex,
                FolderId = folderId,
                OpenModeFlags = (byte)FolderOpenModeFlags.None
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openFolderRequest, logonHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);

            RopOpenFolderResponse openFolderResponse = (RopOpenFolderResponse)this.response;
            Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openFolderResponse.ReturnValue, "Call RopOpenFolder should success.");

            uint openedFolderHandle = this.ResponseSOHs[0][openFolderResponse.OutputHandleIndex];
            return openedFolderHandle;
        }
        /// <summary>
        /// Clean the Inbox folder in private mailbox.
        /// </summary>
        /// <param name="folderID">The specified folder's FID.</param>
        private void CleanFolder(ulong folderID)
        {
            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
            {
                RopId = (byte)RopId.RopOpenFolder,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                OutputHandleIndex = CommonOutputHandleIndex,
                FolderId = folderID,
                OpenModeFlags = 0x00
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openFolderRequest, this.insideObjHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            uint folderHandle = this.ResponseSOHs[0][((RopOpenFolderResponse)this.response).OutputHandleIndex];

            RopHardDeleteMessagesAndSubfoldersRequest hardDeleteMessagesAndSubfoldersRequest = new RopHardDeleteMessagesAndSubfoldersRequest()
            {
                RopId = (byte)RopId.RopHardDeleteMessagesAndSubfolders,
                LogonId = CommonLogonId,
                InputHandleIndex = CommonInputHandleIndex,
                WantAsynchronous = 0x00, // Synchronously
                WantDeleteAssociated = 0xFF // TRUE: delete all messages and subfolders
            };
            object temp = new object();
            this.MSOXCMSGAdapter.DoRopCall(hardDeleteMessagesAndSubfoldersRequest, folderHandle, ref temp, ref this.rawData, GetPropertiesFlags.None);
        }