static ServiceStackHttpHandlerFactory()
        {
            //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 = EndpointHost.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 = config.GetCustomErrorHttpHandler(HttpStatusCode.Forbidden);
            if (ForbiddenHttpHandler == null)
            {
                ForbiddenHttpHandler = new ForbiddenHttpHandler
                {
                    IsIntegratedPipeline = IsIntegratedPipeline,
                    WebHostPhysicalPath = WebHostPhysicalPath,
                    WebHostRootFileNames = WebHostRootFileNames,
                    ApplicationBaseUrl = ApplicationBaseUrl,
                    DefaultRootFileName = DefaultRootFileName,
                    DefaultHandler = debugDefaultHandler,
                };
            }

            NotFoundHttpHandler = config.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();
        }
        static ServiceStackHttpHandlerFactory()
        {
            //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 isAspNetHost = HttpListenerBase.Instance == null || HttpContext.Current != null;
            WebHostPhysicalPath = isAspNetHost
                ? "~".MapHostAbsolutePath()
                : "~".MapAbsolutePath();

            //Apache+mod_mono treats path="servicestack*" as path="*" so takes over root path, so we need to serve matching resources
            var hostedAtRootPath = EndpointHost.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 fileName in Directory.GetFiles(WebHostPhysicalPath))
                {
                    var fileNameLower = Path.GetFileName(fileName).ToLower();
                    if (DefaultRootFileName == null && EndpointHost.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;
                            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(EndpointHost.Config.DefaultRedirectPath))
                DefaultHttpHandler = new RedirectHttpHandler { RelativeUrl = EndpointHost.Config.DefaultRedirectPath };

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

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

            if (DefaultHttpHandler == null)
                DefaultHttpHandler = NotFoundHttpHandler;

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

            ForbiddenHttpHandler = new ForbiddenHttpHandler
            {
                IsIntegratedPipeline = IsIntegratedPipeline,
                WebHostPhysicalPath = WebHostPhysicalPath,
                WebHostRootFileNames = WebHostRootFileNames,
                ApplicationBaseUrl = ApplicationBaseUrl,
                DefaultRootFileName = DefaultRootFileName,
                DefaultHandler = debugDefaultHandler,
            };

            NotFoundHttpHandler = string.IsNullOrEmpty(EndpointHost.Config.NotFoundRedirectPath)
                ? (IHttpHandler)new NotFoundHttpHandler
                {
                    IsIntegratedPipeline = IsIntegratedPipeline,
                    WebHostPhysicalPath = WebHostPhysicalPath,
                    WebHostRootFileNames = WebHostRootFileNames,
                    ApplicationBaseUrl = ApplicationBaseUrl,
                    DefaultRootFileName = DefaultRootFileName,
                    DefaultHandler = debugDefaultHandler,
                }
                : new RedirectHttpHandler { RelativeUrl = EndpointHost.Config.NotFoundRedirectPath };
        }