Inheritance: System.UriBuilder
        /// <summary>
        /// Creates the upload preset.
        /// Upload presets allow you to define the default behavior for your uploads, instead of receiving these as parameters during the upload request itself. Upload presets have precedence over client-side upload parameters.
        /// </summary>
        /// <param name="parameters">Parameters of the upload preset.</param>
        /// <returns></returns>
        public UploadPresetResult CreateUploadPreset(UploadPresetParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV.
                Add("upload_presets").
                BuildUrl(),
                parameters.ToParamsDictionary());

            using (HttpWebResponse response = m_api.Call(HttpMethod.POST, urlBuilder.ToString(), null, null))
            {
                return UploadPresetResult.Parse(response);
            }
        }
        public TransformResult CreateTransform(CreateTransformParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV.
                ResourceType("transformations").
                Add(parameters.Name).
                BuildUrl());

            urlBuilder.QueryString["transformation"] = parameters.Transform.Generate();

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.POST, urlBuilder.ToString(), null, null))
            {
                TransformResult result = TransformResult.Parse(response);
                return result;
            }
        }
        public DelDerivedResResult DeleteDerivedResources(DelDerivedResParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV.
                Add("derived_resources").
                BuildUrl(),
                parameters.ToParamsDictionary());

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.DELETE, urlBuilder.ToString(), null, null))
            {
                DelDerivedResResult result = DelDerivedResResult.Parse(response);
                return result;
            }
        }
        public GetResourceResult GetResource(GetResourceParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV.
                ResourceType("resources").
                Add(Api.GetCloudinaryParam<ResourceType>(parameters.ResourceType)).
                Add(parameters.Type).Add(parameters.PublicId).
                BuildUrl(),
                parameters.ToParamsDictionary());

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.GET, urlBuilder.ToString(), null, null))
            {
                GetResourceResult result = GetResourceResult.Parse(response);
                return result;
            }
        }
        public ListTransformsResult ListTransformations(ListTransformsParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV.
                ResourceType("transformations").
                BuildUrl(),
                parameters.ToParamsDictionary());

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.GET, urlBuilder.ToString(), null, null))
            {
                ListTransformsResult result = ListTransformsResult.Parse(response);
                return result;
            }
        }
        public GetTransformResult GetTransform(GetTransformParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV.
                ResourceType("transformations").
                Add(parameters.Transformation).
                BuildUrl());

            foreach (var param in parameters.ToParamsDictionary())
            {
                urlBuilder.QueryString[param.Key] = param.Value.ToString();
            }

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.GET, urlBuilder.ToString(), null, null))
            {
                GetTransformResult result = GetTransformResult.Parse(response);
                return result;
            }
        }
        /// <summary>
        /// Updates the upload preset.
        /// Every update overwrites all the preset settings.
        /// </summary>
        /// <param name="parameters">New parameters for upload preset.</param>
        /// <returns></returns>
        public UploadPresetResult UpdateUploadPreset(UploadPresetParams parameters)
        {
            var @params = parameters.ToParamsDictionary();
            @params.Remove("name");

            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV
                .Add("upload_presets")
                .Add(parameters.Name)
                .BuildUrl(),
                @params);

            using (HttpWebResponse response = m_api.Call(HttpMethod.PUT, urlBuilder.ToString(), null, null))
            {
                return UploadPresetResult.Parse(response);
            }
        }
        public TransformResult DeleteTransform(string transformName)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV.
                ResourceType("transformations").
                Add(transformName).
                BuildUrl());

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.DELETE, urlBuilder.ToString(), null, null))
            {
                TransformResult result = TransformResult.Parse(response);
                return result;
            }
        }
        /// <summary>
        /// Gets URL to download private image
        /// </summary>
        /// <param name="publicId">The image public ID.</param>
        /// <param name="attachment">Whether to download image as attachment (optional).</param>
        /// <param name="format">Format to download (optional).</param>
        /// <param name="type">The type (optional).</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentException">publicId can't be null</exception>
        public string DownloadPrivate(string publicId, bool? attachment = null, string format = "", string type = "")
        {
            if (String.IsNullOrEmpty(publicId))
                throw new ArgumentException("publicId");

            UrlBuilder urlBuilder = new UrlBuilder(
               m_api.ApiUrlV
               .ResourceType("image")
               .Action("download")
               .BuildUrl());

            var parameters = new SortedDictionary<string, object>();

            parameters.Add("public_id", publicId);

            if (!String.IsNullOrEmpty(format))
                parameters.Add("format", format);

            if (attachment != null)
                parameters.Add("attachment", (bool)attachment ? "true" : "false");

            if (!String.IsNullOrEmpty(type))
                parameters.Add("type", type);

            return GetDownloadUrl(urlBuilder, parameters);
        }
        /// <summary>
        /// Deletes the upload preset.
        /// </summary>
        /// <param name="name">Name of the upload preset.</param>
        /// <returns></returns>
        public DeleteUploadPresetResult DeleteUploadPreset(string name)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV
                .Add("upload_presets")
                .Add(name)
                .BuildUrl());

            using (HttpWebResponse response = m_api.Call(HttpMethod.DELETE, urlBuilder.ToString(), null, null))
            {
                return DeleteUploadPresetResult.Parse(response);
            }
        }
        private string GetDownloadUrl(UrlBuilder builder, IDictionary<string, object> parameters)
        {
            m_api.FinalizeUploadParameters(parameters);

            builder.SetParameters(parameters);

            return builder.ToString();
        }
        /// <summary>
        /// Explode multipage document to single pages
        /// </summary>
        /// <param name="parameters">Parameters of explosion</param>
        /// <returns>Result of operation</returns>
        public ExplodeResult Explode(ExplodeParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlImgUpV.
                Action("explode").
                BuildUrl());

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.POST, urlBuilder.ToString(), parameters.ToParamsDictionary(), null))
            {
                ExplodeResult result = ExplodeResult.Parse(response);
                return result;
            }
        }
        public DelDerivedResResult DeleteDerivedResources(DelDerivedResParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV.
                Add("derived_resources").
                BuildUrl());

            foreach (var param in parameters.ToParamsDictionary())
            {
                if (param.Value is IEnumerable<string>)
                {
                    foreach (var item in (IEnumerable)param.Value)
                    {
                        urlBuilder.QueryString.Add(String.Format("{0}[]", param.Key), item.ToString());
                    }
                }
                else
                {
                    urlBuilder.QueryString[param.Key] = param.Value.ToString();
                }
            }

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.DELETE, urlBuilder.ToString(), null, null))
            {
                DelDerivedResResult result = DelDerivedResResult.Parse(response);
                return result;
            }
        }
        public ListResourcesResult ListResources(ListResourcesParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV.
                ResourceType("resources").
                Add(Api.GetCloudinaryParam<ResourceType>(parameters.ResourceType)).
                Add(!String.IsNullOrEmpty(parameters.Tag) ? String.Format("tags/{0}", parameters.Tag) : String.Empty).
                BuildUrl());

            foreach (var param in parameters.ToParamsDictionary())
            {
                urlBuilder.QueryString[param.Key] = param.Value.ToString();
            }

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.GET, urlBuilder.ToString(), null, null))
            {
                ListResourcesResult result = ListResourcesResult.Parse(response);
                return result;
            }
        }
        public DelResResult DeleteResources(DelResParams parameters)
        {
            Url url = m_api.ApiUrlV.
                Add("resources").
                Add(Api.GetCloudinaryParam<ResourceType>(parameters.ResourceType));

            if (String.IsNullOrEmpty(parameters.Tag))
            {
                url = url.Add(parameters.Type);
            }
            else
            {
                url = url.Add("tags").Add(parameters.Tag);
            }

            UrlBuilder urlBuilder = new UrlBuilder(url.BuildUrl(), parameters.ToParamsDictionary());

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.DELETE, urlBuilder.ToString(), null, null))
            {
                DelResResult result = DelResResult.Parse(response);
                return result;
            }
        }
        /// <summary>
        /// Gets URL to download tag cloud as ZIP package
        /// </summary>
        /// <param name="tag">The tag.</param>
        /// <param name="transform">The transformation.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentException">Tag should be specified!</exception>
        public string DownloadZip(string tag, Transformation transform)
        {
            if (String.IsNullOrEmpty(tag))
                throw new ArgumentException("Tag should be specified!");

            UrlBuilder urlBuilder = new UrlBuilder(
               m_api.ApiUrlV
               .ResourceType("image")
               .Action("download_tag.zip")
               .BuildUrl());

            var parameters = new SortedDictionary<string, object>();

            parameters.Add("tag", tag);

            if (transform != null)
                parameters.Add("transformation", transform.Generate());

            return GetDownloadUrl(urlBuilder, parameters);
        }
        public UpdateTransformResult UpdateTransform(UpdateTransformParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV.
                ResourceType("transformations").
                Add(parameters.Transformation).
                BuildUrl(),
                parameters.ToParamsDictionary());

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.PUT, urlBuilder.ToString(), null, null))
            {
                UpdateTransformResult result = UpdateTransformResult.Parse(response);
                return result;
            }
        }
        /// <summary>
        /// Lists resources.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        public ListResourcesResult ListResources(ListResourcesParams parameters)
        {
            var url = m_api.ApiUrlV.
                ResourceType("resources").
                Add(Api.GetCloudinaryParam<ResourceType>(parameters.ResourceType));

            if (parameters is ListResourcesByTagParams)
            {
                var tagParams = (ListResourcesByTagParams)parameters;
                if (!String.IsNullOrEmpty(tagParams.Tag))
                    url.Add("tags").Add(tagParams.Tag);
            }

            if (parameters is ListResourcesByModerationParams)
            {
                var modParams = (ListResourcesByModerationParams)parameters;

                if (!String.IsNullOrEmpty(modParams.ModerationKind))
                {
                    url
                        .Add("moderations")
                        .Add(modParams.ModerationKind)
                        .Add(Api.GetCloudinaryParam<ModerationStatus>(modParams.ModerationStatus));
                }
            }

            UrlBuilder urlBuilder = new UrlBuilder(
                url.BuildUrl(),
                parameters.ToParamsDictionary());

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.GET, urlBuilder.ToString(), null, null))
            {
                ListResourcesResult result = ListResourcesResult.Parse(response);
                return result;
            }
        }
        /// <summary>
        /// Eagerly generate sprites
        /// </summary>
        /// <param name="parameters">Parameters for sprite generation</param>
        /// <returns>Result of sprite generation</returns>
        public SpriteResult MakeSprite(SpriteParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlImgUpV.
                Action("sprite").
                BuildUrl());

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.POST, urlBuilder.ToString(), parameters.ToParamsDictionary(), null))
            {
                SpriteResult result = SpriteResult.Parse(response);
                return result;
            }
        }
        public ListTagsResult ListTags(ListTagsParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlV.
                ResourceType("tags").
                Add(Api.GetCloudinaryParam<ResourceType>(parameters.ResourceType)).
                BuildUrl(),
                parameters.ToParamsDictionary());

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.GET, urlBuilder.ToString(), null, null))
            {
                ListTagsResult result = ListTagsResult.Parse(response);
                return result;
            }
        }
        /// <summary>
        /// Allows multi transformation
        /// </summary>
        /// <param name="parameters">Parameters of operation</param>
        /// <returns>Result of operation</returns>
        public MultiResult Multi(MultiParams parameters)
        {
            UrlBuilder urlBuilder = new UrlBuilder(
                m_api.ApiUrlImgUpV.
                Action("multi").
                BuildUrl());

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.POST, urlBuilder.ToString(), parameters.ToParamsDictionary(), null))
            {
                MultiResult result = MultiResult.Parse(response);
                return result;
            }
        }
        public DelResResult DeleteResources(DelResParams parameters)
        {
            Url url = m_api.ApiUrlV.
                Add("resources").
                Add(Api.GetCloudinaryParam<ResourceType>(parameters.ResourceType));

            if (String.IsNullOrEmpty(parameters.Tag))
            {
                url = url.Add(parameters.Type);
            }
            else
            {
                url = url.Add("tags").Add(parameters.Tag);
            }

            UrlBuilder urlBuilder = new UrlBuilder(url.BuildUrl());

            foreach (var param in parameters.ToParamsDictionary())
            {
                if (param.Value is IEnumerable<string>)
                {
                    foreach (var item in (IEnumerable)param.Value)
                    {
                        urlBuilder.QueryString.Add(String.Format("{0}[]", param.Key), item.ToString());
                    }
                }
                else
                {
                    urlBuilder.QueryString[param.Key] = param.Value.ToString();
                }
            }

            using (HttpWebResponse response = m_api.Call(
                HttpMethod.DELETE, urlBuilder.ToString(), null, null))
            {
                DelResResult result = DelResResult.Parse(response);
                return result;
            }
        }