class BytesReferenceStreamInput extends StreamInput {
    private final BytesRefIterator iterator;
    private int sliceIndex;
    private BytesRef slice;
    private final int length; // the total size of the stream
    private int offset; // the current position of the stream

    BytesReferenceStreamInput(BytesRefIterator iterator, final int length) throws IOException {
        this.iterator = iterator;
        this.slice = iterator.next();
        this.length = length;
        this.offset = 0;
        this.sliceIndex = 0;
    }

    @Override
    public byte readByte() throws IOException {
        if (offset >= length) {
            throw new EOFException();
        }
        maybeNextSlice();
        byte b = slice.bytes[slice.offset + (sliceIndex++)];
        offset++;
        return b;
    }

    private void maybeNextSlice() throws IOException {
        while (sliceIndex == slice.length) {
            slice = iterator.next();
            sliceIndex = 0;
            if (slice == null) {
                throw new EOFException();
            }
        }
    }

    @Override
    public void readBytes(byte[] b, int bOffset, int len) throws IOException {
        if (offset + len > length) {
            throw new IndexOutOfBoundsException("Cannot read " + len + " bytes from stream with length " + length + " at offset " + offset);
        }
        read(b, bOffset, len);
    }

    @Override
    public int read() throws IOException {
        if (offset >= length) {
            return -1;
        }
        return Byte.toUnsignedInt(readByte());
    }

    @Override
    public int read(final byte[] b, final int bOffset, final int len) throws IOException {<FILL_FUNCTION_BODY>}

    @Override
    public void close() throws IOException {
        // do nothing
    }

    @Override
    public int available() throws IOException {
        return length - offset;
    }

    @Override
    protected void ensureCanReadBytes(int bytesToRead) throws EOFException {
        int bytesAvailable = length - offset;
        if (bytesAvailable < bytesToRead) {
            throw new EOFException("tried to read: " + bytesToRead + " bytes but only " + bytesAvailable + " remaining");
        }
    }

    @Override
    public long skip(long n) throws IOException {
        final int skip = (int) Math.min(Integer.MAX_VALUE, n);
        final int numBytesSkipped = Math.min(skip, length - offset);
        int remaining = numBytesSkipped;
        while (remaining > 0) {
            maybeNextSlice();
            int currentLen = Math.min(remaining, slice.length - sliceIndex);
            remaining -= currentLen;
            sliceIndex += currentLen;
            offset += currentLen;
            assert remaining >= 0 : "remaining: " + remaining;
        }
        return numBytesSkipped;
    }

    int getOffset() {
        return offset;
    }
}

        if (offset >= length) {
            return -1;
        }
        final int numBytesToCopy = Math.min(len, length - offset);
        int remaining = numBytesToCopy; // copy the full length or the remaining part
        int destOffset = bOffset;
        while (remaining > 0) {
            maybeNextSlice();
            final int currentLen = Math.min(remaining, slice.length - sliceIndex);
            assert currentLen > 0 : "length has to be > 0 to make progress but was: " + currentLen;
            System.arraycopy(slice.bytes, slice.offset + sliceIndex, b, destOffset, currentLen);
            destOffset += currentLen;
            remaining -= currentLen;
            sliceIndex += currentLen;
            offset += currentLen;
            assert remaining >= 0 : "remaining: " + remaining;
        }
        return numBytesToCopy;
    
