Inheritance: IServiceStackHttpHandler, IHttpHandler
        static HttpHandlerFactory()
        {
            try
            {
                //MONO doesn't implement this property
                var pi = typeof(HttpRuntime).GetProperty("UsingIntegratedPipeline");
                if (pi != null)
                {
                    IsIntegratedPipeline = (bool)pi.GetGetMethod().Invoke(null, new object[0]);
                }

                var appHost = HostContext.AppHost;
                var config = appHost.Config;

                var isAspNetHost = HostContext.IsAspNetHost;
                WebHostPhysicalPath = appHost.VirtualFileSources.RootDirectory.RealPath;
                HostAutoRedirectsDirs = isAspNetHost && !Env.IsMono;

                //Apache+mod_mono treats path="servicestack*" as path="*" so takes over root path, so we need to serve matching resources
                var hostedAtRootPath = config.HandlerFactoryPath == null;

                //DefaultHttpHandler not supported in IntegratedPipeline mode
                if (!IsIntegratedPipeline && isAspNetHost && !hostedAtRootPath && !Env.IsMono)
                    DefaultHttpHandler = new DefaultHttpHandler();

                var rootFiles = appHost.VirtualFileSources.GetRootFiles().ToList();
                foreach (var file in rootFiles)
                {
                    var fileNameLower = file.Name.ToLower();
                    if (DefaultRootFileName == null && config.DefaultDocuments.Contains(fileNameLower))
                    {
                        //Can't serve Default.aspx pages so ignore and allow for next default document
                        if (!fileNameLower.EndsWith(".aspx"))
                        {
                            DefaultRootFileName = fileNameLower;
                            StaticFileHandler.SetDefaultFile(file.VirtualPath, file.ReadAllBytes(), file.LastModified);

                            if (DefaultHttpHandler == null)
                                DefaultHttpHandler = new StaticFileHandler(file);
                        }
                    }
                    WebHostRootFileNames.Add(fileNameLower);
                }

                foreach (var dir in appHost.VirtualFileSources.GetRootDirectories())
                {
                    WebHostRootFileNames.Add(dir.Name.ToLower());
                }

                if (!string.IsNullOrEmpty(config.DefaultRedirectPath))
                    DefaultHttpHandler = new RedirectHttpHandler { RelativeUrl = config.DefaultRedirectPath };

                if (DefaultHttpHandler == null && !string.IsNullOrEmpty(config.MetadataRedirectPath))
                    DefaultHttpHandler = new RedirectHttpHandler { RelativeUrl = config.MetadataRedirectPath };

                if (!string.IsNullOrEmpty(config.MetadataRedirectPath))
                    NonRootModeDefaultHttpHandler = new RedirectHttpHandler { RelativeUrl = config.MetadataRedirectPath };

                if (DefaultHttpHandler == null)
                    DefaultHttpHandler = NotFoundHttpHandler;

                var defaultRedirectHanlder = DefaultHttpHandler as RedirectHttpHandler;
                var debugDefaultHandler = defaultRedirectHanlder != null
                    ? defaultRedirectHanlder.RelativeUrl
                    : typeof(DefaultHttpHandler).GetOperationName();

                SetApplicationBaseUrl(config.WebHostUrl);

                ForbiddenHttpHandler = appHost.GetCustomErrorHttpHandler(HttpStatusCode.Forbidden);
                if (ForbiddenHttpHandler == null)
                {
                    ForbiddenHttpHandler = new ForbiddenHttpHandler
                    {
                        IsIntegratedPipeline = IsIntegratedPipeline,
                        WebHostPhysicalPath = WebHostPhysicalPath,
                        WebHostRootFileNames = WebHostRootFileNames,
                        WebHostUrl = config.WebHostUrl,
                        DefaultRootFileName = DefaultRootFileName,
                        DefaultHandler = debugDefaultHandler,
                    };
                }

                NotFoundHttpHandler = appHost.GetCustomErrorHttpHandler(HttpStatusCode.NotFound);
                if (NotFoundHttpHandler == null)
                {
                    NotFoundHttpHandler = new NotFoundHttpHandler
                    {
                        IsIntegratedPipeline = IsIntegratedPipeline,
                        WebHostPhysicalPath = WebHostPhysicalPath,
                        WebHostRootFileNames = WebHostRootFileNames,
                        WebHostUrl = config.WebHostUrl,
                        DefaultRootFileName = DefaultRootFileName,
                        DefaultHandler = debugDefaultHandler,
                    };
                }

            }
            catch (Exception ex)
            {
                HostContext.AppHost.OnStartupException(ex);
            }
        }
        static HttpHandlerFactory()
        {
            //MONO doesn't implement this property
            var pi = typeof(HttpRuntime).GetProperty("UsingIntegratedPipeline");
            if (pi != null)
            {
                IsIntegratedPipeline = (bool)pi.GetGetMethod().Invoke(null, new object[0]);
            }

            var config = HostContext.Config;
            if (config == null)
            {
                throw new ConfigurationErrorsException(
                    "ServiceStack: AppHost does not exist or has not been initialized. "
                    + "Make sure you have created an AppHost and started it with 'new AppHost().Init();' in your Global.asax Application_Start()",
                    new ArgumentNullException("EndpointHost.Config"));
            }

            var isAspNetHost = HttpListenerBase.Instance == null || HttpContext.Current != null;
            WebHostPhysicalPath = config.WebHostPhysicalPath;
            AutoRedirectsDirs = isAspNetHost && !Env.IsMono;

            //Apache+mod_mono treats path="servicestack*" as path="*" so takes over root path, so we need to serve matching resources
            var hostedAtRootPath = config.ServiceStackHandlerFactoryPath == null;

            //DefaultHttpHandler not supported in IntegratedPipeline mode
            if (!IsIntegratedPipeline && isAspNetHost && !hostedAtRootPath && !Env.IsMono)
                DefaultHttpHandler = new DefaultHttpHandler();

            ServeDefaultHandler = hostedAtRootPath || Env.IsMono;
            if (ServeDefaultHandler)
            {
                foreach (var filePath in Directory.GetFiles(WebHostPhysicalPath))
                {
                    var fileNameLower = Path.GetFileName(filePath).ToLower();
                    if (DefaultRootFileName == null && config.DefaultDocuments.Contains(fileNameLower))
                    {
                        //Can't serve Default.aspx pages when hostedAtRootPath so ignore and allow for next default document
                        if (!(hostedAtRootPath && fileNameLower.EndsWith(".aspx")))
                        {
                            DefaultRootFileName = fileNameLower;
                            ((StaticFileHandler)StaticFileHandler).SetDefaultFile(filePath);

                            if (DefaultHttpHandler == null)
                                DefaultHttpHandler = new RedirectHttpHandler { RelativeUrl = DefaultRootFileName };
                        }
                    }
                    WebHostRootFileNames.Add(Path.GetFileName(fileNameLower));
                }
                foreach (var dirName in Directory.GetDirectories(WebHostPhysicalPath))
                {
                    var dirNameLower = Path.GetFileName(dirName).ToLower();
                    WebHostRootFileNames.Add(Path.GetFileName(dirNameLower));
                }
            }

            if (!string.IsNullOrEmpty(config.DefaultRedirectPath))
                DefaultHttpHandler = new RedirectHttpHandler { RelativeUrl = config.DefaultRedirectPath };

            if (DefaultHttpHandler == null && !string.IsNullOrEmpty(config.MetadataRedirectPath))
                DefaultHttpHandler = new RedirectHttpHandler { RelativeUrl = config.MetadataRedirectPath };

            if (!string.IsNullOrEmpty(config.MetadataRedirectPath))
                NonRootModeDefaultHttpHandler = new RedirectHttpHandler { RelativeUrl = config.MetadataRedirectPath };

            if (DefaultHttpHandler == null)
                DefaultHttpHandler = NotFoundHttpHandler;

            var defaultRedirectHanlder = DefaultHttpHandler as RedirectHttpHandler;
            var debugDefaultHandler = defaultRedirectHanlder != null
                ? defaultRedirectHanlder.RelativeUrl
                : typeof(DefaultHttpHandler).Name;

            SetApplicationBaseUrl(config.WebHostUrl);

            ForbiddenHttpHandler = HostContext.GetCustomErrorHttpHandler(HttpStatusCode.Forbidden);
            if (ForbiddenHttpHandler == null)
            {
                ForbiddenHttpHandler = new ForbiddenHttpHandler
                {
                    IsIntegratedPipeline = IsIntegratedPipeline,
                    WebHostPhysicalPath = WebHostPhysicalPath,
                    WebHostRootFileNames = WebHostRootFileNames,
                    ApplicationBaseUrl = ApplicationBaseUrl,
                    DefaultRootFileName = DefaultRootFileName,
                    DefaultHandler = debugDefaultHandler,
                };
            }

            NotFoundHttpHandler = HostContext.GetCustomErrorHttpHandler(HttpStatusCode.NotFound);
            if (NotFoundHttpHandler == null)
            {
                NotFoundHttpHandler = new NotFoundHttpHandler
                {
                    IsIntegratedPipeline = IsIntegratedPipeline,
                    WebHostPhysicalPath = WebHostPhysicalPath,
                    WebHostRootFileNames = WebHostRootFileNames,
                    ApplicationBaseUrl = ApplicationBaseUrl,
                    DefaultRootFileName = DefaultRootFileName,
                    DefaultHandler = debugDefaultHandler,
                };
            }

            var rawHandlers = config.RawHttpHandlers;
            rawHandlers.Add(ReturnRequestInfo);
            rawHandlers.Add(MiniProfilerHandler.MatchesRequest);
            RawHttpHandlers = rawHandlers.ToArray();
        }