// ReSharper disable once UnusedMember.Global
        public Task Invoke(HttpContext httpContext, IServerTiming serverTiming, IEnumerable <IServerTimingCallback> callbacks)
        {
            var callbackServices = callbacks as IServerTimingCallback[] ?? callbacks.ToArray();
            var invokeCallbacks  = _options.InvokeCallbackServices && callbackServices.Length > 0;

            var requestOptions = new RequestTimingOptions();

            _options.ConfigureRequestTimingOptions(httpContext, requestOptions);

            if (!requestOptions.WriteHeader && !invokeCallbacks)
            {
                return(_next(httpContext));
            }

            var totalMetric = serverTiming.Manual(
                _options.TotalMetricName,
                _options.TotalMetricDescription);

            totalMetric.Start();

            httpContext.Response.OnStarting(() => OnResponseStarting(httpContext, totalMetric, serverTiming, requestOptions));

            if (invokeCallbacks)
            {
                httpContext.Response.OnCompleted(() => OnResponseCompleted(httpContext, serverTiming, callbackServices));
            }

            return(_next(httpContext));
        }
        internal Task OnResponseStarting(HttpContext httpContext, IManualMetric totalMetric, IServerTiming serverTiming, RequestTimingOptions requestOptions)
        {
            totalMetric.Stop();

            var metrics = serverTiming.GetMetrics();

            if (_options.ValidateMetrics && httpContext.Response.StatusCode != 500)
            {
                // ReSharper disable once ForCanBeConvertedToForeach
                for (var i = 0; i < metrics.Count; i++)
                {
                    if (metrics[i] is IValidatableMetric validatableMetric)
                    {
                        if (!validatableMetric.Validate(out var message))
                        {
                            _logger.LogWarning(message);
                        }
                    }
                }
            }

            if (!requestOptions.WriteHeader)
            {
                return(Task.CompletedTask);
            }

            if (!requestOptions.IncludeCustomMetrics)
            {
                metrics = new[] { (IMetric)totalMetric }
            }
            ;

            _headerWriter.WriteHeaders(httpContext.Response.Headers, requestOptions.IncludeDescriptions, metrics);

            return(Task.CompletedTask);
        }