public void MSOXORULE_S02_TC05_ServerExecuteRule_Action_OP_DELETE()
        {
            this.CheckMAPIHTTPTransportSupported();

            #region Prepare value for ruleProperties variable.
            RuleProperties ruleProperties = AdapterHelper.GenerateRuleProperties(this.Site, Constants.RuleNameCopy);
            #endregion

            #region TestUser1 creates a new folder in server store.
            RopCreateFolderResponse createFolderResponse;
            uint newFolderHandle = this.OxoruleAdapter.RopCreateFolder(this.InboxFolderHandle, Common.GenerateResourceName(this.Site, "User1Folder"), "TestForOP_COPY", out createFolderResponse);
            ulong newFolderId = createFolderResponse.FolderId;
            Site.Assert.AreEqual<uint>(0, createFolderResponse.ReturnValue, "Creating folder operation should succeed.");
            #endregion

            #region Prepare rules' data.
            MoveCopyActionData moveCopyActionData = new MoveCopyActionData();

            // Get the created folder entry ID.
            ServerEID serverEID = new ServerEID(BitConverter.GetBytes(newFolderId));
            byte[] folderEId = serverEID.Serialize();

            // Get the store object's entry ID.
            byte[] storeEId = this.GetStoreObjectEntryID(StoreObjectType.Mailbox, this.Server, this.User1ESSDN);
            moveCopyActionData.FolderInThisStore = 1;
            moveCopyActionData.FolderEID = folderEId;
            moveCopyActionData.StoreEID = storeEId;
            moveCopyActionData.FolderEIDSize = (ushort)folderEId.Length;
            moveCopyActionData.StoreEIDSize = (ushort)storeEId.Length;
            RuleData ruleForCopy = AdapterHelper.GenerateValidRuleData(ActionType.OP_COPY, TestRuleDataType.ForAdd, 1, RuleState.ST_ENABLED, moveCopyActionData, ruleProperties, null);
            #endregion

            #region TestUser1 adds OP_COPY rule to the Inbox folder.
            RopModifyRulesResponse modifyRulesResponse = this.OxoruleAdapter.RopModifyRules(this.InboxFolderHandle, ModifyRuleFlag.Modify_ReplaceAll, new RuleData[] { ruleForCopy });
            Site.Assert.AreEqual<uint>(0, modifyRulesResponse.ReturnValue, "Adding Copy rule should succeed.");
            #endregion

            #region TestUser1 adds OP_DELETE rule for Inbox folder with rule Sequence set to 2.
            ruleProperties.Name = Common.GenerateResourceName(this.Site, Constants.RuleNameDelete);
            RuleData ruleForDelete = AdapterHelper.GenerateValidRuleData(ActionType.OP_DELETE, TestRuleDataType.ForAdd, 2, RuleState.ST_ENABLED, new DeleteMarkReadActionData(), ruleProperties, null);
            RopModifyRulesResponse ropModifyRulesResponse = this.OxoruleAdapter.RopModifyRules(this.InboxFolderHandle, ModifyRuleFlag.Modify_OnExisting, new RuleData[] { ruleForDelete });
            Site.Assert.AreEqual<uint>(0, ropModifyRulesResponse.ReturnValue, "Adding the delete rule should succeed.");
            #endregion

            #region TestUser1 adds OP_FORWARD rule with rule sequence set to 3.
            ruleProperties.Name = Common.GenerateResourceName(this.Site, Constants.RuleNameForward);
            ForwardDelegateActionData forwardActionData = new ForwardDelegateActionData
            {
                RecipientCount = (ushort)0x01
            };
            RecipientBlock recipientBlock = new RecipientBlock
            {
                Reserved = 0x01,
                NoOfProperties = (ushort)0x04u
            };

            #region Prepare the recipient Block.
            TaggedPropertyValue[] recipientProperties = AdapterHelper.GenerateRecipientPropertiesBlock(this.User2Name, this.User2ESSDN);

            recipientBlock.PropertiesData = recipientProperties;
            #endregion

            forwardActionData.RecipientsData = new RecipientBlock[1] { recipientBlock };
            RuleData ruleForward = AdapterHelper.GenerateValidRuleData(ActionType.OP_FORWARD, TestRuleDataType.ForAdd, 3, RuleState.ST_ENABLED, forwardActionData, ruleProperties, null);
            ropModifyRulesResponse = this.OxoruleAdapter.RopModifyRules(this.InboxFolderHandle, ModifyRuleFlag.Modify_OnExisting, new RuleData[] { ruleForward });
            Site.Assert.AreEqual<uint>(0, ropModifyRulesResponse.ReturnValue, "Adding Forward rule should succeed");
            #endregion

            #region Get the rule properties in the Inbox of TestUser1.
            RopGetRulesTableResponse ropGetRulesTableResponse = new RopGetRulesTableResponse();
            uint ruleTableHandler = this.OxoruleAdapter.RopGetRulesTable(this.InboxFolderHandle, TableFlags.Normal, out ropGetRulesTableResponse);
            Site.Assert.AreEqual<uint>(0, ropGetRulesTableResponse.ReturnValue, "Getting rule table operation should succeed.");

            PropertyTag[] propertyTags = new PropertyTag[2];

            // PidTagRuleFolderEntryId
            propertyTags[0].PropertyId = (ushort)PropertyId.PidTagRuleFolderEntryId;
            propertyTags[0].PropertyType = (ushort)PropertyType.PtypBinary;

            // PidTagRuleLevel
            propertyTags[1].PropertyId = (ushort)PropertyId.PidTagRuleLevel;
            propertyTags[1].PropertyType = (ushort)PropertyType.PtypInteger32;

            RopQueryRowsResponse ropQueryRowsResponse = this.OxoruleAdapter.QueryPropertiesInTable(ruleTableHandler, propertyTags);
            Site.Assert.AreEqual<uint>(0, ropQueryRowsResponse.ReturnValue, "Query rows operation should succeed.");

            // Three rules have been added to the Inbox folder, so the row count in the rule table should be 3.
            Site.Assert.AreEqual<uint>(3, ropQueryRowsResponse.RowCount, "The rule number in the rule table is {0}", ropQueryRowsResponse.RowCount);
            this.VerifyRuleTable();
            #endregion

            #region TestUser2 deliver a message to TestUser1 to trigger these rules
            // Wait for the mail to be received and the rule to take effect.
            Thread.Sleep(this.WaitForTheRuleToTakeEffect);
            string mailSubject = Common.GenerateResourceName(this.Site, ruleProperties.ConditionSubjectName + "Title");
            this.SUTAdapter.SendMailToRecipient(this.User2Name, this.User2Password, this.User1Name, mailSubject);

            // Wait for the mail to be received and the rule to take effect.
            Thread.Sleep(this.WaitForTheRuleToTakeEffect);
            #endregion

            #region TestUser1 checks whether the origin message is deleted.
            // Set PidTagSubject and PidTagMessageFlags visible.
            PropertyTag[] propertyTag = new PropertyTag[2];
            propertyTag[0].PropertyId = (ushort)PropertyId.PidTagSubject;
            propertyTag[0].PropertyType = (ushort)PropertyType.PtypString;
            propertyTag[1].PropertyId = (ushort)PropertyId.PidTagMessageFlags;
            propertyTag[1].PropertyType = (ushort)PropertyType.PtypInteger32;

            // Get mail message content.
            uint contentsTableHandle = 0;
            bool doesUnexpectedMessageExist = this.CheckUnexpectedMessageExist(this.InboxFolderHandle, ref contentsTableHandle, propertyTag, mailSubject);

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

            // Verify MS-OXORULE requirement: MS-OXORULE_R931.
            // In this test case, the server-side rule is OP_DELETE, and the actions specified in the PidTagRuleActions property associated with this rule is to delete the incoming message. 
            // TestUser2 has sent a message to TestUser1. If the message doesn't appear in TestUser1's mailbox, it means the server has deleted the incoming message. This requirement can be verified.
            Site.CaptureRequirementIfIsFalse(
                doesUnexpectedMessageExist,
                931,
                @"[In Processing Incoming Messages to a Folder] When executing a rule (2) whose condition evaluates to ""TRUE"" as per the restriction (2) in the PidTagRuleCondition property (section 2.2.1.3.1.9), then the server MUST perform the actions (2) specified in the PidTagRuleActions property (section 2.2.1.3.1.10) associated with that rule (2) in the case of a server-side rule.");

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

                Site.CaptureRequirementIfIsFalse(
                    doesUnexpectedMessageExist,
                    898,
                    @"[In OP_DELETE or OP_MARK_AS_READ Data Buffer Format] For the OP_DELETE action type, the implementation does delete the incoming messages according to the ActionType itself. (Windows Exchange 2003 and above follow this behavior)");
            }

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

            // Verify MS-OXORULE requirement: MS-OXORULE_R549.
            // TestUser2 has sent a message to TestUser1. If the message doesn't appear in TestUser1's mailbox, it means the server has deleted the incoming message. This requirement can be verified.
            Site.CaptureRequirementIfIsFalse(
                doesUnexpectedMessageExist,
                549,
                @"[In Processing Incoming Messages to a Folder] [Following is a description of what the server does when it executes each action (2) type, as specified in section 2.2.5.1.1, for an incoming message] ""OP_DELETE"": The server MUST delete the message.");

            #endregion
            #endregion

            #region TestUser2 checks whether a forward message is received.
            this.LogonMailbox(TestUser.TestUser2);
            bool doesUnexpectedMessageExist2 = this.CheckUnexpectedMessageExist(this.InboxFolderHandle, ref contentsTableHandle, propertyTag, mailSubject);

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

            // Verify MS-OXORULE requirement: MS-OXORULE_R550.
            // In this test case, if the forward message doesn't appear in TestUser2's mailbox, it means the subsequent OP_FORWARD rule, which is not an Out of Office rule, is not executed.
            Site.CaptureRequirementIfIsFalse(
                doesUnexpectedMessageExist2,
                550,
                @"[In Processing Incoming Messages to a Folder] [Following is a description of what the server does when it executes each action (2) type, as specified in section 2.2.5.1.1, for an incoming message] ""OP_DELETE"": The server MUST stop evaluating subsequent rules (2) on the message except for Out of Office rules.");
            #endregion

            #region Delete the newly created folder.
            this.LogonMailbox(TestUser.TestUser1);
            RopDeleteFolderResponse deleteFolder = this.OxoruleAdapter.RopDeleteFolder(this.InboxFolderHandle, newFolderId);
            Site.Assert.AreEqual<uint>(0, deleteFolder.ReturnValue, "Deleting folder should succeed.");
            #endregion
        }
        public void MSOXORULE_S02_TC09_ServerExecuteRule_Action_OP_TAG()
        {
            this.CheckMAPIHTTPTransportSupported();

            #region Prepare value for ruleProperties variable.
            RuleProperties ruleProperties = AdapterHelper.GenerateRuleProperties(this.Site, Constants.RuleNameTag);
            #endregion

            #region TestUser1 adds an OP_TAG rule to the Inbox folder.
            TagActionData tagActionData = new TagActionData();
            PropertyTag tagActionDataPropertyTag = new PropertyTag
            {
                PropertyId = (ushort)PropertyId.PidTagImportance,
                PropertyType = (ushort)PropertyType.PtypInteger32
            };
            tagActionData.PropertyTag = tagActionDataPropertyTag;
            tagActionData.PropertyValue = BitConverter.GetBytes(2);

            RuleData ruleOpTag = AdapterHelper.GenerateValidRuleData(ActionType.OP_TAG, TestRuleDataType.ForAdd, 1, RuleState.ST_ENABLED, tagActionData, ruleProperties, null);
            RopModifyRulesResponse modifyRulesResponse = this.OxoruleAdapter.RopModifyRules(this.InboxFolderHandle, ModifyRuleFlag.Modify_ReplaceAll, new RuleData[] { ruleOpTag });
            Site.Assert.AreEqual<uint>(0, modifyRulesResponse.ReturnValue, "Adding OP_TAG rule should succeed.");
            #endregion

            #region TestUser2 delivers a message to TestUser1.

            // Wait for the mail to be received and the rule to take effect.
            Thread.Sleep(this.WaitForTheRuleToTakeEffect);
            string mailSubject = Common.GenerateResourceName(this.Site, ruleProperties.ConditionSubjectName + "Title");

            // TestUser2 delivers a message to trigger these rules.
            this.SUTAdapter.SendMailToRecipient(this.User2Name, this.User2Password, this.User1Name, mailSubject);

            // Wait for the mail to be received and the rule to take effect.
            Thread.Sleep(this.WaitForTheRuleToTakeEffect);
            #endregion

            #region TestUser1 gets the message and its properties to verify the rule evaluation.
            PropertyTag[] propertyTagList = new PropertyTag[2];
            propertyTagList[0].PropertyId = (ushort)PropertyId.PidTagImportance;
            propertyTagList[0].PropertyType = (ushort)PropertyType.PtypInteger32;
            propertyTagList[1].PropertyId = (ushort)PropertyId.PidTagSubject;
            propertyTagList[1].PropertyType = (ushort)PropertyType.PtypString;

            uint contentTableHandle = 0;
            int expectedMessageIndex = 0;
            RopQueryRowsResponse getMailMessageContent = this.GetExpectedMessage(this.InboxFolderHandle, ref contentTableHandle, propertyTagList, ref expectedMessageIndex, mailSubject);

            // Add the debug information.
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXORULE_R548: the value of PidTagImportance is {0}", BitConverter.ToInt32(getMailMessageContent.RowData.PropertyRows[expectedMessageIndex].PropertyValues[0].Value, 0));

            // Verify MS-OXORULE requirement: MS-OXORULE_R548.
            // If the PidTagImportance is 2 which is set on OP_TAG rule, it means the rule tacks action and the rule sets the property specified in the rule's action buffer structure.
            bool isVerifyR548 = BitConverter.ToInt32(getMailMessageContent.RowData.PropertyRows[expectedMessageIndex].PropertyValues[0].Value, 0) == 2;

            Site.CaptureRequirementIfIsTrue(
                isVerifyR548,
                548,
                @"[In Processing Incoming Messages to a Folder] [Following is a description of what the server does when it executes each action (2) type, as specified in section 2.2.5.1.1, for an incoming message] ""OP_TAG"": The server MUST set on the message the property specified in the action buffer structure.");

            // Add the debug information.
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXORULE_R266: the value of PidTagImportance is {0}", BitConverter.ToInt32(getMailMessageContent.RowData.PropertyRows[expectedMessageIndex].PropertyValues[0].Value, 0));

            // Verify MS-OXORULE requirement: MS-OXORULE_R266.
            // If the PidTagImportance is 2 which is set on OP_TAG rule, it means the rule tacks action and the rule sets the property specified in the rule's action buffer structure.
            bool isVerifyR266 = BitConverter.ToInt32(getMailMessageContent.RowData.PropertyRows[expectedMessageIndex].PropertyValues[0].Value, 0) == 2;

            Site.CaptureRequirementIfIsTrue(
                isVerifyR266,
                266,
                @"[In ActionBlock Structure] The meaning of action type OP_TAG: Adds or changes a property on the message.");
            #endregion

            #region TestUser1 gets the rule action property to check the rule action property.
            uint ruleHandle;
            RopGetRulesTableResponse ruleTableResponse = new RopGetRulesTableResponse();
            ruleHandle = this.OxoruleAdapter.RopGetRulesTable(this.InboxFolderHandle, TableFlags.Normal, out ruleTableResponse);

            // Get rule property.
            PropertyTag[] ruleProperty = new PropertyTag[1];
            ruleProperty[0].PropertyId = (ushort)PropertyId.PidTagRuleActions;
            ruleProperty[0].PropertyType = (ushort)PropertyType.PtypRuleAction;
            RopQueryRowsResponse queryRowResponseOfProperty = this.OxoruleAdapter.QueryPropertiesInTable(ruleHandle, ruleProperty);
            Site.Assert.AreEqual<uint>(0, queryRowResponseOfProperty.ReturnValue, "Getting the rule action property should succeed, the actual value is {0}!", queryRowResponseOfProperty.ReturnValue);
            #endregion
        }
        /// <summary>
        /// Verify RopGetRulesTable Response
        /// </summary>
        /// <param name="ropGetRulesTableResponse">The response of RopGetRulesTable request</param>
        private void VerifyRopGetRulesTableResponse(RopGetRulesTableResponse ropGetRulesTableResponse)
        {
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R3612");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R3612
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropGetRulesTableResponse.RopId.GetType(),
                3612,
                @"[In RopGetRulesTable ROP Response Buffer] RopId (1 byte): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R3614
            Site.CaptureRequirementIfAreEqual<byte>(
                (byte)RopId.RopGetRulesTable,
                ropGetRulesTableResponse.RopId,
                3614,
                @"[In RopGetRulesTable ROP Response Buffer,RopId (1 byte):] For this operation[RopGetRulesTable] this field is set to 0x3F.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R3615
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropGetRulesTableResponse.OutputHandleIndex.GetType(),
                3615,
                @"[In RopGetRulesTable ROP Response Buffer]OutputHandleIndex (1 byte): An unsigned integer.");

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

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R3618
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(uint),
                ropGetRulesTableResponse.ReturnValue.GetType(),
                3618,
                @"[In RopGetRulesTable ROP Response Buffer] ReturnValue (4 bytes): An unsigned integer.");
        }
        /// <summary>
        /// Verify the RopGetRulesTable operation.
        /// </summary>
        /// <param name="ropGetRulesTableResponse">RopGetRulesTable response buffer.</param>
        /// <param name="ropGetRulesTableRequest">RopGetRulesTable request buffer.</param>
        private void VerifyRopGetRulesTable(RopGetRulesTableResponse ropGetRulesTableResponse, RopGetRulesTableRequest ropGetRulesTableRequest)
        {
            // Add the debug information.
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXORULE_R690");

            // Verify MS-OXORULE requirement: MS-OXORULE_R690.
            Site.CaptureRequirementIfAreEqual<byte>(
                ropGetRulesTableRequest.OutputHandleIndex,
                ropGetRulesTableResponse.OutputHandleIndex,
                690,
                @"[In RopGetRulesTable ROP Response Buffer] OutputHandleIndex (1 byte): MUST be set to the value of the OutputHandleIndex field specified in the request.");
        }
        /// <summary>
        /// This ROP gets the rules table of a folder.
        /// </summary>
        /// <param name="objHandle">This index refers to the location in the Server object handle table used to find the handle for this operation.</param>
        /// <param name="tableFlags">These Flags control the Type of table. The possible values are specified in [MS-OXORULE].</param>
        /// <param name="getRulesTableResponse">Structure of RopGetRulesTableResponse.</param>
        /// <returns>Table handle.</returns>
        public uint RopGetRulesTable(uint objHandle, TableFlags tableFlags, out RopGetRulesTableResponse getRulesTableResponse)
        {
            this.rawData = null;
            this.response = null;
            this.responseSOHs = null;

            RopGetRulesTableRequest getRulesTableRequest;

            getRulesTableRequest.RopId = 0x3F;
            getRulesTableRequest.LogonId = 0x00;
            getRulesTableRequest.InputHandleIndex = 0x00;
            getRulesTableRequest.OutputHandleIndex = 0x01;
            getRulesTableRequest.TableFlags = (byte)tableFlags;

            this.responseSOHs = this.DoRPCCall(getRulesTableRequest, objHandle, ref this.response, ref this.rawData);
            getRulesTableResponse = (RopGetRulesTableResponse)this.response;
            uint tableHandle = this.responseSOHs[0][getRulesTableResponse.OutputHandleIndex];

            // Verify the response of RopGetRulesTable 
            this.VerifyRopGetRulesTable(getRulesTableResponse, getRulesTableRequest);
            return tableHandle;
        }