public IEnumerable <OwinMiddlewareRegistration> GetOwinMiddlewares()
        {
            return(new[]
            {
                new OwinMiddlewareRegistration
                {
                    Configure = app =>
                                app.Use(async(context, next) =>
                    {
                        var nextDelegateWasRun = false;

                        try
                        {
                            var workContext = _wca.GetContext();

                            // The authenticated user should be set here so ContextPopulatingTelemetryInitializer
                            // can retrieve it. If it would try to get it directly it would cause a spiral of calls
                            // when (SQL) dependency tracking is enabled, resulting in stack overflow.
                            workContext.SetAuthenticatedUserIdForRequest();

                            var requestTrackingIsEnabled = workContext.CurrentSite
                                                           .As <AzureApplicationInsightsTelemetrySettingsPart>()
                                                           .RequestTrackingIsEnabled;
                            if (requestTrackingIsEnabled)
                            {
                                var clock = workContext.Resolve <IClock>();

                                var requestStart = clock.UtcNow;

                                var request = context.Request;
                                var response = context.Response;
                                var requestTrackingEvents = workContext.Resolve <IRequestTrackingEventHandler>();

                                // Ideally filling most of the RequestTelemetry data wouldn't be required: once the
                                // types in Microsoft.ApplicationInsights.Extensibility.Web.RequestTracking.TelemetryModules
                                // will be public they can be used instead of re-implementing them here.
                                var requestTelemetry = new RequestTelemetry
                                {
                                    Timestamp = requestStart,
                                    Url = request.Uri,
                                    HttpMethod = request.Method
                                };


                                requestTelemetry.Context.Operation.Id = requestTelemetry.Id;
                                requestTelemetry.SetShellName(workContext.Resolve <ShellSettings>());

                                if (context.Environment.ContainsKey("System.Web.HttpContextBase"))
                                {
                                    var httpContext =
                                        context.Environment["System.Web.HttpContextBase"] as HttpContextBase;
                                    if (httpContext != null)
                                    {
                                        var routeDataValues = httpContext.Request.RequestContext.RouteData.Values;
                                        if (routeDataValues.ContainsKey("controller"))
                                        {
                                            requestTelemetry.Name = request.Method + " " +
                                                                    (routeDataValues["action"] == null ? "api/" : string.Empty) +
                                                                    routeDataValues["area"] + "/" +
                                                                    routeDataValues["controller"] + "/" +
                                                                    routeDataValues["action"];
                                        }

                                        httpContext.SetOperationIdForRequest(requestTelemetry.Context.Operation.Id);
                                    }
                                }

                                requestTrackingEvents.BeginRequest(requestTelemetry);


                                nextDelegateWasRun = true;
                                try
                                {
                                    await next.Invoke();
                                }
                                catch (Exception ex)
                                {
                                    if (ex.IsFatal())
                                    {
                                        throw;
                                    }
                                    throw new RequestException(ex);
                                }


                                requestTelemetry.Duration = clock.UtcNow - requestStart;
                                requestTelemetry.ResponseCode = response.StatusCode.ToString();
                                requestTelemetry.Success = response.StatusCode < 400;

                                if (string.IsNullOrEmpty(requestTelemetry.Name))
                                {
                                    requestTelemetry.Name =
                                        (string)workContext.Layout.Title.ToString() ??
                                        request.Uri.ToString();
                                }

                                requestTrackingEvents.EndRequest(requestTelemetry);

                                var telemetryClient = workContext
                                                      .Resolve <ITelemetryClientFactory>()
                                                      .CreateTelemetryClientFromCurrentConfiguration();
                                if (telemetryClient != null)
                                {
                                    telemetryClient.TrackRequest(requestTelemetry);
                                }
                            }
                            else
                            {
                                nextDelegateWasRun = true;
                                await next.Invoke();
                            }
                        }
                        catch (RequestException)
                        {
                            // Let such exceptions bubble up, as these originate from the request pipeline downwards.
                            throw;
                        }
                        catch (Exception ex)
                        {
                            if (ex.IsFatal())
                            {
                                throw;
                            }
                            Logger.Error(ex, "An error happened during Application Insights request tracking. The problem most possibly completely prevents request tracking.");
                        }

                        // This should be rather in the catch, but there can't be an awaited call.
                        if (!nextDelegateWasRun)
                        {
                            await next.Invoke();
                        }
                    })
                }
            });
        }