/** {@inheritDoc} */
  public void doShutdown() {
    if (protocolAcceptor != null) {
      try {
        protocolAcceptor.close();
      } catch (IOException ignore) {
      }
    }
    for (ClientSessionHandler handler : handlers.values()) {
      handler.shutdown();
    }
    handlers.clear();

    if (exporter != null) {
      try {
        exporter.unexport();
        logger.log(Level.FINEST, "client session server unexported");
      } catch (RuntimeException e) {
        logger.logThrow(Level.FINEST, e, "unexport server throws");
        // swallow exception
      }
    }

    synchronized (flushContextsLock) {
      flushContextsLock.notifyAll();
    }
  }
  /** {@inheritDoc} */
  public void doShutdown() {
    final IoFuture<?, ?> future = acceptFuture;
    acceptFuture = null;
    if (future != null) {
      future.cancel(true);
    }

    if (acceptor != null) {
      try {
        acceptor.close();
      } catch (IOException e) {
        logger.logThrow(Level.FINEST, e, "closing acceptor throws");
        // swallow exception
      }
    }

    if (asyncChannelGroup != null) {
      asyncChannelGroup.shutdown();
      boolean groupShutdownCompleted = false;
      try {
        groupShutdownCompleted = asyncChannelGroup.awaitTermination(1, TimeUnit.SECONDS);
      } catch (InterruptedException e) {
        logger.logThrow(Level.FINEST, e, "shutdown acceptor interrupted");
        Thread.currentThread().interrupt();
      }
      if (!groupShutdownCompleted) {
        logger.log(Level.WARNING, "forcing async group shutdown");
        try {
          asyncChannelGroup.shutdownNow();
        } catch (IOException e) {
          logger.logThrow(Level.FINEST, e, "shutdown acceptor throws");
          // swallow exception
        }
      }
    }
    logger.log(Level.FINEST, "acceptor shutdown");

    if (exporter != null) {
      try {
        exporter.unexport();
        logger.log(Level.FINEST, "client session server unexported");
      } catch (RuntimeException e) {
        logger.logThrow(Level.FINEST, e, "unexport server throws");
        // swallow exception
      }
    }

    for (ClientSessionHandler handler : handlers.values()) {
      handler.shutdown();
    }
    handlers.clear();

    flushContextsThread.interrupt();
  }