/// <summary>Authenticates the current client and returns an access token.</summary>
        /// <exception cref="Exception">Thrown when an exception error condition occurs.</exception>
        /// <returns>The access token.</returns>
        public virtual async Task<AccessTokenResponse> Authenticate()
        {
            // Get access token. 
            var accessTokenRequest = new AccessTokenRequest()
            {
                Scope = this.Settings.RedirectUri,
                GrantType = "client_credentials"
            };

            var request = new HttpRequestMessage(HttpMethod.Post, "oauth/token")
                              {
                                  Content = new FormUrlEncodedContent(accessTokenRequest.Properties)
                              };
            request.Headers.Authorization = new BasicAuthenticationHeaderValue(this.Settings.ClientId, this.Settings.ClientSecret);

            var response = await this.Client.SendAsync(request);

            if (response.IsSuccessStatusCode)
            {
                return JsonConvert.DeserializeObject<AccessTokenResponse>(await response.Content.ReadAsStringAsync());
            }

            throw new Exception(string.Format("Unable to get access token for application {{ {0} }}.\r\n", accessTokenRequest), new HttpRequestException(await response.Content.ReadAsStringAsync()));
        }
        /// <summary>Authenticates the specified user and client and returns an access token.</summary>
        /// <exception cref="Exception">Thrown when an exception error condition occurs.</exception>
        /// <param name="userName">The username.</param>
        /// <param name="password">The password.</param>
        /// <returns>The access token.</returns>
        public virtual async Task<AccessTokenResponse> Authenticate(string userName, string password)
        {
            // Get access token
            var accessTokenRequest = new AccessTokenRequest()
            {
                Username = userName,
                Password = password,
                RedirectUri = this.Settings.RedirectUri,
                GrantType = "password"
            };

            var accessTokenRequestMessage = new HttpRequestMessage(HttpMethod.Post, "oauth/token")
            {
                Content = new FormUrlEncodedContent(accessTokenRequest.Properties)
            };
            accessTokenRequestMessage.Headers.Authorization = new BasicAuthenticationHeaderValue(this.Settings.ClientId, this.Settings.ClientSecret);

            var accessTokenResponseMessage = await this.Client.SendAsync(accessTokenRequestMessage);

            if (accessTokenResponseMessage.IsSuccessStatusCode)
            {
                var accessTokenResponse = JsonConvert.DeserializeObject<AccessTokenResponse>(await accessTokenResponseMessage.Content.ReadAsStringAsync());

                return accessTokenResponse;
            }

            throw new Exception(string.Format("Unable to get access token for user {{ {0} }}.\r\n", accessTokenRequestMessage), new HttpRequestException(await accessTokenResponseMessage.Content.ReadAsStringAsync()));
        }
        /// <summary>Re-authenticates by refreshing the access token.</summary>
        /// <exception cref="Exception">Thrown when an exception error condition occurs.</exception>
        /// <param name="refreshToken">The refresh token.</param>
        /// <returns>The access token.</returns>
        public virtual async Task<AccessTokenResponse> RefreshAuthentication(string refreshToken)
        {
            // Get access token
            var accessTokenRequest = new AccessTokenRequest()
            {
                RefreshToken = refreshToken,
                RedirectUri = this.Settings.RedirectUri,
                GrantType = "refresh_token"
            };

            var request = new HttpRequestMessage(HttpMethod.Post, "oauth/token")
            {
                Content = new FormUrlEncodedContent(accessTokenRequest.Properties)
            };
            request.Headers.Authorization = new AuthenticationHeaderValue(
                "Basic",
                Convert.ToBase64String(
                    Encoding.UTF8.GetBytes(string.Format("{0}:{1}", this.Settings.ClientId, this.Settings.ClientSecret))));

            var response = await this.Client.SendAsync(request);

            if (response.IsSuccessStatusCode)
            {
                return JsonConvert.DeserializeObject<AccessTokenResponse>(await response.Content.ReadAsStringAsync());
            }

            throw new Exception("Unable to refresh access token", new HttpRequestException(await response.Content.ReadAsStringAsync()));
        }