void shutdown() {
   interrupt();
   final ClientConnection c = conn;
   if (c != null) {
     c.close();
   }
 }
 @Override
 public synchronized void shutdown() {
   if (!live) {
     return;
   }
   live = false;
   for (ClientConnection connection : connections.values()) {
     connection.close();
   }
   inSelector.shutdown();
   outSelector.shutdown();
   connectionLockMap.clear();
 }
  private ClientConnection getOrConnect(Address target, Authenticator authenticator)
      throws Exception {
    if (!smartRouting) {
      target = ownerConnectionFuture.getOrWaitForCreation().getEndPoint();
    }

    Address address = addressTranslator.translate(target);

    if (address == null) {
      throw new IOException("Address is required!");
    }

    ClientConnection clientConnection = connections.get(address);
    if (clientConnection == null) {
      final Object lock = getLock(address);
      synchronized (lock) {
        clientConnection = connections.get(address);
        if (clientConnection == null) {
          final ConnectionProcessor connectionProcessor =
              new ConnectionProcessor(address, authenticator, false);
          final ICompletableFuture<ClientConnection> future =
              executionService.submitInternal(connectionProcessor);
          try {
            clientConnection = future.get(connectionTimeout, TimeUnit.MILLISECONDS);
          } catch (Exception e) {
            future.cancel(true);
            throw new RetryableIOException(e);
          }
          ClientConnection current = connections.putIfAbsent(address, clientConnection);
          if (current != null) {
            clientConnection.close();
            clientConnection = current;
          }
        }
      }
    }
    return clientConnection;
  }
 public void removeEndpoint(Address address) {
   final ClientConnection clientConnection = connections.get(address);
   if (clientConnection != null) {
     clientConnection.close();
   }
 }
 @Override
 public void close() {
   close(null);
 }