@Override
  public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) {
    assert totalRead < contentLength;
    int remaining = bb.remaining();
    int toRead = Math.min(contentLength - totalRead, remaining);

    bb.get(transformed, toRead);

    totalRead += transformed.remaining();
    super.onDataAvailable(emitter, transformed);
    if (totalRead == contentLength) report(null);
  }
    @Override
    public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) {
      if (cached != null) {
        com.koushikdutta.async.Util.emitAllData(this, cached);
        // couldn't emit it all, so just wait for another day...
        if (cached.remaining() > 0) return;
        cached = null;
      }

      // write to cache... any data not consumed needs to be retained for the next callback
      try {
        if (cacheRequest != null) {
          OutputStream outputStream = cacheRequest.getBody();
          if (outputStream != null) {
            int count = bb.size();
            for (int i = 0; i < count; i++) {
              ByteBuffer b = bb.remove();
              outputStream.write(b.array(), b.arrayOffset() + b.position(), b.remaining());
              bb.add(b);
            }
          } else {
            abort();
          }
        }
      } catch (Exception e) {
        abort();
      }

      super.onDataAvailable(emitter, bb);

      if (cacheRequest != null && bb.remaining() > 0) {
        cached = new ByteBufferList();
        cached.add(bb);
        bb.clear();
      }
    }
  @Override
  public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) {
    try {
      ByteBufferList transformed = new ByteBufferList();
      ByteBuffer output = ByteBuffer.allocate(bb.remaining() * 2);
      int totalInflated = 0;
      int totalRead = 0;
      while (bb.size() > 0) {
        ByteBuffer b = bb.remove();
        if (b.hasRemaining()) {
          totalRead = +b.remaining();
          mInflater.setInput(b.array(), b.arrayOffset() + b.position(), b.remaining());
          do {
            int inflated =
                mInflater.inflate(
                    output.array(), output.arrayOffset() + output.position(), output.remaining());
            totalInflated += inflated;
            output.position(output.position() + inflated);
            if (!output.hasRemaining()) {
              output.limit(output.position());
              output.position(0);
              transformed.add(output);
              Assert.assertNotSame(totalRead, 0);
              int newSize = output.capacity() * 2;
              output = ByteBuffer.allocate(newSize);
            }
          } while (!mInflater.needsInput() && !mInflater.finished());
        }
      }
      output.limit(output.position());
      output.position(0);
      transformed.add(output);

      Util.emitAllData(this, transformed);
    } catch (Exception ex) {
      report(ex);
    }
  }
 @Override
 public void write(ByteBufferList bb) {
   // it's gonna write headers and stuff... whatever
   bb.clear();
 }
 @Override
 public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) {
   if (data == null) data = new ByteBufferList();
   data.add(bb);
   bb.clear();
 }