/** Attach to the specified address with optional attach and handshake timeout. */
  public Connection attach(String address, long attachTimeout, long handshakeTimeout)
      throws IOException {

    if (address == null) {
      throw new NullPointerException("address is null");
    }
    if (attachTimeout < 0 || handshakeTimeout < 0) {
      throw new IllegalArgumentException("timeout is negative");
    }

    int splitIndex = address.indexOf(':');
    String host;
    String portStr;
    if (splitIndex < 0) {
      host = InetAddress.getLocalHost().getHostName();
      portStr = address;
    } else {
      host = address.substring(0, splitIndex);
      portStr = address.substring(splitIndex + 1);
    }

    int port;
    try {
      port = Integer.decode(portStr).intValue();
    } catch (NumberFormatException e) {
      throw new IllegalArgumentException("unable to parse port number in address");
    }

    // open TCP connection to VM

    InetSocketAddress sa = new InetSocketAddress(host, port);
    Socket s = new Socket();
    try {
      s.connect(sa, (int) attachTimeout);
    } catch (SocketTimeoutException exc) {
      try {
        s.close();
      } catch (IOException x) {
      }
      throw new TransportTimeoutException("timed out trying to establish connection");
    }

    // handshake with the target VM
    try {
      handshake(s, handshakeTimeout);
    } catch (IOException exc) {
      try {
        s.close();
      } catch (IOException x) {
      }
      throw exc;
    }

    return new SocketConnection(s);
  }
    /*
     * Returns the string representation of the address that this
     * listen key represents.
     */
    public String address() {
      InetAddress address = ss.getInetAddress();

      /*
       * If bound to the wildcard address then use current local
       * hostname. In the event that we don't know our own hostname
       * then assume that host supports IPv4 and return something to
       * represent the loopback address.
       */
      if (address.isAnyLocalAddress()) {
        try {
          address = InetAddress.getLocalHost();
        } catch (UnknownHostException uhe) {
          byte[] loopback = {0x7f, 0x00, 0x00, 0x01};
          try {
            address = InetAddress.getByAddress("127.0.0.1", loopback);
          } catch (UnknownHostException x) {
            throw new InternalError("unable to get local hostname");
          }
        }
      }

      /*
       * Now decide if we return a hostname or IP address. Where possible
       * return a hostname but in the case that we are bound to an
       * address that isn't registered in the name service then we
       * return an address.
       */
      String result;
      String hostname = address.getHostName();
      String hostaddr = address.getHostAddress();
      if (hostname.equals(hostaddr)) {
        if (address instanceof Inet6Address) {
          result = "[" + hostaddr + "]";
        } else {
          result = hostaddr;
        }
      } else {
        result = hostname;
      }

      /*
       * Finally return "hostname:port", "ipv4-address:port" or
       * "[ipv6-address]:port".
       */
      return result + ":" + ss.getLocalPort();
    }