/// <inheritdoc />
        protected override async Task <HttpResponseMessage> ImplementationAsync
        (
            Func <Context, CancellationToken, Task <HttpResponseMessage> > action,
            Context context,
            CancellationToken cancellationToken,
            bool continueOnCapturedContext
        )
        {
            if (!context.TryGetValue("endpoint", out var rawEndpoint) || !(rawEndpoint is string endpoint))
            {
                throw new InvalidOperationException("No endpoint set.");
            }

            if (!_rateLimitBuckets.TryGetValue(endpoint, out var rateLimitBucket))
            {
                rateLimitBucket = _globalRateLimitBucket;
            }

            var now = DateTime.UtcNow;

            if (!await rateLimitBucket.TryTakeAsync())
            {
                var rateLimitedResponse = new HttpResponseMessage(HttpStatusCode.TooManyRequests);

                var delay = rateLimitBucket.ResetsAt - now;
                rateLimitedResponse.Headers.RetryAfter = new RetryConditionHeaderValue(delay);

                return(rateLimitedResponse);
            }

            // The request can proceed without hitting rate limits, and we've taken a token
            var requestAction = action(context, cancellationToken).ConfigureAwait(continueOnCapturedContext);

            var response = await requestAction;

            if (!RateLimitBucket.TryParse(response.Headers, out var newLimits))
            {
                return(response);
            }

            if (newLimits.IsGlobal)
            {
                if (_globalRateLimitBucket.ResetsAt < newLimits.ResetsAt)
                {
                    _globalRateLimitBucket = newLimits;
                }

                return(response);
            }

            _rateLimitBuckets.AddOrUpdate
            (
                endpoint,
                newLimits,
                (_, old) => old.ResetsAt < newLimits.ResetsAt ? newLimits : old
            );

            return(response);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DiscordRateLimitPolicy"/> class.
        /// </summary>
        private DiscordRateLimitPolicy()
        {
            _globalRateLimitBucket = new RateLimitBucket
                                     (
                10000,
                10000,
                DateTime.Today + TimeSpan.FromDays(1),
                "global",
                true
                                     );

            _rateLimitBuckets = new ConcurrentDictionary <string, RateLimitBucket>();
        }