/// <summary>
        /// This method is used to add a request to the request collection in the request envelope body.
        /// </summary>
        /// <param name="url">Specify the URL of the file to edit.</param>
        /// <param name="subRequests">Specify the sub request array.</param>
        /// <param name="requestToken">Specify the token which uniquely identify the request.</param>
        /// <param name="interval">Specify a nonnegative integer in seconds, which the protocol client will repeat this request.</param>
        /// <param name="metaData">Specify a 32-bit value that specifies information about the scenario and urgency of the request.</param>
        public void AddRequest(string url, SubRequestType[] subRequests, string requestToken, uint? interval, int? metaData)
        {
            Request request = new Request();
            request.RequestToken = requestToken;
            request.Url = url;
            request.Interval = interval == null ? null : interval.Value.ToString();
            request.MetaData = metaData == null ? null : metaData.Value.ToString();

            int index = 0;
            if (subRequests != null)
            {
                request.SubRequest = new SubRequestElementGenericType[subRequests.Length];
                foreach (SubRequestType item in subRequests)
                {
                    if (item != null)
                    {
                        request.SubRequest[index++] = FsshttpConverter.ConvertSubRequestToGenericType<SubRequestElementGenericType>(item);
                    }
                }
            }
            else
            {
                throw new System.ArgumentException("subRequests parameter in FSSHTTPMessageBodyWriter::AddRequest cannot be null.");
            }

            List<Request> requestList = this.requestEnvelope.RequestCollection.Request == null ? new List<Request>(1) : new List<Request>(this.requestEnvelope.RequestCollection.Request);
            requestList.Add(request);

            this.requestEnvelope.RequestCollection.Request = requestList.ToArray();
        }
        /// <summary>
        /// Create a Sync Change request by using the specified sync key, folder collectionId and change application data.
        /// </summary>
        /// <param name="syncKey">Specify the sync key obtained from the last Sync response.</param>
        /// <param name="collectionId">Specify the serverId of the folder to be synchronized.</param>
        /// <param name="changeData">The data used to specify the Change element for Sync command.</param>
        /// <returns>The SyncRequest instance.</returns>
        internal static SyncRequest CreateSyncChangeRequest(string syncKey, string collectionId, Request.SyncCollectionChange changeData)
        {
            Request.SyncCollection syncCollection = CreateSyncCollection(syncKey, collectionId);
            syncCollection.Commands = new object[] { changeData };

            return Common.CreateSyncRequest(new Request.SyncCollection[] { syncCollection });
        }
        /// <summary>
        /// Builds an ItemOperations request to fetch the whole content of the tasks.
        /// </summary>
        /// <param name="collectionId">Specify the tasks folder.</param>
        /// <param name="serverIds">Specify a unique identifier that is assigned by the server for the tasks.</param>
        /// <param name="longIds">Specifies a unique identifier that was assigned by the server to each result returned by a previous Search response.</param>
        /// <param name="bodyPreference">Sets preference information related to the type and size of the body.</param>
        /// <param name="schema">Specifies the schema of the item to be fetched.</param>
        /// <returns>Returns the ItemOperationsRequest instance</returns>
        internal static ItemOperationsRequest CreateItemOperationsFetchRequest(
            string collectionId,
            List<string> serverIds,
            List<string> longIds,
            Request.BodyPreference bodyPreference,
            Request.Schema schema)
        {
            Request.ItemOperationsFetchOptions fetchOptions = new Request.ItemOperationsFetchOptions();
            List<object> fetchOptionItems = new List<object>();
            List<Request.ItemsChoiceType5> fetchOptionItemsName = new List<Request.ItemsChoiceType5>();

            if (null != bodyPreference)
            {
                fetchOptionItemsName.Add(Request.ItemsChoiceType5.BodyPreference);
                fetchOptionItems.Add(bodyPreference);
            }

            if (null != schema)
            {
                fetchOptionItemsName.Add(Request.ItemsChoiceType5.Schema);
                fetchOptionItems.Add(schema);
            }

            fetchOptions.Items = fetchOptionItems.ToArray();
            fetchOptions.ItemsElementName = fetchOptionItemsName.ToArray();

            List<Request.ItemOperationsFetch> fetchElements = new List<Request.ItemOperationsFetch>();

            if (serverIds != null)
            {
                foreach (string serverId in serverIds)
                {
                    Request.ItemOperationsFetch fetchElement = new Request.ItemOperationsFetch()
                    {
                        CollectionId = collectionId,
                        ServerId = serverId,
                        Store = SearchName.Mailbox.ToString(),
                        Options = fetchOptions
                    };
                    fetchElements.Add(fetchElement);
                }
            }

            if (longIds != null)
            {
                foreach (string longId in longIds)
                {
                    Request.ItemOperationsFetch fetchElement = new Request.ItemOperationsFetch()
                    {
                        LongId = longId,
                        Store = SearchName.Mailbox.ToString(),
                        Options = fetchOptions
                    };
                    fetchElements.Add(fetchElement);
                }
            }

            return Common.CreateItemOperationsRequest(fetchElements.ToArray());
        }
        /// <summary>
        /// Create an initial Sync request by using the specified collection Id.
        /// </summary>
        /// <param name="collectionId">Identify the folder as the collection being synchronized.</param>
        /// <param name="supportedElements">The elements in Supported element.</param>
        /// <returns>The SyncRequest instance.</returns>
        internal static SyncRequest CreateInitialSyncRequest(string collectionId, Request.Supported supportedElements)
        {
            Request.SyncCollection syncCollection = new Request.SyncCollection
            {
                CollectionId = collectionId,
                SyncKey = "0",
                Supported = supportedElements
            };

            return Common.CreateSyncRequest(new Request.SyncCollection[] { syncCollection });
        }
        /// <summary>
        /// Create a Sync Add request.
        /// </summary>
        /// <param name="syncKey">Specify the sync key obtained from the last Sync response</param>
        /// <param name="collectionId">Specify the serverId of the folder to be synchronized.</param>
        /// <param name="applicationData">The data used to specify the Add element for Sync command.</param>
        /// <returns>The SyncRequest instance.</returns>
        internal static SyncRequest CreateSyncAddRequest(string syncKey, string collectionId, Request.SyncCollectionAddApplicationData applicationData)
        {
            SyncRequest syncAddRequest = TestSuiteHelper.CreateSyncRequest(syncKey, collectionId, null);
            Request.SyncCollectionAdd add = new Request.SyncCollectionAdd
            {
                ClientId = Guid.NewGuid().ToString("N"),
                ApplicationData = applicationData
            };

            List<object> commandList = new List<object> { add };

            syncAddRequest.RequestData.Collections[0].Commands = commandList.ToArray();

            return syncAddRequest;
        }
        /// <summary>
        /// Get the request of Sync command.
        /// </summary>
        /// <param name="collectionId">The collection id of the folder to sync.</param>
        /// <param name="syncKey">The SyncKey of the latest sync.</param>
        /// <param name="bodyPartPreference">The bodyPartPreference in the options element.</param>
        /// <param name="bodyPreference">The bodyPreference in the options element.</param>
        /// <param name="conversationMode">The value of ConversationMode element.</param>
        /// <returns>The request of Sync command.</returns>
        internal static SyncRequest GetSyncRequest(string collectionId, string syncKey, Request.BodyPartPreference bodyPartPreference, Request.BodyPreference bodyPreference, bool conversationMode)
        {
            // Create the Sync command request.
            Request.SyncCollection[] synCollections = new Request.SyncCollection[1];
            synCollections[0] = new Request.SyncCollection { SyncKey = syncKey, CollectionId = collectionId };

            List<object> items = new List<object>();
            List<Request.ItemsChoiceType1> itemsElementName = new List<Request.ItemsChoiceType1>();

            if (bodyPartPreference != null)
            {
                items.Add(bodyPartPreference);
                itemsElementName.Add(Request.ItemsChoiceType1.BodyPartPreference);
            }

            if (bodyPreference != null)
            {
                items.Add(bodyPreference);
                itemsElementName.Add(Request.ItemsChoiceType1.BodyPreference);
            }

            if (conversationMode)
            {
                synCollections[0].ConversationMode = true;
                synCollections[0].ConversationModeSpecified = true;
                synCollections[0].Options = new Request.Options[1];
                synCollections[0].Options[0] = new Request.Options
                {
                    ItemsElementName = new Request.ItemsChoiceType1[] { Request.ItemsChoiceType1.FilterType },
                    Items = new object[] { (byte)1 }
                };
            }

            if (items.Count > 0)
            {
                synCollections[0].Options = new Request.Options[]
                {
                    new Request.Options()
                    {
                        ItemsElementName = itemsElementName.ToArray(),
                        Items = items.ToArray()
                    }
                };
            }

            return Common.CreateSyncRequest(synCollections);
        }
        /// <summary>
        /// Builds a Sync add request by using the specified sync key, folder collection ID and add application data.
        /// In general, returns the XMl formatted Sync request as follows:
        /// <!--
        /// <?xml version="1.0" encoding="utf-8"?>
        /// <Sync xmlns="AirSync">
        ///   <Collections>
        ///     <Collection>
        ///       <SyncKey>0</SyncKey>
        ///       <CollectionId>5</CollectionId>
        ///       <GetChanges>1</GetChanges>
        ///       <WindowSize>152</WindowSize>
        ///        <Commands>
        ///            <Add>
        ///                <ServerId>5:1</ServerId>
        ///                <ApplicationData>
        ///                    ...
        ///                </ApplicationData>
        ///            </Add>
        ///        </Commands>
        ///     </Collection>
        ///   </Collections>
        /// </Sync>
        /// -->
        /// </summary>
        /// <param name="collectionId">Specify the server ID of the folder to be synchronized, which can be returned by ActiveSync FolderSync command(Refer to [MS-ASCMD]2.2.3.30.5)</param>
        /// <param name="syncKey">Specify the sync key obtained from the last sync response(Refer to [MS-ASCMD]2.2.3.166.4)</param>
        /// <param name="addCalendars">Contains the data used to specify the Add element for Sync command(Refer to [MS-ASCMD]2.2.3.7.2)</param>
        /// <returns>Returns the SyncRequest instance</returns>
        internal static SyncRequest CreateSyncAddRequest(string collectionId, string syncKey, Request.SyncCollectionAddApplicationData addCalendars)
        {
            SyncRequest syncAddRequest;
            Request.SyncCollectionAdd add = new Request.SyncCollectionAdd
            {
                ClientId = TestSuiteHelper.Next(),
                ApplicationData = addCalendars
            };

            List<object> commandList = new List<object> { add };

            // The Sync request include the GetChanges element of the Collection element will set to 0 (FALSE)
            syncAddRequest = TestSuiteHelper.CreateSyncRequest(collectionId, syncKey, false);
            syncAddRequest.RequestData.Collections[0].Commands = commandList.ToArray();

            return syncAddRequest;
        }
        /// <summary>
        /// Get the request of ItemOperations command.
        /// </summary>
        /// <param name="collectionId">The collection id of the folder to fetch.</param>
        /// <param name="serverId">The server id of the mail.</param>
        /// <param name="bodyPartPreference">The BodyPartPreference in the Options element.</param>
        /// <param name="bodyPreference">The BodyPreference in the Options element.</param>
        /// <returns>An ItemOperations command request.</returns>
        internal static ItemOperationsRequest GetItemOperationsRequest(string collectionId, string serverId, Request.BodyPartPreference bodyPartPreference, Request.BodyPreference bodyPreference)
        {
            ItemOperationsRequest request = new ItemOperationsRequest { RequestData = new Request.ItemOperations() };
            Request.ItemOperationsFetch fetch = new Request.ItemOperationsFetch
            {
                Store = SearchName.Mailbox.ToString(),
                CollectionId = collectionId,
                ServerId = serverId
            };

            List<object> items = new List<object>();
            List<Request.ItemsChoiceType5> itemsElementName = new List<Request.ItemsChoiceType5>();

            if (bodyPreference != null)
            {
                items.Add(bodyPreference);
                itemsElementName.Add(Request.ItemsChoiceType5.BodyPreference);
            }

            if (bodyPartPreference != null)
            {
                items.Add(bodyPartPreference);
                itemsElementName.Add(Request.ItemsChoiceType5.BodyPartPreference);
            }

            if (items.Count > 0)
            {
                fetch.Options = new Request.ItemOperationsFetchOptions()
                {
                    ItemsElementName = itemsElementName.ToArray(),
                    Items = items.ToArray()
                };
            }

            request.RequestData.Items = new object[] { fetch };

            return request;
        }
        /// <summary>
        /// Fetch item with specified ServerID on the server.
        /// </summary>
        /// <param name="collectionId">The collection id.</param>
        /// <param name="serverId">The server id of the mail.</param>
        /// <param name="fileReference">The file reference of the attachment.</param>
        /// <param name="bodyPreferences">The bodyPreference in the options element.</param>
        /// <param name="bodyPartPreferences">The bodyPartPreference in the options element.</param>
        /// <param name="deliveryMethod">Indicate whether use multipart or inline method to send the request.</param>
        /// <returns>The item with specified ServerID.</returns>
        protected DataStructures.ItemOperations GetItemOperationsResult(string collectionId, string serverId, string fileReference, Request.BodyPreference[] bodyPreferences, Request.BodyPartPreference[] bodyPartPreferences, DeliveryMethodForFetch? deliveryMethod)
        {
            DataStructures.ItemOperations item = null;
            ItemOperationsRequest request = TestSuiteHelper.CreateItemOperationsRequest(collectionId, serverId, fileReference, bodyPreferences, bodyPartPreferences);

            int counter = 0;
            int waitTime = int.Parse(Common.GetConfigurationPropertyValue("WaitTime", this.Site));
            int retryCount = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));

            do
            {
                Thread.Sleep(waitTime);
                DataStructures.ItemOperationsStore itemOperationsStore = this.ASAIRSAdapter.ItemOperations(request, deliveryMethod ?? DeliveryMethodForFetch.Inline);

                // Since the item serverId or attachment fileReference is unique, there should be only one item in response
                this.Site.Assert.AreEqual<int>(
                    1,
                    itemOperationsStore.Items.Count,
                    "The count of Items in ItemOperations command response should be 1.");

                if (itemOperationsStore.Items[0].Email != null)
                {
                    item = itemOperationsStore.Items[0];
                }
            }
            while (item == null && counter < retryCount);

            this.Site.Assert.IsNotNull(item, "The item should be found, retry count: {0}.", counter);

            return item;
        }
        /// <summary>
        /// Builds a initial Sync request by using the specified collection Id.
        /// In order to sync the content of a folder, an initial sync key for the folder MUST be obtained from the server.
        /// The client obtains the key by sending an initial Sync request with a SyncKey element value of zero and the CollectionId element
        /// In general, returns the XML formatted Sync request as follows:
        /// <!--
        /// <?xml version="1.0" encoding="utf-8"?>
        /// <Sync xmlns="AirSync">
        ///   <Collections>
        ///     <Collection>
        ///       <SyncKey>0</SyncKey>
        ///       <CollectionId>5</CollectionId>
        ///     </Collection>
        ///   </Collections>
        /// </Sync>
        /// -->
        /// </summary>
        /// <param name="collectionId">Identify the folder as the collection being synchronized, which can be returned by ActiveSync FolderSync command(Refer to [MS-ASCMD]2.2.3.30.5)</param>
        /// <param name="supported">Specifies which contact and calendar elements in a Sync request are managed by the client and therefore not ghosted.</param>
        /// <returns>Returns the SyncRequest instance</returns>
        internal static SyncRequest InitializeSyncRequest(string collectionId, Request.Supported supported)
        {
            Request.SyncCollection syncCollection = new Request.SyncCollection
            {
                Supported = supported,
                WindowSize = "512",
                CollectionId = collectionId,
                SyncKey = "0"
            };

            List<object> items = new List<object>();
            List<Request.ItemsChoiceType1> itemsElementName = new List<Request.ItemsChoiceType1>
            {
                Request.ItemsChoiceType1.BodyPreference
            };

            items.Add(
                new Request.BodyPreference()
                {
                    TruncationSize = 0,
                    TruncationSizeSpecified = false,
                    Type = 2,
                    Preview = 0,
                    PreviewSpecified = false,
                });

            Request.Options option = new Request.Options
            {
                Items = items.ToArray(),
                ItemsElementName = itemsElementName.ToArray()
            };

            syncCollection.Options = new Request.Options[] { option };

            SyncRequest request = Common.CreateSyncRequest(new Request.SyncCollection[] { syncCollection });

            return request;
        }
        /// <summary>
        /// Synchronize item with specified subject.
        /// </summary>
        /// <param name="subject">The subject of the item.</param>
        /// <param name="collectionId">The collection id which to sync with.</param>
        /// <param name="commands">The sync commands.</param>
        /// <param name="bodyPreferences">The bodyPreference in the options element.</param>
        /// <param name="bodyPartPreferences">The bodyPartPreference in the options element.</param>
        /// <returns>The item with specified subject.</returns>
        protected DataStructures.Sync GetSyncResult(string subject, string collectionId, object[] commands, Request.BodyPreference[] bodyPreferences, Request.BodyPartPreference[] bodyPartPreferences)
        {
            DataStructures.SyncStore syncStore;
            DataStructures.Sync item = null;
            SyncRequest request = TestSuiteHelper.CreateSyncRequest(this.GetInitialSyncKey(collectionId), collectionId, commands, bodyPreferences, bodyPartPreferences);

            int counter = 0;
            int waitTime = int.Parse(Common.GetConfigurationPropertyValue("WaitTime", this.Site));
            int retryCount = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));

            do
            {
                Thread.Sleep(waitTime);
                syncStore = this.ASAIRSAdapter.Sync(request);
                if (syncStore != null && syncStore.CollectionStatus == 1)
                {
                    item = TestSuiteHelper.GetSyncAddItem(syncStore, subject);
                }

                counter++;
            }
            while ((syncStore == null || item == null) && counter < retryCount);

            this.Site.Assert.IsNotNull(item, "The email item with subject {0} should be found, retry count: {1}.", subject, counter);

            this.SyncKey = syncStore.SyncKey;

            return item;
        }
        /// <summary>
        /// Builds a ItemOperations request to fetch the whole content of a single mail item
        /// by using the specified collectionId, emailServerId,bodyPreference and bodyPartPreference
        /// In general, returns the XML formatted ItemOperations request as follows:
        /// <!--
        /// <?xml version="1.0" encoding="utf-8"?>
        /// <ItemOperations xmlns="ItemOperations" xmlns:airsync="AirSync" xmlns:airsyncbase="AirSyncBase">
        ///    <Fetch>
        ///       <Store>Mailbox</Store>
        ///       <airsync:CollectionId>5</airsync:CollectionId>
        ///       <airsync:ServerId>5:1</airsync:ServerId>
        ///       <Options>
        ///          <airsync:MIMESupport>2</airsync:MIMESupport>
        ///          <airsyncbase:BodyPreference>
        ///             <airsyncbase:Type>4</airsyncbase:Type>
        ///          </airsyncbase:BodyPreference>
        ///          <airsyncbase:BodyPreference>
        ///             <airsyncbase:Type>2</airsyncbase:Type>
        ///          </airsyncbase:BodyPreference>
        ///       </Options>
        ///    </Fetch>
        /// </ItemOperations>
        /// -->
        /// </summary>
        /// <param name="collectionId">Specify the folder of mailItem, which can be returned by ActiveSync FolderSync command(Refer to [MS-ASCMD]2.2.3.30.2)</param>
        /// <param name="serverIds">Specify a unique identifier that was assigned by the server for a mailItem, which can be returned by ActiveSync Sync command(Refer to [MS-ASCMD]2.2.3.151.5)</param>
        /// <param name="schema">Sets the schema information</param>
        /// <returns>Returns the ItemOperationsRequest instance</returns>
        internal static ItemOperationsRequest CreateItemOperationsFetchRequest(string collectionId, List<string> serverIds, Request.Schema schema)
        {
            Request.ItemOperations itemOperations = new Request.ItemOperations();
            List<object> items = new List<object>();

            Request.ItemOperationsFetch fetchElement = new Request.ItemOperationsFetch();

            if (serverIds != null)
            {
                foreach (string item in serverIds)
                {
                    fetchElement.CollectionId = collectionId;
                    fetchElement.ServerId = item;
                    items.Add(fetchElement);
                }
            }

            itemOperations.Items = items.ToArray();

            foreach (object item in itemOperations.Items)
            {
                Request.ItemOperationsFetch fetch = item as Request.ItemOperationsFetch;
                if (fetch != null)
                {
                    fetch.Store = SearchName.Mailbox.ToString();
                    Request.ItemOperationsFetchOptions fetchOptions = new Request.ItemOperationsFetchOptions();

                    List<object> fetchOptionItems = new List<object>();
                    List<Request.ItemsChoiceType5> fetchOptionItemsName = new List<Request.ItemsChoiceType5>
                    {
                        Request.ItemsChoiceType5.BodyPreference,
                        Request.ItemsChoiceType5.Schema
                    };

                    fetchOptionItems.Add(
                        new Request.BodyPreference()
                        {
                            AllOrNone = false,
                            AllOrNoneSpecified = false,
                            TruncationSize = 0,
                            TruncationSizeSpecified = false,
                            Preview = 0,
                            PreviewSpecified = false,
                            Type = 2,
                        });
                    fetchOptionItems.Add(schema);

                    fetchOptions.Items = fetchOptionItems.ToArray();
                    fetchOptions.ItemsElementName = fetchOptionItemsName.ToArray();
                    fetch.Options = fetchOptions;
                }
            }

            return Common.CreateItemOperationsRequest(itemOperations.Items);
        }
        /// <summary>
        /// Initialize the sync with server
        /// </summary>
        /// <param name="collectionId">Specify the folder collection Id which needs to be synced.</param>
        /// <param name="supported">Specifies which contact and calendar elements in a Sync request are managed by the client and therefore not ghosted.</param>
        /// <returns>Return Sync response</returns>
        public SyncStore InitializeSync(string collectionId, Request.Supported supported)
        {
            // Obtains the key by sending an initial Sync request with a SyncKey element value of zero and the CollectionId element
            SyncRequest initializeSyncRequest = TestSuiteHelper.InitializeSyncRequest(collectionId, supported);
            SyncStore initializeSyncResponse = this.CALAdapter.Sync(initializeSyncRequest);

            // Verify sync result
            Site.Assert.AreEqual<byte>(
                1,
                initializeSyncResponse.CollectionStatus,
                "If the Sync command executes successfully, the Status in response should be 1.");

            return initializeSyncResponse;
        }
        /// <summary>
        /// Builds a Search request on the Mailbox store by using the specified keyword and folder collection ID
        /// In general, returns the XML formatted search request as follows:
        /// <!--
        /// <?xml version="1.0" encoding="utf-8"?>
        /// <Search xmlns="Search" xmlns:airsync="AirSync">
        /// <Store>
        ///   <Name>Mailbox</Name>
        ///     <Query>
        ///       <And>
        ///         <airsync:CollectionId>5</airsync:CollectionId>
        ///         <FreeText>Presentation</FreeText>
        ///       </And>
        ///     </Query>
        ///     <Options>
        ///       <RebuildResults />
        ///       <Range>0-9</Range>
        ///       <DeepTraversal/>
        ///     </Options>
        ///   </Store>
        /// </Search>
        /// -->
        /// </summary>
        /// <param name="storeName">Specify the store for which to search. Refer to [MS-ASCMD] section 2.2.3.110.2.</param>
        /// <param name="option">Specify a string value for which to search. Refer to [MS-ASCMD] section 2.2.3.73.</param>
        /// <param name="queryType">Specify the folder in which to search. Refer to [MS-ASCMD] section 2.2.3.30.4.</param>
        /// <returns>Returns a SearchRequest instance.</returns>
        internal static SearchRequest CreateSearchRequest(string storeName, Request.Options1 option, Request.queryType queryType)
        {
            Request.SearchStore searchStore = new Request.SearchStore
            {
                Name = storeName,
                Options = option,
                Query = queryType
            };

            return Common.CreateSearchRequest(new Request.SearchStore[] { searchStore });
        }
        /// <summary>
        /// Update email with more data
        /// </summary>
        /// <param name="collectionId">The collectionId of the folder which contains the item to be updated.</param>
        /// <param name="syncKey">The syncKey which is returned from server</param>
        /// <param name="read">The value is TRUE indicates the email has been read; a value of FALSE indicates the email has not been read</param>
        /// <param name="serverId">The server id of the email</param>
        /// <param name="flag">The flag instance</param>
        /// <param name="categories">The list of categories</param>
        /// <param name="additionalElement">Additional flag element</param>
        /// <param name="insertTag">Additional element will insert before this tag</param>
        /// <returns>Return update email result</returns>
        protected SendStringResponse UpdateEmailWithMoreData(string collectionId, string syncKey, bool read, string serverId, Request.Flag flag, Collection<object> categories, string additionalElement, string insertTag)
        {
            // Create normal sync request
            Request.SyncCollectionChange changeData = TestSuiteHelper.CreateSyncChangeData(read, serverId, flag, categories);
            SyncRequest syncRequest = TestSuiteHelper.CreateSyncChangeRequest(syncKey, collectionId, changeData);

            // Calls Sync command to update email with invalid sync request
            SendStringResponse result = this.EMAILAdapter.InvalidSync(syncRequest, additionalElement, insertTag);
            return result;
        }
        /// <summary>
        /// This method is used to get the initial syncKey of the specified folder.
        /// </summary>
        /// <param name="collectionId">The collection id of the specified folder.</param>
        /// <param name="supportedElements">The elements in Supported element.</param>
        /// <returns>The initial syncKey of the specified folder.</returns>
        protected string GetInitialSyncKey(string collectionId, Request.Supported supportedElements)
        {
            // Obtains the key by sending an initial Sync request with a SyncKey element value of zero and the CollectionId element
            SyncRequest syncRequest = TestSuiteHelper.CreateInitialSyncRequest(collectionId, supportedElements);
            DataStructures.SyncStore syncResult = this.ASCNTCAdapter.Sync(syncRequest);

            // Status code '12' means the folder hierarchy has changed
            while (syncResult.Status == 12)
            {
                // Resynchronize the folder hierarchy
                this.FolderSync();

                syncResult = this.ASCNTCAdapter.Sync(syncRequest);
            }

            this.Site.Assert.IsNotNull(
                syncResult,
                "The result for an initial synchronize should not be null.");

            // Verify Sync result
            this.Site.Assert.AreEqual<byte>(
                1,
                syncResult.CollectionStatus,
                "If the Sync command executes successfully, the Status in response should be 1.");

            return syncResult.SyncKey;
        }
        /// <summary>
        /// Get the specified email item.
        /// </summary>
        /// <param name="emailSubject">The subject of the email item.</param>
        /// <param name="folderCollectionId">The serverId of the default folder.</param>
        /// <param name="bodyPreference">The preference information related to the type and size of information that is returned from fetching.</param>
        /// <returns>The result of getting the specified email item.</returns>
        protected SyncStore GetSyncResult(string emailSubject, string folderCollectionId, Request.BodyPreference bodyPreference)
        {
            SyncStore syncItemResult;
            Sync item = null;
            int counter = 0;
            int waitTime = int.Parse(Common.GetConfigurationPropertyValue("WaitTime", this.Site));
            int retryCount = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site));

            do
            {
                Thread.Sleep(waitTime);

                // Get the new added email item
                SyncStore initSyncResult = this.InitializeSync(folderCollectionId);
                syncItemResult = this.SyncChanges(initSyncResult.SyncKey, folderCollectionId, bodyPreference);
                if (syncItemResult != null && syncItemResult.CollectionStatus == 1)
                {
                    item = TestSuiteHelper.GetSyncAddItem(syncItemResult, emailSubject);
                }

                counter++;
            }
            while ((syncItemResult == null || item == null) && counter < retryCount);

            Site.Assert.IsNotNull(item, "The email item with subject {0} should be found. Retry count: {1}", emailSubject, counter);

            // Verify sync result
            Site.Assert.AreEqual<byte>(
                1,
                syncItemResult.CollectionStatus,
                "If the Sync command executes successfully, the status in response should be 1.");

            return syncItemResult;
        }
        /// <summary>
        /// Verify the Preview element in Body element.
        /// </summary>
        /// <param name="email">The email item got from server.</param>
        /// <param name="allContentEmail">The email item which has full content.</param>
        /// <param name="bodyPreference">A BodyPreference object.</param>
        private void VerifyBodyPreview(DataStructures.Email email, DataStructures.Email allContentEmail, Request.BodyPreference[] bodyPreference)
        {
            Site.Assert.IsNotNull(
                email.Body,
                "The Body element should be included in command response when the BodyPreference element is specified in command request.");

            Site.Assert.IsNotNull(
                email.Body.Preview,
                "The Preview element should be included in command response when the Preview element is specified in command request.");

            Site.Assert.IsTrue(
                email.Body.Preview.Length <= bodyPreference[0].Preview,
                "The Preview element in a response should contain no more than the number of characters specified in the request. The length of Preview element in response is: {0}.",
                email.Body.Preview.Length);

            Site.Assert.IsTrue(
                allContentEmail.Body.Data.Contains(email.Body.Preview),
                "The Preview element in a response should contain the message part preview returned to the client.");
        }
        /// <summary>
        /// This method is used to create Ping request.
        /// </summary>
        /// <param name="folderID">The value of the FolderId element.</param>
        /// <param name="pingFolderClass">An instance of the PingFolderClass.</param>
        /// <returns>The Ping request.</returns>
        private static PingRequest CreatePingRequest(string folderID, Request.PingFolderClass pingFolderClass)
        {
            Request.PingFolder pingFolder = new Request.PingFolder
            {
                Class = pingFolderClass,
                Id = folderID
            };

            return Common.CreatePingRequest(new Request.PingFolder[] { pingFolder }, "80");
        }
        /// <summary>
        /// This method is used to get the changed item from server.
        /// </summary>
        /// <param name="fileAs">The FileAs of the contact.</param>
        /// <param name="collectionId">The collectionId of the folder that store the contact.</param>
        /// <param name="syncKey">The syncKey of the last Sync response.</param>
        /// <param name="bodyPreference">The bodyPreference in the options element.</param>
        /// <returns>The changed item.</returns>
        protected DataStructures.Sync GetSyncChangeResult(string fileAs, string collectionId, string syncKey, Request.BodyPreference bodyPreference)
        {
            DataStructures.SyncStore syncStore;
            DataStructures.Sync item = null;
            SyncRequest request = TestSuiteHelper.CreateSyncRequest(syncKey, collectionId, bodyPreference);

            syncStore = this.ASCNTCAdapter.Sync(request);
            if (syncStore != null && syncStore.CollectionStatus == 1)
            {
                item = TestSuiteHelper.GetSyncChangeItem(syncStore, fileAs);
            }

            this.Site.Assert.IsNotNull(item, "The email item with FileAs: {0} should be found.", fileAs);

            return item;
        }
        /// <summary>
        /// Get the request of Search command.
        /// </summary>
        /// <param name="conversationId">The conversation for which to search.</param>
        /// <param name="bodyPartPreference">The BodyPartPreference in the Options element.</param>
        /// <param name="bodyPreference">The BodyPreference in the Options element.</param>
        /// <returns>A Search command request.</returns>
        internal static SearchRequest GetSearchRequest(string conversationId, Request.BodyPartPreference bodyPartPreference, Request.BodyPreference bodyPreference)
        {
            SearchRequest request = new SearchRequest
            {
                RequestData =
                {
                    Items = new Request.SearchStore[]
                    {
                        new Request.SearchStore()
                        {
                            Name = SearchName.Mailbox.ToString(),
                            Query = new Request.queryType()
                            {
                                Items = new object[]
                                {
                                    new Request.queryType()
                                    {
                                        Items = new object[]
                                        {
                                            "Email",
                                            conversationId
                                        },
                                        ItemsElementName = new Request.ItemsChoiceType2[]
                                        {
                                            Request.ItemsChoiceType2.Class,
                                            Request.ItemsChoiceType2.ConversationId
                                        }
                                    }
                                },
                                ItemsElementName = new Request.ItemsChoiceType2[]
                                {
                                    Request.ItemsChoiceType2.And
                                }
                            }
                        }
                    }
                }
            };

            List<object> items = new List<object>();
            List<Request.ItemsChoiceType6> itemsElementName = new List<Request.ItemsChoiceType6>();

            if (bodyPreference != null)
            {
                items.Add(bodyPreference);
                itemsElementName.Add(Request.ItemsChoiceType6.BodyPreference);
            }

            if (bodyPartPreference != null)
            {
                items.Add(bodyPartPreference);
                itemsElementName.Add(Request.ItemsChoiceType6.BodyPartPreference);
            }

            items.Add(string.Empty);
            itemsElementName.Add(Request.ItemsChoiceType6.RebuildResults);
            items.Add("0-9");
            itemsElementName.Add(Request.ItemsChoiceType6.Range);
            items.Add(string.Empty);
            itemsElementName.Add(Request.ItemsChoiceType6.DeepTraversal);

            request.RequestData.Items[0].Options = new Request.Options1()
            {
                ItemsElementName = itemsElementName.ToArray(),
                Items = items.ToArray()
            };

            return request;
        }
        /// <summary>
        /// Search item with specified criteria on the server.
        /// </summary>
        /// <param name="fileAs">The FileAs of the item.</param>
        /// <param name="collectionId">The collection id.</param>
        /// <param name="bodyPreference">The bodyPreference in the options element.</param>
        /// <returns>The server response.</returns>
        protected DataStructures.Search GetSearchResult(string fileAs, string collectionId, Request.BodyPreference bodyPreference)
        {
            SearchRequest request = TestSuiteHelper.CreateSearchRequest(fileAs.Substring(0, fileAs.IndexOf('_')), collectionId, bodyPreference);

            DataStructures.SearchStore searchStore = this.ASCNTCAdapter.Search(request);
            DataStructures.Search searchItem = null;
            if (searchStore.Results.Count != 0)
            {
                searchItem = TestSuiteHelper.GetSearchItem(searchStore, fileAs);
            }

            this.Site.Assert.IsNotNull(searchItem, "The contact item with FileAs: {0} should be found.", fileAs);

            return searchItem;
        }
        /// <summary>
        /// Search item with specified criteria on the server.
        /// </summary>
        /// <param name="subject">The subject of the item.</param>
        /// <param name="collectionId">The collection id.</param>
        /// <param name="conversationId">The conversation for which to search.</param>
        /// <param name="bodyPreferences">The bodyPreference in the options element.</param>
        /// <param name="bodyPartPreferences">The bodyPartPreference in the options element.</param>
        /// <returns>The server response.</returns>
        protected DataStructures.Search GetSearchResult(string subject, string collectionId, string conversationId, Request.BodyPreference[] bodyPreferences, Request.BodyPartPreference[] bodyPartPreferences)
        {
            SearchRequest request = TestSuiteHelper.CreateSearchRequest(subject, collectionId, conversationId, bodyPreferences, bodyPartPreferences);

            DataStructures.SearchStore searchStore = this.ASAIRSAdapter.Search(request);
            DataStructures.Search searchItem = null;
            if (searchStore.Results.Count != 0)
            {
                searchItem = TestSuiteHelper.GetSearchItem(searchStore, subject);
            }

            this.Site.Assert.IsNotNull(searchItem, "The email message with subject {0} should be found.", subject);

            return searchItem;
        }
        /// <summary>
        /// Update email
        /// </summary>
        /// <param name="collectionId">The collectionId of the folder which contains the item to be updated.</param>
        /// <param name="syncKey">The syncKey which is returned from server</param>
        /// <param name="read">The value is TRUE indicates the email has been read; a value of FALSE indicates the email has not been read</param>
        /// <param name="serverId">The server id of the email</param>
        /// <param name="flag">The flag instance</param>
        /// <param name="categories">The array of categories</param>
        /// <returns>Return update email result</returns>
        protected SyncStore UpdateEmail(string collectionId, string syncKey, bool? read, string serverId, Request.Flag flag, Collection<string> categories)
        {
            Request.SyncCollectionChange changeData = new Request.SyncCollectionChange
            {
                ServerId = serverId,
                ApplicationData = new Request.SyncCollectionChangeApplicationData()
            };

            List<object> items = new List<object>();
            List<Request.ItemsChoiceType7> itemsElementName = new List<Request.ItemsChoiceType7>();

            if (null != read)
            {
                items.Add(read);
                itemsElementName.Add(Request.ItemsChoiceType7.Read);
            }

            if (null != flag)
            {
                items.Add(flag);
                itemsElementName.Add(Request.ItemsChoiceType7.Flag);
            }

            if (null != categories)
            {
                Request.Categories2 mailCategories = new Request.Categories2 { Category = new string[categories.Count] };
                categories.CopyTo(mailCategories.Category, 0);
                items.Add(mailCategories);
                itemsElementName.Add(Request.ItemsChoiceType7.Categories2);
            }

            changeData.ApplicationData.Items = items.ToArray();
            changeData.ApplicationData.ItemsElementName = itemsElementName.ToArray();

            SyncRequest syncRequest = TestSuiteHelper.CreateSyncChangeRequest(syncKey, collectionId, changeData);
            SyncStore result = this.EMAILAdapter.Sync(syncRequest);
            Site.Assert.AreEqual<byte>(
                1,
                result.CollectionStatus,
                "The server returns a Status 1 in the Sync command response indicate sync command success.");

            return result;
        }
        /// <summary>
        /// Verify elements in command response when the request includes multiple BodyPreference elements.
        /// </summary>
        /// <param name="email">The email item got from server.</param>
        /// <param name="body">The body of the email.</param>
        /// <param name="bodyPreferences">A BodyPreference object.</param>
        private void VerifyMultipleBodyPreference(DataStructures.Email email, string body, Request.BodyPreference[] bodyPreferences)
        {
            Site.Assert.IsNotNull(
                email.Body,
                "The Body element should be included in command response when the BodyPreference element is specified in command request.");

            Site.Assert.IsTrue(
                email.Body.Truncated,
                "The data should be truncated since the available data exceeds the TruncationSize value in the second BodyPreference and the first BodyPreference includes the AllOrNone element with a value of 1 (TRUE) along with the TruncationSize element which is smaller than the available data.");

            Site.Assert.AreEqual<string>(
                body.Substring(0, (int)bodyPreferences[1].TruncationSize),
                email.Body.Data,
                "The data should be truncated to the size that requested by TruncationSize element in the second BodyPreference if the request includes the AllOrNone element with a value of 1 (TRUE) along with the TruncationSize element which is smaller than the available data in the first BodyPreference.");
        }
        /// <summary>
        /// This method is used to update the contact properties.
        /// </summary>
        /// <param name="syncKey">The SyncKey returned form last Sync response.</param>
        /// <param name="collectionId">The collectionId of folder that the item belongs to.</param>
        /// <param name="changeData">The change data.</param>
        protected void UpdateContact(string syncKey, string collectionId, Request.SyncCollectionChange changeData)
        {
            SyncRequest syncChangeRequest = TestSuiteHelper.CreateSyncChangeRequest(syncKey, collectionId, changeData);
            DataStructures.SyncStore changeStore = this.ASCNTCAdapter.Sync(syncChangeRequest);

            this.Site.Assert.AreEqual<byte>(
                1,
                changeStore.CollectionStatus,
                "The Sync Change operation should be successful.");
        }
        /// <summary>
        /// Builds a generic Sync request without command references by using the specified sync key, folder collection ID and body preference option.
        /// </summary>
        /// <param name="syncKey">Specifies the sync key obtained from the last sync response.</param>
        /// <param name="collectionId">Specifies the server ID of the folder to be synchronized.</param>
        /// <param name="bodyPreference">Sets preference information related to the type and size of information for body.</param>
        /// <returns>Returns the SyncRequest instance</returns>
        internal static SyncRequest CreateSyncRequest(string syncKey, string collectionId, Request.BodyPreference bodyPreference)
        {
            Request.SyncCollection syncCollection = new Request.SyncCollection
            {
                SyncKey = syncKey,
                CollectionId = collectionId
            };

            // Sets Getchanges only if SyncKey != 0 since fail response is returned when the SyncKey element value is 0.
            if (syncKey != "0")
            {
                syncCollection.GetChanges = true;
                syncCollection.GetChangesSpecified = true;
            }

            syncCollection.WindowSize = "512";

            Request.Options syncOptions = new Request.Options();
            List<object> syncOptionItems = new List<object>();
            List<Request.ItemsChoiceType1> syncOptionItemsName = new List<Request.ItemsChoiceType1>();

            if (null != bodyPreference)
            {
                syncOptionItemsName.Add(Request.ItemsChoiceType1.BodyPreference);
                syncOptionItems.Add(bodyPreference);
            }

            syncOptions.Items = syncOptionItems.ToArray();
            syncOptions.ItemsElementName = syncOptionItemsName.ToArray();
            syncCollection.Options = new Request.Options[] { syncOptions };

            return Common.CreateSyncRequest(new Request.SyncCollection[] { syncCollection });
        }
        /// <summary>
        /// Verify the Preview element in BodyPart element.
        /// </summary>
        /// <param name="email">The email item got from server.</param>
        /// <param name="allContentEmail">The email item which has full content.</param>
        /// <param name="bodyPartPreference">A BodyPartPreference object.</param>
        private void VerifyBodyPartPreview(DataStructures.Email email, DataStructures.Email allContentEmail, Request.BodyPartPreference[] bodyPartPreference)
        {
            Site.Assert.IsNotNull(
                email.BodyPart,
                "The BodyPart element should be included in command response when the BodyPartPreference element is specified in command request.");

            Site.Assert.AreEqual<byte>(
                1,
                email.BodyPart.Status,
                "The Status should be 1 to indicate the success of the command response in returning Data element content given the BodyPartPreference element settings in the command request.");

            Site.Assert.IsNotNull(
               email.BodyPart.Preview,
               "The Preview element should be present in response if a BodyPartPreference element in the request included a Preview element and the server can honor the request.");

            Site.Assert.IsTrue(
                email.BodyPart.Preview.Length <= bodyPartPreference[0].Preview,
                "The Preview element in a response should contain no more than the number of characters specified in the request. The length of Preview element in response is: {0}.",
                email.BodyPart.Preview.Length);

            Site.Assert.IsTrue(
                allContentEmail.BodyPart.Data.Contains(email.BodyPart.Preview),
                "The Preview element in a response should contain the message part preview returned to the client.");
        }
        /// <summary>
        /// This method is designed to create Ping request.
        /// </summary>
        /// <param name="folderIDList">The List value of the FolderId element.</param>
        /// <param name="pingFolderClass">An instance of the PingFolderClass.</param>
        /// <returns>The Ping request.</returns>
        private static PingRequest CreateMultiFolderPingRequest(List<string> folderIDList, Request.PingFolderClass pingFolderClass)
        {
            List<Request.PingFolder> pingRequestList = new List<Request.PingFolder>();
            foreach (string folderID in folderIDList)
            {
                Request.PingFolder pingFolder = new Request.PingFolder { Class = pingFolderClass, Id = folderID };
                pingRequestList.Add(pingFolder);
            }

            return Common.CreatePingRequest(pingRequestList.ToArray(), "80");
        }
        /// <summary>
        /// Sync changes between client and server
        /// </summary>
        /// <param name="syncKey">The synchronization key returned by last request.</param>
        /// <param name="collectionId">Identify the folder as the collection being synchronized.</param>
        /// <param name="bodyPreference">Sets preference information related to the type and size of information for body</param>
        /// <returns>Return change result</returns>
        protected SyncStore SyncChanges(string syncKey, string collectionId, Request.BodyPreference bodyPreference)
        {
            // Get changes from server use initial syncKey
            SyncRequest syncRequest = TestSuiteHelper.CreateSyncRequest(syncKey, collectionId, bodyPreference);
            SyncStore syncResult = this.EMAILAdapter.Sync(syncRequest);

            return syncResult;
        }