/** Stops Jetty. */
  private void stopJetty() {
    // Jetty does not really stop the server if port is busy.
    try {
      if (httpSrv != null) {
        // If server was successfully started, deregister ports.
        if (httpSrv.isStarted()) ctx.ports().deregisterPorts(getClass());

        // Record current interrupted status of calling thread.
        boolean interrupted = Thread.interrupted();

        try {
          httpSrv.stop();
        } finally {
          // Reset interrupted flag on calling thread.
          if (interrupted) Thread.currentThread().interrupt();
        }
      }
    } catch (InterruptedException ignored) {
      if (log.isDebugEnabled()) log.debug("Thread has been interrupted.");

      Thread.currentThread().interrupt();
    } catch (Exception e) {
      U.error(log, "Failed to stop Jetty HTTP server.", e);
    }
  }
  /**
   * Checks that the only connector configured for the current jetty instance and returns it.
   *
   * @return Connector instance.
   * @throws GridException If no or more than one connectors found.
   */
  private AbstractNetworkConnector getJettyConnector() throws GridException {
    if (httpSrv.getConnectors().length == 1) {
      Connector connector = httpSrv.getConnectors()[0];

      if (!(connector instanceof AbstractNetworkConnector))
        throw new GridException(
            "Error in jetty configuration. Jetty connector should extend "
                + "AbstractNetworkConnector class.");

      return (AbstractNetworkConnector) connector;
    } else
      throw new GridException(
          "Error in jetty configuration [connectorsFound="
              + httpSrv.getConnectors().length
              + "connectorsExpected=1]");
  }
  /**
   * @throws GridException If failed.
   * @return {@code True} if Jetty started.
   */
  @SuppressWarnings("IfMayBeConditional")
  private boolean startJetty() throws GridException {
    try {
      httpSrv.start();

      if (httpSrv.isStarted()) {
        for (Connector con : httpSrv.getConnectors()) {
          int connPort = ((NetworkConnector) con).getPort();

          if (connPort > 0) ctx.ports().registerPort(connPort, TCP, getClass());
        }

        return true;
      }

      return false;
    } catch (SocketException ignore) {
      if (log.isDebugEnabled()) log.debug("Failed to bind HTTP server to configured port.");

      stopJetty();

      return false;
    } catch (MultiException e) {
      if (log.isDebugEnabled()) log.debug("Caught multi exception: " + e);

      for (Object obj : e.getThrowables())
        if (!(obj instanceof SocketException))
          throw new GridException("Failed to start Jetty HTTP server.", e);

      if (log.isDebugEnabled()) log.debug("Failed to bind HTTP server to configured port.");

      stopJetty();

      return false;
    } catch (Exception e) {
      throw new GridException("Failed to start Jetty HTTP server.", e);
    }
  }
  /**
   * Loads jetty configuration from the given URL.
   *
   * @param cfgUrl URL to load configuration from.
   * @throws GridException if load failed.
   */
  private void loadJettyConfiguration(@Nullable URL cfgUrl) throws GridException {
    if (cfgUrl == null) {
      HttpConfiguration httpCfg = new HttpConfiguration();

      httpCfg.setSecureScheme("https");
      httpCfg.setSecurePort(8443);
      httpCfg.setSendServerVersion(true);
      httpCfg.setSendDateHeader(true);

      String srvPortStr = System.getProperty(GG_JETTY_PORT, "8080");

      int srvPort;

      try {
        srvPort = Integer.valueOf(srvPortStr);
      } catch (NumberFormatException ignore) {
        throw new GridException(
            "Failed to start Jetty server because GRIDGAIN_JETTY_PORT system property "
                + "cannot be cast to integer: "
                + srvPortStr);
      }

      httpSrv = new Server(new QueuedThreadPool(20, 200));

      ServerConnector srvConn = new ServerConnector(httpSrv, new HttpConnectionFactory(httpCfg));

      srvConn.setHost(System.getProperty(GG_JETTY_HOST, "localhost"));
      srvConn.setPort(srvPort);
      srvConn.setIdleTimeout(30000L);
      srvConn.setReuseAddress(true);

      httpSrv.addConnector(srvConn);

      httpSrv.setStopAtShutdown(false);
    } else {
      XmlConfiguration cfg;

      try {
        cfg = new XmlConfiguration(cfgUrl);
      } catch (FileNotFoundException e) {
        throw new GridSpiException("Failed to find configuration file: " + cfgUrl, e);
      } catch (SAXException e) {
        throw new GridSpiException("Failed to parse configuration file: " + cfgUrl, e);
      } catch (IOException e) {
        throw new GridSpiException("Failed to load configuration file: " + cfgUrl, e);
      } catch (Exception e) {
        throw new GridSpiException(
            "Failed to start HTTP server with configuration file: " + cfgUrl, e);
      }

      try {
        httpSrv = (Server) cfg.configure();
      } catch (Exception e) {
        throw new GridException("Failed to start Jetty HTTP server.", e);
      }
    }

    assert httpSrv != null;

    httpSrv.setHandler(jettyHnd);

    override(getJettyConnector());
  }