public EmbeddedServer(String inHost, int inPort, int inMaxThreads, String keystorePath, final List<IPFilter> whitelist, final List<IPFilter> blacklist) {

		CommunityDAO.get();

		mServer = new Server();
		
		QueuedThreadPool threadPool = new QueuedThreadPool();
		threadPool.setMinThreads(2);
		threadPool.setMaxThreads(inMaxThreads);
		threadPool.setName("Jetty embedded server thread pool");
		threadPool.setDaemon(true);

		logger.info("max_threads: " + inMaxThreads);

		mServer.setThreadPool(threadPool);

		Connector connector;

		/**
		 * We'll at least use this SecurityHandler for the administrator
		 * interface -- we may also use it for user authentication (if this is
		 * an authorized-users-only server)
		 */

		// Constraint constraint = new Constraint();
		// constraint.setName(Constraint.__BASIC_AUTH);
		// constraint.setRoles(new String[] { ADMIN_ROLE });
		// constraint.setAuthenticate(true);

		// cm.setConstraint(constraint);
		// cm.setPathSpec(ADMIN_SERVLET_PATH + "/*");
		// constraintMappings.add(cm);
		//		
		// cm = new ConstraintMapping();
		// cm.setConstraint(constraint);
		// cm.setPathSpec("/CommunityServerAdmin.html");
		// constraintMappings.add(cm);

		boolean requireAuthentication = true;

		/**
		 * Install the key registration servlet
		 */
		Context registrationContext = new Context(mServer, "/community");
		SecurityHandler secHandler = new SecurityHandler();
		secHandler.setUserRealm(new OurHashRealm());
		
		/**
		 * We need to support POST messages at /community to retain backwards compatibility 
		 * with 0.6.5 clients. 
		 */
		registrationContext.setAllowNullPathInfo(true);
		
		List<ConstraintMapping> constraintMappings = new ArrayList<ConstraintMapping>();
		ConstraintMapping cm = null;

		registrationContext.setSecurityHandler(secHandler);
		registrationContext.addServlet(new ServletHolder(new KeyRegistrationServlet()), "/");
		
		registrationContext.addFilter(new FilterHolder(new IPServletFilter(whitelist, blacklist)), "/*", org.mortbay.jetty.Handler.ALL);

		/**
		 * Authentication constraint for requesting peers
		 */
		if (System.getProperty(StartupSetting.REQUIRE_AUTH_FOR_KEY_REGISTRATION.getKey()).equals(Boolean.TRUE.toString())) {

			logger.info("Authentication required for key registration / requests");

			Constraint constraint = new Constraint();
			constraint.setName(Constraint.__BASIC_AUTH);
			constraint.setRoles(new String[] { "user", "admin", "moderator" });
			constraint.setAuthenticate(true);

			cm = new ConstraintMapping();
			cm.setConstraint(constraint);
			cm.setPathSpec("/*");
			constraintMappings.add(cm);
		}
		secHandler.setConstraintMappings(constraintMappings.toArray(new ConstraintMapping[0]));

		/**
		 * Install the publishing servlet
		 */
		Context publishContext = new Context(mServer, "/publish");
		secHandler = new SecurityHandler();
		secHandler.setUserRealm(new OurHashRealm());
		publishContext.setSecurityHandler(secHandler);
		publishContext.addServlet(new ServletHolder(new SwarmPublishServlet()), "/");

		publishContext.addFilter(new FilterHolder(new IPServletFilter(whitelist, blacklist)), "/*", org.mortbay.jetty.Handler.ALL);

		/**
		 * Authentication constraint for publishing swarms
		 */
		if (System.getProperty(StartupSetting.REQUIRE_AUTH_FOR_PUBLISH.getKey()).equals(Boolean.TRUE.toString())) {

			logger.info("Authentication required for swarm publishing");

			Constraint constraint = new Constraint();
			constraint.setName(Constraint.__BASIC_AUTH);
			constraint.setRoles(new String[] { "user", "admin", "moderator" });
			constraint.setAuthenticate(true);

			cm = new ConstraintMapping();
			cm.setConstraint(constraint);
			cm.setPathSpec("/*");
			constraintMappings.add(cm);
		}

		secHandler.setConstraintMappings(constraintMappings.toArray(new ConstraintMapping[0]));

		/**
		 * Install the JSP interface.
		 */
		WebAppContext app = new WebAppContext();
		app.setContextPath("/");
		app.setWar("./war");
		app.setConfigurationClasses(new String[] { JettyWebXmlConfiguration.class.getName(), WebInfConfiguration.class.getName(), WebXmlConfiguration.class.getName() });
		app.setParentLoaderPriority(true);
		
		app.getInitParams().put("org.mortbay.jetty.servlet.Default.dirAllowed", "false");
		app.getInitParams().put("org.mortbay.jetty.servlet.Default.maxCacheSize", "0");
		app.getInitParams().put("org.mortbay.jetty.servlet.Default.cacheControl", "no-store,no-cache,must-revalidate");

		app.addFilter(new FilterHolder(new IPServletFilter(whitelist, blacklist)), "/*", org.mortbay.jetty.Handler.ALL);

		if (keystorePath != null) {

			logger.info("Using SSL...");

			/**
			 * see: http://docs.codehaus.org/display/JETTY/How+to+configure+SSL
			 */
			connector = new SslSocketConnector();
			final SslSocketConnector sslconnector = (SslSocketConnector) connector;
			sslconnector.setKeystore(keystorePath);
			sslconnector.setPassword(System.getProperty("jetty.ssl.password"));
			sslconnector.setKeyPassword(System.getProperty("jetty.ssl.keypassword"));
			sslconnector.setNeedClientAuth(false);
			sslconnector.setWantClientAuth(false);
			
			sslconnector.setAcceptors(1);
			sslconnector.setAcceptQueueSize(100);
			
			logger.fine(new Formatter().format("acceptors: %d acceptQueueSize: %d handshakeTimeout: %d\n", 
					sslconnector.getAcceptors(), 
					sslconnector.getAcceptQueueSize(), 
					sslconnector.getHandshakeTimeout()).toString());
			
		} else {
			connector = new SelectChannelConnector();
		}
		
		connector.setMaxIdleTime(3000);
		connector.setLowResourceMaxIdleTime(1000);
		
		if (inHost != null) {
			connector.setHost(inHost);
			logger.info("host: " + inHost);
		}
		connector.setPort(inPort);
		mServer.addConnector(connector);
		
		Handler[] handlers = null;
		if (System.getProperty(StartupSetting.REQUEST_LOG_DIRECTORY.getKey()) != null) {

			RequestLogHandler requestLogHandler = new RequestLogHandler();
			NCSARequestLog requestLog = new NCSARequestLog(System.getProperty(StartupSetting.REQUEST_LOG_DIRECTORY.getKey()) + "/communityserver-yyyy_mm_dd.request.log");
			requestLog.setRetainDays(Integer.parseInt(System.getProperty(StartupSetting.REQUEST_LOG_RETAIN_DAYS.getKey())));
			requestLog.setAppend(true);
			requestLog.setExtended(true);
			requestLog.setLogTimeZone("GMT");
			requestLogHandler.setRequestLog(requestLog);

			handlers = new Handler[] { registrationContext, publishContext, app, requestLogHandler };
		} else {
			handlers = new Handler[] { registrationContext, publishContext, app };
		}

		mServer.setHandlers(handlers);
//		if( System.getProperty("mxbeans") != null ) {
//			System.clearProperty("mxbeans");
//			MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
//		    MBeanContainer mBeanContainer = new MBeanContainer(mBeanServer);
//		    mServer.getContainer().addEventListener(mBeanContainer);
//		    mBeanContainer.start();
//		}
		logger.info("port: " + inPort);
	}