/// <summary>
        ///     Builds a HttpRequestMessage based on the profile options provided.
        /// </summary>
        /// <param name="url"></param>
        /// <param name="options"></param>
        /// <param name="asCsv"></param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <returns></returns>
        internal HttpRequestMessage BuildRequestMessage(string url, IProfileOptions options, bool asCsv)
        {
            if (string.IsNullOrWhiteSpace(url))
                throw new ArgumentNullException(nameof(url));

            //If no options are provided, a message can't be built
            if (options == null)
                throw new ArgumentNullException(nameof(options));

            //if both the string text and content list are null, stop
            if (string.IsNullOrWhiteSpace(options.Text) && options.Content == null)
                throw new ArgumentNullException(nameof(options.Text));

            //If the content is not null, check the list is populated
            if (options.Content != null)
            {
                //If the content list is null, stop
                if (options.Content.ContentItems == null)
                    throw new ArgumentNullException(nameof(options.Content.ContentItems));

                //If the content is is empty, stop
                if (!options.Content.ContentItems.Any())
                    throw new ArgumentOutOfRangeException(nameof(options.Content));
            }

            var content = options.Text;

            //If content items are provided, serialize them to a string 
            if (options.Content != null && options.Content.ContentItems.Any())
                content = JsonConvert.SerializeObject(options.Content);

            var uriQueries = new Dictionary<string, string>();

            if (options.IncludeRaw)
                uriQueries.Add("include_raw", "true");

            if (options.IncludeCsvHeaders)
                uriQueries.Add("headers", "true");

            var query = string.Join("&", uriQueries.Keys.Select(key =>
                $"{WebUtility.UrlEncode(key)}={WebUtility.UrlEncode(uriQueries[key])}"));

            if (uriQueries.Count > 0)
                url = $"{url}?{query}";

            var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url)
            {
                Content = new StringContent(content)
            };

            httpRequestMessage.Headers.Accept.Add(asCsv
                ? new MediaTypeWithQualityHeaderValue("text/csv")
                : new MediaTypeWithQualityHeaderValue("application/json"));

            httpRequestMessage.Headers.AcceptLanguage.Add(
                new StringWithQualityHeaderValue($"{options.AcceptLanguage}".ToLower()));
            httpRequestMessage.Content.Headers.ContentLanguage.Add($"{options.ContentLanguage}".ToLower());

            return httpRequestMessage;
        }
        /// <summary>
        ///     Gets a PersonalityProfile in Csv format based on multiple content items to analyze.
        /// </summary>
        /// <param name="options">Profile options when making a personality profile request.</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="WatsonException"></exception>
        /// <returns></returns>
        public async Task<string> GetProfileAsCsvAsync(IProfileOptions options)
        {
            //If no options are provided, we can't proceed
            if (options == null)
                throw new ArgumentNullException(nameof(options));

            using (var request = RequestBuilder.BuildRequestMessage("v2/profile", options, true))
            {
                var profile = await SendRequestAsync(request).ConfigureAwait(false);
                return profile;
            }
        }
        /// <summary>
        ///     Gets a PersonalityProfile in its raw json format based on multiple content items to analyze.
        /// </summary>
        /// <param name="options">Profile options when making a personality profile request.</param>
        /// <param name="formatting">Indicates how the output is formatted.</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="WatsonException"></exception>
        /// <returns></returns>
        public async Task<string> GetProfileAsJsonAsync(IProfileOptions options, Formatting formatting = Formatting.None)
        {
            //If no options are provided, we can't proceed
            if (options == null)
                throw new ArgumentNullException(nameof(options));

            using (var request = RequestBuilder.BuildRequestMessage("v2/profile", options, false))
            {
                var rawProfile = await SendRequestAsync(request).ConfigureAwait(false);

                //As the raw string content isn't properly formatted as Json
                //Deserialize it and serialize it with formatting settings.
                var profile = JsonConvert.DeserializeObject(rawProfile);
                return JsonConvert.SerializeObject(profile, formatting);
            }
        }