@Override
  <V extends Number, A> Future<V> implRead(
      boolean isScatteringRead,
      ByteBuffer dst,
      ByteBuffer[] dsts,
      long timeout,
      TimeUnit unit,
      A attachment,
      CompletionHandler<V, ? super A> handler) {
    // setup task
    PendingFuture<V, A> result = new PendingFuture<V, A>(this, handler, attachment);
    ByteBuffer[] bufs;
    if (isScatteringRead) {
      bufs = dsts;
    } else {
      bufs = new ByteBuffer[1];
      bufs[0] = dst;
    }
    final ReadTask readTask = new ReadTask<V, A>(bufs, isScatteringRead, result);
    result.setContext(readTask);

    // schedule timeout
    if (timeout > 0L) {
      Future<?> timeoutTask =
          iocp.schedule(
              new Runnable() {
                public void run() {
                  readTask.timeout();
                }
              },
              timeout,
              unit);
      result.setTimeoutTask(timeoutTask);
    }

    // initiate I/O
    if (Iocp.supportsThreadAgnosticIo()) {
      readTask.run();
    } else {
      Invoker.invokeOnThreadInThreadPool(this, readTask);
    }
    return result;
  }