class Acceptor {

  public void shutdown() throws CommunicationException {

    synchronized (m_socketSets) {
      // Prevent recursion and creation of new ResourcePools.

      if (m_isShutdown) {
        return;
      }

      m_isShutdown = true;
    }

    try {
      m_serverSocket.close();
    }
    catch (IOException e) {
      UncheckedInterruptedException.ioException(e);
      throw new CommunicationException("Error closing socket", e);
    }
    finally {
      // Interrupt the acceptor thread group.
      m_executor.shutdownNow();

      // We clone contents of m_socketSets and don't hold m_socketSets whilst
      // closing the ResourcePools to remove opportunity for dead lock with
      // events triggered by closing resources.
      final ResourcePool[] socketSets = cloneListOfSocketSets();

      for (int i = 0; i < socketSets.length; ++i) {
        socketSets[i].closeCurrentResources();
      }

      m_exceptionQueue.clear();
    }
  }

  public  Acceptor(String addressString,
                  int port,
                  int numberOfThreads,
                  TimeAuthority timeAuthority);

}