private object Invoke(string url, RequestModes requestMode, NameValueCollection requestParams, bool replaceQueryParameters = false)
        {
            object result = null;

            // Authentication
            if (this.credentials != null)
            {
                this.webClient.SetCredentials(this.credentials);
            }

            // build url
            if (replaceQueryParameters)
            {
                url = this.ReplaceInUrl(url, requestParams);
                url = Uri.EscapeUriString(url);
            }
            else
            {
                url += this.ToQueryString(requestParams);
            }

            var address = new Uri(url);

            // send
            switch (requestMode)
            {
            case RequestModes.GET:
                using (Stream responseStream = this.webClient.OpenRead(address))
                {
                    if (responseStream != null)
                    {
                        using (var reader = new StreamReader(responseStream, this.RequestEncoding))
                        {
                            result = reader.ReadToEnd();
                        }
                    }
                }

                break;

            case RequestModes.POST:
                byte[] responsebytes = this.webClient.UploadValues(address, "POST", requestParams);
                result = Encoding.UTF8.GetString(responsebytes);

                break;
            }

            return(result);
        }
        /// <summary>
        /// Get an Access Token in order to call an API.
        /// </summary>
        /// <param name="httpClient">A <see cref="HttpClient"/> param.</param>
        /// <param name="endpoint">The OpenId's Endpoint.</param>
        /// <param name="auth0ClientId">The Auth0's client id.</param>
        /// <param name="code">The code received from Auth0.</param>
        /// <param name="audience">The Auth0's audience domain.</param>
        /// <param name="codeVerifier">The code verification token used in the authentication flow</param>
        /// <param name="redirectUri">URL to redirect the user after the logout.</param>
        /// <param name="secret">The Auth0's client secret</param>
        /// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.</returns>
        public static async Task <SessionInfo> GetAccessToken(
            HttpClient httpClient,
            string endpoint,
            string auth0ClientId,
            string code,
            string audience          = null,
            string codeVerifier      = null,
            string redirectUri       = null,
            string secret            = null,
            RequestModes requestMode = RequestModes.Json)
        {
            if (httpClient is null)
            {
                throw new ArgumentNullException(nameof(httpClient));
            }

            if (string.IsNullOrEmpty(endpoint))
            {
                throw new ArgumentException(Resources.NullArgumentExceptionError, nameof(endpoint));
            }

            if (string.IsNullOrEmpty(auth0ClientId))
            {
                throw new ArgumentException(Resources.NullArgumentExceptionError, nameof(auth0ClientId));
            }

            if (string.IsNullOrEmpty(codeVerifier) && string.IsNullOrEmpty(secret))
            {
                throw new ArgumentException(Resources.MissingPKCERequiredParamError, $"{nameof(secret)} or {nameof(codeVerifier)}");
            }

            if (!string.IsNullOrEmpty(codeVerifier) && !string.IsNullOrEmpty(secret))
            {
                throw new ArgumentException(Resources.DuplicatedPKCERequiredParamError, $"{nameof(secret)} and {nameof(codeVerifier)}");
            }
            SessionInfo response = null;

            if (RequestModes.Json == requestMode)
            {
                using (HttpContent content = new StringContent(
                           JsonSerializer.Serialize(
                               new
                {
                    grant_type = "authorization_code",
                    client_id = auth0ClientId,
                    audience,
                    code,
                    code_verifier = codeVerifier,
                    redirect_uri = redirectUri,
                    client_secret = secret,
                },
                               new JsonSerializerOptions
                {
                    IgnoreNullValues = true,
                }), Encoding.UTF8,
                           Resources.ApplicationJsonMediaType
                           )
                       )
                {
                    HttpResponseMessage httpResponseMessage = await httpClient.PostAsync($@"{endpoint}", content).ConfigureAwait(false);

                    var responseText = await httpResponseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);

                    if (httpResponseMessage.StatusCode == System.Net.HttpStatusCode.OK)
                    {
                        response = JsonSerializer.Deserialize <SessionInfo>(responseText);
                    }
                }
            }
            else
            {
                var formContent = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair <string, string>("grant_type", "authorization_code"),
                    new KeyValuePair <string, string>("client_id", auth0ClientId),
                    new KeyValuePair <string, string>("audience", audience),
                    new KeyValuePair <string, string>("code", code),
                    new KeyValuePair <string, string>("code_verifier", codeVerifier),
                    new KeyValuePair <string, string>("redirect_uri", redirectUri),
                    new KeyValuePair <string, string>("client_secret", secret),
                });
                HttpResponseMessage httpResponseMessage = await httpClient.PostAsync($@"{endpoint}", formContent).ConfigureAwait(false);

                formContent.Dispose();
                var responseText = await httpResponseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);

                if (httpResponseMessage.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    response = JsonSerializer.Deserialize <SessionInfo>(responseText);
                }
            }

            return(response);
        }