code: @NotNull
  	public ByteBuf takeAtLeast(int size) {
  		assert hasRemainingBytes(size);
  		if (size == 0) return ByteBuf.empty();
  		ByteBuf buf = bufs[first];
  		if (buf.readRemaining() >= size) {
  			first = next(first);
  			return buf;
  		}
  		ByteBuf result = ByteBufPool.allocate(size);
  		drainTo(result.array(), 0, size);
  		result.moveTail(size);
  		return result;
  	}
docs: Creates and returns a ByteBuf which contains at least {@code size}
  bytes from queue's first ByteBuf if the latter contains enough bytes.
  Then {@code first} index is increased by 1 or set to the value 0 if it
  has run a full circle of the queue.
  <p>
  Otherwise a new ByteBuf is allocated from the {@link ByteBufPool} with
  {@code size} bytes which contains all data from the queue's first ByteBuf.
  
  @param size the minimum size of returned ByteBuf
  @return a ByteBuf which contains at least {@code size} bytes