private void invokeOnComplete(final IoCallback callback) {
    inCall = true;
    try {
      callback.onComplete(exchange, this);
    } finally {
      inCall = false;
    }
    while (next != null || pendingFile != null) {
      ByteBuffer[] next = this.next;
      IoCallback queuedCallback = this.queuedCallback;
      FileChannel file = this.pendingFile;
      this.next = null;
      this.queuedCallback = null;
      this.pendingFile = null;

      if (next != null) {
        for (ByteBuffer buffer : next) {
          writeBuffer(buffer, queuedCallback);
        }
      } else if (file != null) {
        performTransfer(file, queuedCallback);
      }
      inCall = true;
      try {
        queuedCallback.onComplete(exchange, this);
      } finally {
        inCall = false;
      }
    }
  }