/// <summary>
        ///     Gets a Redmine object. This method does not block the calling thread.
        /// </summary>
        /// <typeparam name="T">The type of objects to retrieve.</typeparam>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="id">The id of the object.</param>
        /// <param name="parameters">Optional filters and/or optional fetched data.</param>
        /// <returns></returns>
        public static async Task <T> GetObjectAsync <T>(this RedmineManager redmineManager, string id, NameValueCollection parameters)
            where T : class, new()
        {
            var uri = UrlHelper.GetGetUrl <T>(redmineManager, id);

            return(await WebApiAsyncHelper.ExecuteDownload <T>(redmineManager, uri, parameters).ConfigureAwait(false));
        }
        /// <summary>
        ///     Adds an existing user to a group. This method does not block the calling thread.
        /// </summary>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="groupId">The group id.</param>
        /// <param name="userId">The user id.</param>
        /// <returns>
        ///     Returns the Guid associated with the async request.
        /// </returns>
        public static async Task AddUserToGroupAsync(this RedmineManager redmineManager, int groupId, int userId)
        {
            var data = DataHelper.UserData(userId, redmineManager.MimeFormat);
            var uri  = UrlHelper.GetAddUserToGroupUrl(redmineManager, groupId);

            await WebApiAsyncHelper.ExecuteUpload(redmineManager, uri, HttpVerbs.POST, data, "AddUserToGroupAsync");
        }
        /// <summary>
        ///     Adds the watcher asynchronous.
        /// </summary>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="issueId">The issue identifier.</param>
        /// <param name="userId">The user identifier.</param>
        /// <returns></returns>
        public static async Task AddWatcherToIssueAsync(this RedmineManager redmineManager, int issueId, int userId)
        {
            var data = DataHelper.UserData(userId, redmineManager.MimeFormat);
            var uri  = UrlHelper.GetAddWatcherUrl(redmineManager, issueId);

            await WebApiAsyncHelper.ExecuteUpload(redmineManager, uri, HttpVerbs.POST, data).ConfigureAwait(false);
        }
        /// <summary>
        ///     Creates the or update wiki page asynchronous.
        /// </summary>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="projectId">The project identifier.</param>
        /// <param name="pageName">Name of the page.</param>
        /// <param name="wikiPage">The wiki page.</param>
        /// <returns></returns>
        public static async Task <WikiPage> CreateOrUpdateWikiPageAsync(this RedmineManager redmineManager, string projectId, string pageName, WikiPage wikiPage)
        {
            var uri  = UrlHelper.GetWikiCreateOrUpdaterUrl(redmineManager, projectId, pageName);
            var data = RedmineSerializer.Serialize(wikiPage, redmineManager.MimeFormat);

            return(await WebApiAsyncHelper.ExecuteUpload <WikiPage>(redmineManager, uri, HttpVerbs.PUT, data, "CreateOrUpdateWikiPageAsync"));
        }
        /// <summary>
        ///     Gets the wiki page asynchronous.
        /// </summary>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="projectId">The project identifier.</param>
        /// <param name="parameters">The parameters.</param>
        /// <param name="pageName">Name of the page.</param>
        /// <param name="version">The version.</param>
        /// <returns></returns>
        public static async Task <WikiPage> GetWikiPageAsync(this RedmineManager redmineManager, string projectId,
                                                             NameValueCollection parameters, string pageName, uint version = 0)
        {
            var uri = UrlHelper.GetWikiPageUrl(redmineManager, projectId, parameters, pageName, version);

            return(await WebApiAsyncHelper.ExecuteDownload <WikiPage>(redmineManager, uri, "GetWikiPageAsync", parameters));
        }
        /// <summary>
        ///     Gets the paginated objects asynchronous.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="parameters">The parameters.</param>
        /// <returns></returns>
        public static async Task <PagedResults <T> > GetPaginatedObjectsAsync <T>(this RedmineManager redmineManager,
                                                                                  NameValueCollection parameters)
            where T : class, new()
        {
            var uri = UrlHelper.GetListUrl <T>(redmineManager, parameters);

            return(await WebApiAsyncHelper.ExecuteDownloadPaginatedList <T>(redmineManager, uri, parameters).ConfigureAwait(false));
        }
        /// <summary>
        ///     Deletes the wiki page asynchronous.
        /// </summary>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="projectId">The project identifier.</param>
        /// <param name="pageName">Name of the page.</param>
        /// <returns></returns>
        public static async Task DeleteWikiPageAsync(this RedmineManager redmineManager, string projectId,
                                                     string pageName)
        {
            var uri = UrlHelper.GetDeleteWikiUrl(redmineManager, projectId, pageName);

            uri = Uri.EscapeUriString(uri);
            await WebApiAsyncHelper.ExecuteUpload(redmineManager, uri, HttpVerbs.DELETE, string.Empty).ConfigureAwait(false);
        }
        /// <summary>
        ///     Creates a new Redmine object. This method does not block the calling thread.
        /// </summary>
        /// <typeparam name="T">The type of object to create.</typeparam>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="obj">The object to create.</param>
        /// <param name="ownerId">The owner identifier.</param>
        /// <returns></returns>
        public static async Task <T> CreateObjectAsync <T>(this RedmineManager redmineManager, T obj, string ownerId)
            where T : class, new()
        {
            var uri  = UrlHelper.GetCreateUrl <T>(redmineManager, ownerId);
            var data = RedmineSerializer.Serialize(obj, redmineManager.MimeFormat);

            return(await WebApiAsyncHelper.ExecuteUpload <T>(redmineManager, uri, HttpVerbs.POST, data, "CreateObjectAsync"));
        }
        /// <summary>
        ///     Creates a new Redmine object. This method does not block the calling thread.
        /// </summary>
        /// <typeparam name="T">The type of object to create.</typeparam>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="entity">The object to create.</param>
        /// <param name="ownerId">The owner identifier.</param>
        /// <returns></returns>
        public static async Task <T> CreateObjectAsync <T>(this RedmineManager redmineManager, T entity, string ownerId)
            where T : class, new()
        {
            var uri  = UrlHelper.GetCreateUrl <T>(redmineManager, ownerId);
            var data = redmineManager.Serializer.Serialize(entity);

            var response = await WebApiAsyncHelper.ExecuteUpload(redmineManager, uri, HttpVerbs.POST, data).ConfigureAwait(false);

            return(redmineManager.Serializer.Deserialize <T>(response));
        }
        /// <summary>
        ///     Updates the object asynchronous.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="id">The identifier.</param>
        /// <param name="obj">The object.</param>
        /// <param name="projectId">The project identifier.</param>
        /// <returns></returns>
        public static async Task UpdateObjectAsync <T>(this RedmineManager redmineManager, string id, T obj, string projectId = null)
            where T : class, new()
        {
            var uri  = UrlHelper.GetUploadUrl(redmineManager, id, obj, projectId);
            var data = RedmineSerializer.Serialize(obj, redmineManager.MimeFormat);

            data = Regex.Replace(data, @"\r\n|\r|\n", "\r\n");

            await WebApiAsyncHelper.ExecuteUpload <T>(redmineManager, uri, HttpVerbs.PUT, data, "UpdateObjectAsync");
        }
        /// <summary>
        ///     Updates the object asynchronous.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="id">The identifier.</param>
        /// <param name="entity">The object.</param>
        /// <returns></returns>
        public static async Task UpdateObjectAsync <T>(this RedmineManager redmineManager, string id, T entity)
            where T : class, new()
        {
            var uri  = UrlHelper.GetUploadUrl <T>(redmineManager, id);
            var data = redmineManager.Serializer.Serialize(entity);

            data = Regex.Replace(data, @"\r\n|\r|\n", "\r\n");

            await WebApiAsyncHelper.ExecuteUpload(redmineManager, uri, HttpVerbs.PUT, data).ConfigureAwait(false);
        }
        /// <summary>
        ///     Creates the or update wiki page asynchronous.
        /// </summary>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="projectId">The project identifier.</param>
        /// <param name="pageName">Name of the page.</param>
        /// <param name="wikiPage">The wiki page.</param>
        /// <returns></returns>
        public static async Task UpdateWikiPageAsync(this RedmineManager redmineManager, string projectId, string pageName, WikiPage wikiPage)
        {
            var data = redmineManager.Serializer.Serialize(wikiPage);

            if (string.IsNullOrEmpty(data))
            {
                return;
            }

            var url = UrlHelper.GetWikiCreateOrUpdaterUrl(redmineManager, projectId, pageName);

            url = Uri.EscapeUriString(url);

            var response = await WebApiAsyncHelper.ExecuteUpload(redmineManager, url, HttpVerbs.PUT, data).ConfigureAwait(false);
        }
 /// <summary>
 ///     Deletes the Redmine object. This method does not block the calling thread.
 /// </summary>
 /// <typeparam name="T">The type of objects to delete.</typeparam>
 /// <param name="redmineManager">The redmine manager.</param>
 /// <param name="id">The id of the object to delete</param>
 /// <returns></returns>
 public static async Task DeleteObjectAsync <T>(this RedmineManager redmineManager, string id)
     where T : class, new()
 {
     var uri = UrlHelper.GetDeleteUrl <T>(redmineManager, id);
     await WebApiAsyncHelper.ExecuteUpload(redmineManager, uri, HttpVerbs.DELETE, string.Empty).ConfigureAwait(false);
 }
 /// <summary>
 ///     Downloads the file asynchronous.
 /// </summary>
 /// <param name="redmineManager">The redmine manager.</param>
 /// <param name="address">The address.</param>
 /// <returns></returns>
 public static async Task <byte[]> DownloadFileAsync(this RedmineManager redmineManager, string address)
 {
     return(await WebApiAsyncHelper.ExecuteDownloadFile(redmineManager, address).ConfigureAwait(false));
 }
 /// <summary>
 ///     Removes an user from a group. This method does not block the calling thread.
 /// </summary>
 /// <param name="redmineManager">The redmine manager.</param>
 /// <param name="groupId">The group id.</param>
 /// <param name="userId">The user id.</param>
 /// <returns></returns>
 public static async Task DeleteUserFromGroupAsync(this RedmineManager redmineManager, int groupId, int userId)
 {
     var uri = UrlHelper.GetRemoveUserFromGroupUrl(redmineManager, groupId, userId);
     await WebApiAsyncHelper.ExecuteUpload(redmineManager, uri, HttpVerbs.DELETE, string.Empty, "DeleteUserFromGroupAsync");
 }
        /// <summary>
        ///     Gets the current user asynchronous.
        /// </summary>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="parameters">The parameters.</param>
        /// <returns></returns>
        public static async Task <User> GetCurrentUserAsync(this RedmineManager redmineManager, NameValueCollection parameters = null)
        {
            var uri = UrlHelper.GetCurrentUserUrl(redmineManager);

            return(await WebApiAsyncHelper.ExecuteDownload <User>(redmineManager, uri, parameters).ConfigureAwait(false));
        }
 /// <summary>
 ///     Deletes the Redmine object. This method does not block the calling thread.
 /// </summary>
 /// <typeparam name="T">The type of objects to delete.</typeparam>
 /// <param name="redmineManager">The redmine manager.</param>
 /// <param name="id">The id of the object to delete</param>
 /// <param name="parameters">Optional filters and/or optional fetched data.</param>
 /// <returns></returns>
 public static async Task DeleteObjectAsync <T>(this RedmineManager redmineManager, string id, NameValueCollection parameters)
     where T : class, new()
 {
     var uri = UrlHelper.GetDeleteUrl <T>(redmineManager, id);
     await WebApiAsyncHelper.ExecuteUpload <T>(redmineManager, uri, HttpVerbs.DELETE, string.Empty, "DeleteObjectAsync");
 }
 /// <summary>
 ///     Deletes the wiki page asynchronous.
 /// </summary>
 /// <param name="redmineManager">The redmine manager.</param>
 /// <param name="projectId">The project identifier.</param>
 /// <param name="pageName">Name of the page.</param>
 /// <returns></returns>
 public static async Task DeleteWikiPageAsync(this RedmineManager redmineManager, string projectId,
                                              string pageName)
 {
     var uri = UrlHelper.GetDeleteWikirUrl(redmineManager, projectId, pageName);
     await WebApiAsyncHelper.ExecuteUpload(redmineManager, uri, HttpVerbs.DELETE, string.Empty, "DeleteWikiPageAsync");
 }
        /// <summary>
        ///     Support for adding attachments through the REST API is added in Redmine 1.4.0.
        ///     Upload a file to server. This method does not block the calling thread.
        /// </summary>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="data">The content of the file that will be uploaded on server.</param>
        /// <returns>
        ///     .
        /// </returns>
        public static async Task <Upload> UploadFileAsync(this RedmineManager redmineManager, byte[] data)
        {
            var uri = UrlHelper.GetUploadFileUrl(redmineManager);

            return(await WebApiAsyncHelper.ExecuteUploadFile(redmineManager, uri, data).ConfigureAwait(false));
        }
 /// <summary>
 ///     Removes the watcher asynchronous.
 /// </summary>
 /// <param name="redmineManager">The redmine manager.</param>
 /// <param name="issueId">The issue identifier.</param>
 /// <param name="userId">The user identifier.</param>
 /// <returns></returns>
 public static async Task RemoveWatcherFromIssueAsync(this RedmineManager redmineManager, int issueId, int userId)
 {
     var uri = UrlHelper.GetRemoveWatcherUrl(redmineManager, issueId, userId);
     await WebApiAsyncHelper.ExecuteUpload(redmineManager, uri, HttpVerbs.DELETE, string.Empty).ConfigureAwait(false);
 }
        /// <summary>
        ///     Gets all wiki pages asynchronous.
        /// </summary>
        /// <param name="redmineManager">The redmine manager.</param>
        /// <param name="parameters">The parameters.</param>
        /// <param name="projectId">The project identifier.</param>
        /// <returns></returns>
        public static async Task <List <WikiPage> > GetAllWikiPagesAsync(this RedmineManager redmineManager, NameValueCollection parameters, string projectId)
        {
            var uri = UrlHelper.GetWikisUrl(redmineManager, projectId);

            return(await WebApiAsyncHelper.ExecuteDownloadList <WikiPage>(redmineManager, uri, parameters).ConfigureAwait(false));
        }