class AthenzJettyContainer {

    public void addServletHandlers(String serverHostName) {

        // Handler Structure
        
        RewriteHandler rewriteHandler = new RewriteHandler();
        
        // Check whether or not to disable Keep-Alive support in Jetty.
        // This will be the first handler in our array so we always set
        // the appropriate header in response. However, since we're now
        // behind ATS, we want to keep the connections alive so ATS
        // can re-use them as necessary
        
        boolean keepAlive = Boolean.parseBoolean(System.getProperty(AthenzConsts.ATHENZ_PROP_KEEP_ALIVE, "true"));

        if (!keepAlive) {
            HeaderPatternRule disableKeepAliveRule = new HeaderPatternRule();
            disableKeepAliveRule.setPattern("/*");
            disableKeepAliveRule.setName(HttpHeader.CONNECTION.asString());
            disableKeepAliveRule.setValue(HttpHeaderValue.CLOSE.asString());
            rewriteHandler.addRule(disableKeepAliveRule);
        }
        
        // Return a Host field in the response so during debugging
        // we know what server was handling request
        
        HeaderPatternRule hostNameRule = new HeaderPatternRule();
        hostNameRule.setPattern("/*");
        hostNameRule.setName(HttpHeader.HOST.asString());
        hostNameRule.setValue(serverHostName);
        rewriteHandler.addRule(hostNameRule);
        
        handlers.addHandler(rewriteHandler);

        ContextHandlerCollection contexts = new ContextHandlerCollection();

        // check to see if gzip support is enabled

        boolean gzipSupport = Boolean.parseBoolean(System.getProperty(AthenzConsts.ATHENZ_PROP_GZIP_SUPPORT, "false"));

        if (gzipSupport) {
            int gzipMinSize = Integer.parseInt(
                    System.getProperty(AthenzConsts.ATHENZ_PROP_GZIP_MIN_SIZE, "1024"));

            GzipHandler gzipHandler = new GzipHandler();
            gzipHandler.setMinGzipSize(gzipMinSize);
            gzipHandler.setIncludedMimeTypes("application/json");
            gzipHandler.setHandler(contexts);

            handlers.addHandler(gzipHandler);
        }

        // check to see if graceful shutdown support is enabled
        boolean gracefulShutdown = Boolean.parseBoolean(
                System.getProperty(AthenzConsts.ATHENZ_PROP_GRACEFUL_SHUTDOWN, "false"));
        if (gracefulShutdown) {
            server.setStopAtShutdown(true);

            long stopTimeout = Long.parseLong(
                    System.getProperty(AthenzConsts.ATHENZ_PROP_GRACEFUL_SHUTDOWN_TIMEOUT, "30000"));
            server.setStopTimeout(stopTimeout);

            StatisticsHandler statisticsHandler = new StatisticsHandler();
            statisticsHandler.setHandler(contexts);

            handlers.addHandler(statisticsHandler);
        }

        handlers.addHandler(contexts);

        // now setup our default servlet handler for filters
        
        ServletContextHandler servletCtxHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        servletCtxHandler.setContextPath("/");
        
        FilterHolder filterHolder = new FilterHolder(HealthCheckFilter.class);
        final String healthCheckPath = System.getProperty(AthenzConsts.ATHENZ_PROP_HEALTH_CHECK_PATH,
                getRootDir());
        filterHolder.setInitParameter(AthenzConsts.ATHENZ_PROP_HEALTH_CHECK_PATH, healthCheckPath);

        final String checkList = System.getProperty(AthenzConsts.ATHENZ_PROP_HEALTH_CHECK_URI_LIST);

        if (checkList != null && !checkList.isEmpty()) {
            String[] checkUriArray = checkList.split(",");
            for (String checkUri : checkUriArray) {
                servletCtxHandler.addFilter(filterHolder, checkUri.trim(), EnumSet.of(DispatcherType.REQUEST));
            }
        }
        contexts.addHandler(servletCtxHandler);


        DeploymentManager deployer = new DeploymentManager();
        
        boolean debug = Boolean.parseBoolean(System.getProperty(AthenzConsts.ATHENZ_PROP_DEBUG, "false"));
        if (debug) {
            DebugListener debugListener = new DebugListener(System.err, true, true, true);
            server.addBean(debugListener);
            deployer.addLifeCycleBinding(new DebugListenerBinding(debugListener));
        }
        
        deployer.setContexts(contexts);
        deployer.setContextAttribute(
                "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
                ".*/servlet-api-[^/]*\\.jar$");

        final String jettyHome = System.getProperty(AthenzConsts.ATHENZ_PROP_JETTY_HOME, getRootDir());
        WebAppProvider webappProvider = new WebAppProvider();
        webappProvider.setMonitoredDirName(jettyHome + "/webapps");
        webappProvider.setScanInterval(60);
        webappProvider.setExtractWars(true);
        webappProvider.setConfigurationManager(new PropertiesConfigurationManager());
        webappProvider.setParentLoaderPriority(true);
        //setup a Default web.xml file.  file is applied to a Web application before it's own WEB_INF/web.xml 
        setDefaultsDescriptor(webappProvider, jettyHome);
        final String jettyTemp = System.getProperty(AthenzConsts.ATHENZ_PROP_JETTY_TEMP, jettyHome + "/temp");
        webappProvider.setTempDir(new File(jettyTemp));

        deployer.addAppProvider(webappProvider);
        server.addBean(deployer);
    }

    public  AthenzJettyContainer();

}