/// <inheritdoc />
        public override async Task <BoolValue <AuthResult> > GetAccessTokenAsync(bool allowCached = true)
        {
            if (allowCached)
            {
                var cached = await tryGetCachedAuthResultAsync();

                if (cached && cached.Value.AccessToken != null)
                {
                    return(onAuthorizationDone(cached));
                }
            }

#if DEBUG
            var simulatedAuth = await AuthSimulator.TryGetSimulatedAccessTokenAsync(Config, CacheKey);

            if (simulatedAuth)
            {
                return(simulatedAuth);
            }
#endif

            try
            {
                LogDebug("---- START - Tetra Pak Code Grant Flow ----");
                return(await acquireTokenAsyncUsingNativeWebUI());
            }
            catch (Exception ex)
            {
                LogError(ex, ex.Message);
                LogDebug("---- END - Tetra Pak Code Grant Flow ----");
                return(BoolValue <AuthResult> .Fail("Could not acquire an access token", ex));
            }
        }
        /// <inheritdoc />
        public override async Task <BoolValue <AuthResult> > GetAccessTokenSilentlyAsync()
        {
            if (!IsCaching)
            {
                return(await GetAccessTokenAsync());
            }

            var cached = await tryGetCachedAuthResultAsync();

            if (!cached)
            {
                return(await GetAccessTokenAsync(false));
            }

            if (cached.Value.AccessToken != null)
            {
                if (!cached.Value.Expires.HasValue || DateTime.Now < cached.Value.Expires.Value)
                {
                    return(onAuthorizationDone(cached));
                }
            }

            await removeFromCacheAsync();

            if (string.IsNullOrEmpty(cached.Value.RefreshToken))
            {
                return(await GetAccessTokenAsync());
            }

#if DEBUG
            var simulatedAuth = await AuthSimulator.TryGetSimulatedRenewedAccessTokenAsync(cached.Value.RefreshToken, Config, CacheKey);

            if (simulatedAuth)
            {
                return(simulatedAuth);
            }
#endif

            // access token has expired, try renew from refresh token if available ...
            LogDebug("---- START - Tetra Pak Refresh Token Flow ----");
            BoolValue <AuthResult> result;
            try
            {
                result = await acquireRenewedAccessTokenAsync(cached.Value.RefreshToken);
            }
            catch (Exception ex)
            {
                LogError(ex, ex.Message);
                return(BoolValue <AuthResult> .Fail("Could not renew access token", ex));
            }
            finally
            {
                LogDebug("---- END - Tetra Pak Refresh Token Flow ----");
            }

            return(result ? result : await GetAccessTokenAsync());
        }