<methods>public non-sealed void <init>() ,public abstract int available() throws java.io.IOException,public abstract void close() throws java.io.IOException,public org.elasticsearch.Version getVersion() ,public T[] readArray(Reader<T>, IntFunction<T[]>) throws java.io.IOException,public final boolean readBoolean() throws java.io.IOException,public abstract byte readByte() throws java.io.IOException,public byte[] readByteArray() throws java.io.IOException,public abstract void readBytes(byte[], int, int) throws java.io.IOException,public BytesRef readBytesRef() throws java.io.IOException,public BytesRef readBytesRef(int) throws java.io.IOException,public org.elasticsearch.common.bytes.BytesReference readBytesReference() throws java.io.IOException,public org.elasticsearch.common.bytes.BytesReference readBytesReference(int) throws java.io.IOException,public final double readDouble() throws java.io.IOException,public double[] readDoubleArray() throws java.io.IOException,public E readEnum(Class<E>) throws java.io.IOException,public EnumSet<E> readEnumSet(Class<E>) throws java.io.IOException,public T readException() throws java.io.IOException,public final float readFloat() throws java.io.IOException,public float[] readFloatArray() throws java.io.IOException,public void readFully(byte[]) throws java.io.IOException,public java.lang.Object readGenericValue() throws java.io.IOException,public org.elasticsearch.common.geo.GeoPoint readGeoPoint() throws java.io.IOException,public ImmutableOpenMap<K,V> readImmutableMap(Reader<K>, Reader<V>) throws java.io.IOException,public int readInt() throws java.io.IOException,public int[] readIntArray() throws java.io.IOException,public List<T> readList(Reader<T>) throws java.io.IOException,public long readLong() throws java.io.IOException,public long[] readLongArray() throws java.io.IOException,public Map<K,V> readMap(Supplier<Map<K,V>>, Reader<K>, Reader<V>) throws java.io.IOException,public Map<K,V> readMap(Reader<K>, Reader<V>) throws java.io.IOException,public Map<java.lang.String,java.lang.Object> readMap() throws java.io.IOException,public Map<K,List<V>> readMapOfLists(Reader<K>, Reader<V>) throws java.io.IOException,public C readNamedWriteable(Class<C>) throws java.io.IOException,public C readNamedWriteable(Class<C>, java.lang.String) throws java.io.IOException,public List<T> readNamedWriteableList(Class<T>) throws java.io.IOException,public T[] readOptionalArray(Reader<T>, IntFunction<T[]>) throws java.io.IOException,public final java.lang.Boolean readOptionalBoolean() throws java.io.IOException,public org.elasticsearch.common.bytes.BytesReference readOptionalBytesReference() throws java.io.IOException,public final java.lang.Double readOptionalDouble() throws java.io.IOException,public java.lang.Float readOptionalFloat() throws java.io.IOException,public java.lang.Long readOptionalLong() throws java.io.IOException,public C readOptionalNamedWriteable(Class<C>) throws java.io.IOException,public java.lang.String readOptionalString() throws java.io.IOException,public java.lang.String[] readOptionalStringArray() throws java.io.IOException,public io.crate.common.unit.TimeValue readOptionalTimeValue() throws java.io.IOException,public DateTimeZone readOptionalTimeZone() throws java.io.IOException,public java.lang.Integer readOptionalVInt() throws java.io.IOException,public T readOptionalWriteable(Reader<T>) throws java.io.IOException,public Set<T> readSet(Reader<T>) throws java.io.IOException,public short readShort() throws java.io.IOException,public java.lang.String readString() throws java.io.IOException,public java.lang.String[] readStringArray() throws java.io.IOException,public List<java.lang.String> readStringList() throws java.io.IOException,public io.crate.common.unit.TimeValue readTimeValue() throws java.io.IOException,public DateTimeZone readTimeZone() throws java.io.IOException,public int readVInt() throws java.io.IOException,public int[] readVIntArray() throws java.io.IOException,public long readVLong() throws java.io.IOException,public long[] readVLongArray() throws java.io.IOException,public long readZLong() throws java.io.IOException,public void setVersion(org.elasticsearch.Version) ,public static org.elasticsearch.common.io.stream.StreamInput wrap(byte[]) ,public static org.elasticsearch.common.io.stream.StreamInput wrap(byte[], int, int) <variables>private static final non-sealed Map<java.lang.Byte,java.util.concurrent.TimeUnit> BYTE_TIME_UNIT_MAP,private static final ThreadLocal<CharsRef> SMALL_SPARE,private static final int SMALL_STRING_LIMIT,private static final ThreadLocal<byte[]> STRING_READ_BUFFER,private CharsRef largeSpare,private org.elasticsearch.Version version