class HTTPServer extends Server {

  private final ThreadPoolExecutor executorService;

  /**
   * Prepare a server on the given port - use run() to start it. Accepts
   * connections from localhost only.
   */
  public HTTPServer() {
    this(new HTTPServerConfig());
  }

  /**
   * Prepare a server on localhost on the given port - use run() to start it. Accepts
   * connections from localhost only.
   * @throws PortBindingException if we cannot bind to the given port, e.g. because something else is running there
   */
  public HTTPServer(HTTPServerConfig config) {
    this(config, false, DEFAULT_ALLOWED_IPS);
  }

  
  /**
   * Prepare a server on localhost on the given port - use run() to start it. Accepts
   * connections from localhost only.
   * @param runInternally if true, then the server was started from the GUI.
   * @throws PortBindingException if we cannot bind to the given port, e.g. because something else is running there
   */
  public HTTPServer(HTTPServerConfig config, boolean runInternally) {
    this(config, runInternally, DEFAULT_HOST, DEFAULT_ALLOWED_IPS);
  }

  
  /**
   * Prepare a server on localhost on the given port - use run() to start it. The server will bind to localhost.
   * @param runInternally if true, then the server was started from the GUI.
   * @param allowedIps the IP addresses from which connections are allowed or <code>null</code> to allow any host
   * @throws PortBindingException if we cannot bind to the given port, e.g. because something else is running there
   */
  public HTTPServer(HTTPServerConfig config, boolean runInternally, Set<String> allowedIps) {
    this(config, runInternally, DEFAULT_HOST, allowedIps);
  }
  
  /**
   * Prepare a server on the given host and port - use run() to start it.
   * @param runInternally if true, then the server was started from the GUI.
   * @param host the host to bind to, e.g. <code>"localhost"</code> or <code>null</code> to bind to any host
   * @param allowedIps the IP addresses from which connections are allowed or <code>null</code> to allow any host
   * @throws PortBindingException if we cannot bind to the given port, e.g. because something else is running there
   * @since 1.7
   */
  public HTTPServer(HTTPServerConfig config, boolean runInternally, String host, Set<String> allowedIps) {
    this.port = config.getPort();
    this.host = host;
    try {
      if (System.getProperty("monitorActiveRules") != null) {
        ManagementFactory.getPlatformMBeanServer().registerMBean(new ActiveRules(),
          ObjectName.getInstance("org.languagetool:name=ActiveRules, type=ActiveRules"));
      }
      RequestLimiter limiter = getRequestLimiterOrNull(config);
      ErrorRequestLimiter errorLimiter = getErrorRequestLimiterOrNull(config);
      executorService = getExecutorService(config);
      BlockingQueue<Runnable> workQueue = executorService.getQueue();
      httpHandler = new LanguageToolHttpHandler(config, allowedIps, runInternally, limiter, errorLimiter, workQueue, this);
      //check if port is 0 for get random port from range
      if (port == 0) {
        int minPort = config.getMinPort();
        int maxPort = config.getMaxPort();
        port = getPortFromRange(minPort, maxPort);
      }
      InetSocketAddress address = host != null ? new InetSocketAddress(host, port) : new InetSocketAddress(port);
      server = HttpServer.create(address, 0);
      server.createContext("/", httpHandler);
      server.setExecutor(executorService);

      if (config.isPrometheusMonitoring()) {
        ServerMetricsCollector.init(config);
      }
    } catch (Exception e) {
      ResourceBundle messages = JLanguageTool.getMessageBundle();
      String message = Tools.i18n(messages, "http_server_start_failed", host, Integer.toString(port));
      throw new PortBindingException(message, e);
    }
  }
  
  private int getPortFromRange(int minPort, int maxPort) throws IOException {
    if (minPort > 0 && minPort < maxPort) {
         log.info("Try to find a free Port for Server in range {}-{}", minPort, maxPort);
         for (int p = minPort; p <= maxPort; p++) {
           try {
             log.info("Check port {}", p);
             ServerSocket serverSocket = new ServerSocket(p);
             port = serverSocket.getLocalPort();
             serverSocket.close();
             log.info("Port {} is available.", p);
             return p;
           } catch (IOException ex) {
             log.debug("Port {} is not available.", p);
           }
         }
         throw new IOException("No free port in range ("+ minPort + " - " + maxPort + ") found.");
    } else {
      throw new IOException("Invalid port configuration found. " +
                            "The value for '--port' need to be greater than 0 or if set to 0 you need to specify a minPort and maxPort in your properties file (minPort must be lower that maxPort).");
    }
  }

  @Override
  public void stop() {
    super.stop();
    if (executorService != null) {
      executorService.shutdownNow();
    }
  }

  public static void main(String[] args) {<FILL_FUNCTION_BODY>}

  @Override
  protected String getProtocol() {
    return "http";
  }

}

    if (usageRequested(args)) {
      System.out.println("Usage: " + HTTPServer.class.getSimpleName() + " [--config propertyFile] [--port|-p port] [--public]");
      System.out.println("  --config FILE  a Java property file (one key=value entry per line) with values for:");
      printCommonConfigFileOptions();
      printCommonOptions();
      System.exit(1);
    }
    HTTPServerConfig config = new HTTPServerConfig(args);
    DatabaseAccess.init(config);
    try {
      checkForNonRootUser();
      HTTPServer server;
      if (config.isPublicAccess()) {
        ServerTools.print("WARNING: running in HTTP mode, consider running LanguageTool behind a reverse proxy that takes care of encryption (HTTPS)");
        ServerTools.print("WARNING: running in public mode, LanguageTool API can be accessed without restrictions!");
        server = new HTTPServer(config, false, null, null);
      } else {
        server = new HTTPServer(config, false, DEFAULT_HOST, DEFAULT_ALLOWED_IPS);
      }
      server.run();
    } catch (Exception e) {
      throw new RuntimeException("Could not start LanguageTool HTTP server on " + DEFAULT_HOST + ", port " + config.getPort(), e);
    }
  
<methods>public boolean isRunning() ,public void run() ,public void stop() <variables>protected static final Set<java.lang.String> DEFAULT_ALLOWED_IPS,protected java.lang.String host,protected org.languagetool.server.LanguageToolHttpHandler httpHandler,private boolean isRunning,protected int port,protected com.sun.net.httpserver.HttpServer server