/// <inheritdoc />
        /// <summary>
        ///     Perform the health check
        /// </summary>
        /// <returns>Response with the test result</returns>
        public async Task <HealthyResponse> Check()
        {
            try
            {
                await _semaphore.WaitAsync().ConfigureAwait(false);

                var watcher = Stopwatch.StartNew();
                var results = new List <HttpResponseMessage>();

                var currentContext = _autoHealthCheckContextAccessor.Context;

                // if endpoint discovery was not disabled
                if (!currentContext.Configurations.DisableEndpointDiscovery)
                {
                    var routesDefinition = await _routesFactory;
                    var routeInformation = routesDefinition as IRouteInformation[] ?? routesDefinition.ToArray();

                    if (routeInformation.Any())
                    {
                        foreach (var route in routeInformation.AsParallel()
                                 .WithMergeOptions(ParallelMergeOptions.FullyBuffered))
                        {
                            var endpoint = await _endpointBuilder.CreateFromRoute(route).ConfigureAwait(false);

                            var message = await _endpointMessageTranslator.Transform(endpoint).ConfigureAwait(false);

                            // call endpoint
                            var result = await _endpointCaller.Send(message).ConfigureAwait(false);

                            results.Add(result);
                        }
                    }
                }

                var probesResults = await
                                    _probesProcessor.ExecuteCustomProbes().ConfigureAwait(false);

                // check test timing
                watcher.Stop();

                return(await HealthCheckResultProcessor.ProcessResult(
                           currentContext,
                           watcher,
                           results.ToArray(),
                           probesResults.ToArray()));
            }
            finally
            {
                _semaphore.Release();
            }
        }