/** {@inheritDoc} */
  @Override
  public <A> IoFuture<Long, A> write(
      final ByteBuffer[] srcs,
      final int offset,
      final int length,
      long timeout,
      TimeUnit unit,
      A attachment,
      CompletionHandler<Long, ? super A> handler) {
    if ((offset < 0) || (offset >= srcs.length)) {
      throw new IllegalArgumentException("offset out of range");
    }
    if ((length < 0) || (length > (srcs.length - offset))) {
      throw new IllegalArgumentException("length out of range");
    }

    return key.execute(
        OP_WRITE,
        attachment,
        handler,
        timeout,
        unit,
        new Callable<Long>() {
          public Long call() throws IOException {
            try {
              return channel.write(srcs, offset, length);
            } catch (ClosedChannelException e) {
              throw Util.initCause(new AsynchronousCloseException(), e);
            }
          }
        });
  }
  /** {@inheritDoc} */
  @Override
  public <A> IoFuture<Void, A> connect(
      SocketAddress remote, final A attachment, final CompletionHandler<Void, ? super A> handler) {
    try {
      if (channel.connect(remote)) {
        Future<Void> result = Util.finishedFuture(null);
        key.runCompletion(handler, attachment, result);
        return AttachedFuture.wrap(result, attachment);
      }
    } catch (ClosedChannelException e) {
      throw Util.initCause(new ClosedAsynchronousChannelException(), e);
    } catch (IOException e) {
      Future<Void> result = Util.failedFuture(e);
      key.runCompletion(handler, attachment, result);
      return AttachedFuture.wrap(result, attachment);
    }

    return key.execute(
        OP_CONNECT,
        attachment,
        handler,
        0,
        TimeUnit.MILLISECONDS,
        new Callable<Void>() {
          public Void call() throws IOException {
            try {
              channel.finishConnect();
              return null;
            } catch (ClosedChannelException e) {
              throw Util.initCause(new AsynchronousCloseException(), e);
            }
          }
        });
  }
 /** {@inheritDoc} */
 @Override
 public <A> IoFuture<Integer, A> read(
     final ByteBuffer dst,
     long timeout,
     TimeUnit unit,
     A attachment,
     CompletionHandler<Integer, ? super A> handler) {
   if (timeout == 0) {
     timeout = socketTimeout;
     unit = TimeUnit.MILLISECONDS;
   }
   return key.execute(
       OP_READ,
       attachment,
       handler,
       timeout,
       unit,
       new Callable<Integer>() {
         public Integer call() throws IOException {
           try {
             return channel.read(dst);
           } catch (ClosedChannelException e) {
             throw Util.initCause(new AsynchronousCloseException(), e);
           }
         }
       });
 }
 /** {@inheritDoc} */
 @Override
 public <A> IoFuture<Integer, A> write(
     final ByteBuffer src,
     long timeout,
     TimeUnit unit,
     A attachment,
     CompletionHandler<Integer, ? super A> handler) {
   return key.execute(
       OP_WRITE,
       attachment,
       handler,
       timeout,
       unit,
       new Callable<Integer>() {
         public Integer call() throws IOException {
           try {
             return channel.write(src);
           } catch (ClosedChannelException e) {
             throw Util.initCause(new AsynchronousCloseException(), e);
           }
         }
       });
 }
 /** {@inheritDoc} */
 @Override
 public <A> IoFuture<AsynchronousSocketChannel, A> accept(
     A attachment, CompletionHandler<AsynchronousSocketChannel, ? super A> handler) {
   return key.execute(
       OP_ACCEPT,
       attachment,
       handler,
       0,
       TimeUnit.MILLISECONDS,
       new Callable<AsynchronousSocketChannel>() {
         public AsynchronousSocketChannel call() throws IOException {
           try {
             SocketChannel newChannel = channel.accept();
             if (newChannel == null) {
               // TODO re-execute on the key somehow? -JM
               throw new IOException("accept failed");
             }
             return new AsyncSocketChannelImpl(group, newChannel);
           } catch (ClosedChannelException e) {
             throw Util.initCause(new AsynchronousCloseException(), e);
           }
         }
       });
 }