/**
   * @param address The request bind address
   * @param handlerFactory A {@link Factory} to create an {@link IoHandler} if necessary
   * @return The {@link InetSocketAddress} to which the binding occurred
   * @throws IOException If failed to bind
   */
  private InetSocketAddress doBind(
      SshdSocketAddress address, Factory<? extends IoHandler> handlerFactory) throws IOException {
    if (acceptor == null) {
      FactoryManager manager = session.getFactoryManager();
      IoServiceFactory factory = manager.getIoServiceFactory();
      IoHandler handler = handlerFactory.create();
      acceptor = factory.createAcceptor(handler);
    }

    // TODO find a better way to determine the resulting bind address - what if multi-threaded
    // calls...
    Set<SocketAddress> before = acceptor.getBoundAddresses();
    try {
      InetSocketAddress bindAddress = address.toInetSocketAddress();
      acceptor.bind(bindAddress);

      Set<SocketAddress> after = acceptor.getBoundAddresses();
      if (GenericUtils.size(after) > 0) {
        after.removeAll(before);
      }
      if (GenericUtils.isEmpty(after)) {
        throw new IOException(
            "Error binding to " + address + "[" + bindAddress + "]: no local addresses bound");
      }

      if (after.size() > 1) {
        throw new IOException(
            "Multiple local addresses have been bound for " + address + "[" + bindAddress + "]");
      }
      return (InetSocketAddress) after.iterator().next();
    } catch (IOException bindErr) {
      Set<SocketAddress> after = acceptor.getBoundAddresses();
      if (GenericUtils.isEmpty(after)) {
        close();
      }
      throw bindErr;
    }
  }