@Test
  public void testDispose() throws IOException, InterruptedException {
    List threadsBefore = getThreadNames();
    final IoAcceptor acceptor = new NioSocketAcceptor();
    acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
    acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
    acceptor.setHandler(  new ServerHandler() );
    acceptor.getSessionConfig().setReadBufferSize( 2048 );
    acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
    acceptor.bind( new InetSocketAddress(PORT) );
    System.out.println("Server running ...");
    final NioSocketConnector connector = new NioSocketConnector();
    // Set connect timeout.
    connector.setConnectTimeoutMillis(30 * 1000L);
    connector.setHandler(new ClientHandler());
    connector.getFilterChain().addLast( "logger", new LoggingFilter() );
    connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
    // Start communication.
    ConnectFuture cf = connector.connect(new InetSocketAddress("localhost", 9123));
    cf.awaitUninterruptibly();
    IoSession session = cf.getSession();
    // send a message
    session.write("Hello World!\r");
    // wait until response is received
    CountDownLatch latch = (CountDownLatch) session.getAttribute("latch");
    latch.await();
    // close the session
    CloseFuture closeFuture = session.close(false);
    System.out.println("session.close called");
    //Thread.sleep(5);
    // wait for session close and then dispose the connector
    closeFuture.addListener(new IoFutureListener<IoFuture>() {
      public void operationComplete(IoFuture future) {
        System.out.println("managed session count=" + connector.getManagedSessionCount());
        System.out.println("Disposing connector ...");
        connector.dispose(true);
        System.out.println("Disposing connector ... *finished*");
      }
    });
    closeFuture.awaitUninterruptibly();    
    acceptor.dispose(true);
    List threadsAfter = getThreadNames();
    System.out.println("threadsBefore = " + threadsBefore);
    System.out.println("threadsAfter  = " + threadsAfter);