public synchronized void freeze(final CoreRemotingConnection connectionToKeepOpen) {
    if (!started) return;
    failureCheckAndFlushThread.close(false);

    for (Acceptor acceptor : acceptors) {
      try {
        acceptor.pause();
      } catch (Exception e) {
        HornetQServerLogger.LOGGER.errorStoppingAcceptor();
      }
    }
    HashMap<Object, ConnectionEntry> connectionEntries =
        new HashMap<Object, ConnectionEntry>(connections);

    // Now we ensure that no connections will process any more packets after this method is
    // complete then send a disconnect packet
    for (Entry<Object, ConnectionEntry> entry : connectionEntries.entrySet()) {
      RemotingConnection conn = entry.getValue().connection;

      if (conn.equals(connectionToKeepOpen)) continue;

      if (HornetQServerLogger.LOGGER.isTraceEnabled()) {
        HornetQServerLogger.LOGGER.trace("Sending connection.disconnection packet to " + conn);
      }

      if (!conn.isClient()) {
        conn.disconnect(false);
        connections.remove(entry.getKey());
      }
    }
  }
  public void stop(final boolean criticalError) throws Exception {
    if (!started) {
      return;
    }

    failureCheckAndFlushThread.close(criticalError);

    // We need to stop them accepting first so no new connections are accepted after we send the
    // disconnect message
    for (Acceptor acceptor : acceptors) {
      if (HornetQServerLogger.LOGGER.isDebugEnabled()) {
        HornetQServerLogger.LOGGER.debug("Pausing acceptor " + acceptor);
      }
      acceptor.pause();
    }

    if (HornetQServerLogger.LOGGER.isDebugEnabled()) {
      HornetQServerLogger.LOGGER.debug("Sending disconnect on live connections");
    }

    HashSet<ConnectionEntry> connectionEntries = new HashSet<ConnectionEntry>(connections.values());

    // Now we ensure that no connections will process any more packets after this method is complete
    // then send a disconnect packet
    for (ConnectionEntry entry : connectionEntries) {
      RemotingConnection conn = entry.connection;

      if (HornetQServerLogger.LOGGER.isTraceEnabled()) {
        HornetQServerLogger.LOGGER.trace("Sending connection.disconnection packet to " + conn);
      }

      conn.disconnect(criticalError);
    }

    for (Acceptor acceptor : acceptors) {
      acceptor.stop();
    }

    acceptors.clear();

    connections.clear();

    if (managementService != null) {
      managementService.unregisterAcceptors();
    }

    threadPool.shutdown();

    if (!criticalError) {
      boolean ok = threadPool.awaitTermination(10000, TimeUnit.MILLISECONDS);

      if (!ok) {
        HornetQServerLogger.LOGGER.timeoutRemotingThreadPool();
      }
    }

    started = false;
  }