/** Writes as many messages as possible to the sink. */
  public synchronized boolean handleWrite() throws IOException {
    if (channel == null) throw new IllegalStateException("writing with no source.");

    buffer.flip();
    while (buffer.hasRemaining() && channel.write(buffer) > 0) ;

    boolean remaining = buffer.hasRemaining();
    if (remaining) {
      buffer.compact();
      return true;
    } else {
      buffer.clear();
      channel.interestWrite(this, false);
      return false;
    }
  }
  /**
   * Adds <code>data</code> to the buffer and signals interest in writing to the channel.
   *
   * @throws IOException If the channel is already shutdown
   * @throws BufferOverflowException If there is insufficient space in the buffer
   */
  public synchronized void put(byte[] data) throws IOException {
    if (shutdown) {
      throw new EOFException();
    }

    buffer.put(data);

    if (channel != null) channel.interestWrite(this, true);
  }
 /** The channel we're writing to. */
 public synchronized void setWriteChannel(InterestWritableByteChannel channel) {
   this.channel = channel;
   channel.interestWrite(this, true);
 }