public static async Task RetryOnExceptionAsync(int times, Func <Task> operation, IdServerResourceOwnerClientSettings idServerResourceOwnerClientSettings)
        {
            if (times <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(times));
            }

            var  attempts = 0;
            bool hasClearedAccessToken = false;

            do
            {
                try
                {
                    attempts++;
                    await operation().ConfigureAwait(false);

                    break;
                }
                catch (HttpClientException ex)
                {
                    //If Unauthorized exception decrement attempts and clear the access token - only do once
                    if (!hasClearedAccessToken && ex.HttpStatusCode == System.Net.HttpStatusCode.Unauthorized && idServerResourceOwnerClientSettings != null)
                    {
                        hasClearedAccessToken = true;
                        attempts--;
                        AccessTokenCache.ClearIdServerAccessToken(idServerResourceOwnerClientSettings);
                    }

                    if (attempts == times)
                    {
                        throw ex;
                    }

                    await CreateDelay(attempts).ConfigureAwait(false);
                }
                catch (HttpServerException ex)
                {
                    if (attempts == times)
                    {
                        throw ex;
                    }

                    await CreateDelay(attempts).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    if (attempts == times)
                    {
                        throw ex;
                    }

                    await CreateDelay(attempts).ConfigureAwait(false);
                }
            } while (true);
        }
        private async Task <IHttpRestResponse> ExecuteInternalAsync(IHttpRestRequest request)
        {
            string             apiUrl         = _url + "/" + request.QueryUrl;
            HttpRequestMessage requestMessage = new HttpRequestMessage(request.Method, new Uri(apiUrl));

            if (_hasIDServerResourceOwnerClientSettings)
            {
                string bearerToken = await AccessTokenCache.GetIdServerAccessToken(_idServerResourceOwnerClientSettings, InternalHttpClientHandler).ConfigureAwait(false);

                request.SetHeader("Authorization", string.Format("Bearer {0}", bearerToken));
            }

            requestMessage.Headers.Add("Accept", "application/json");
            foreach (KeyValuePair <string, string> item in request.Headers)
            {
                requestMessage.Headers.Add(item.Key, item.Value.ToString());
            }
            if (request.JsonBody.Length > 0)
            {
                var jsonBody = new StringContent(request.JsonBody, Encoding.UTF8, "application/json");
                requestMessage.Content = jsonBody;
            }

            HttpResponseMessage response = await HttpClient.SendAsync(requestMessage).ConfigureAwait(false);

            CheckResponseError(response);

            Stream stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

            var    sr      = new StreamReader(stream);
            string content = sr.ReadToEnd();

            IHttpRestResponse resp = new HttpRestResponse()
            {
                Request    = request,
                Content    = content,
                StatusCode = response.StatusCode,
                Headers    = response.Headers
            };

            return(resp);
        }