code: @Override
  	public void received(ByteBuffer deflated) {
  		if (ended) {
  			throw new IllegalStateException();
  		}
  
  		if (deflated.remaining() >= FOOTER_LENGTH) {
  			for (ByteBuffer b : previewFooter) {
  				if (!read(b)) {
  					return;
  				}
  			}
  			previewFooter.clear();
  			currentPreviewFooterLength = 0;
  			
  			ByteBuffer deflatedKeepingFooter = deflated.duplicate();
  			deflatedKeepingFooter.limit(deflatedKeepingFooter.limit() - FOOTER_LENGTH);
  			deflated.position(deflated.position() + deflatedKeepingFooter.remaining());
  			if (!read(deflatedKeepingFooter)) {
  				return;
  			}
  
  			currentPreviewFooterLength += deflated.remaining();
  			previewFooter.addLast(deflated.duplicate());
  			deflated.position(deflated.position() + deflated.remaining());
  			return;
  		} else {
  			currentPreviewFooterLength += deflated.remaining();
  			previewFooter.addLast(deflated.duplicate());
  			deflated.position(deflated.position() + deflated.remaining());
  
  			int toFlush = FOOTER_LENGTH - currentPreviewFooterLength;
  			while (toFlush > 0) {
  				ByteBuffer b = previewFooter.getFirst();
  
  				ByteBuffer d = b.duplicate();
  				d.limit(Math.min(d.limit(), toFlush));
  				b.position(b.position() + d.remaining());
  				toFlush -= d.remaining();
  				if (!read(d)) {
  					return;
  				}
  				if (!b.hasRemaining()) {
  					previewFooter.removeFirst();
  				}
  			}
  		}
  	}
docs: MUST sync-ly consume buffer