class ByteUtilities {

    public static boolean readUntilInclusive(PushbackInputStream in, OutputStream out, byte[] marker) throws IOException
    {
        int bytesRead;
        byte[] bytes = new byte[BUFFER_SIZE];
        byte[] mostRecentBytes = new byte[marker.length - 1];
        while ((bytesRead = in.read(bytes)) != -1)
        {
            if (bytesRead > 0)
            {
                int index = indexOf(bytes, bytesRead, marker);
                // Found the marker
                if (index != -1)
                {
                    int writeLength = index + marker.length;
                    out.write(bytes, 0, writeLength);
                    in.unread(bytes, writeLength, bytesRead - writeLength);
                    break;
                }
                else
                {
                    byte[] combinedBytes = concat(mostRecentBytes, bytes, Math.min(bytesRead, marker.length - 1));
                    index = indexOf(combinedBytes, combinedBytes.length, marker);
                    // Found the marker across chunks
                    if (index != -1)
                    {
                        out.write(bytes, 0, index + 1);
                        break;
                    }
                    else
                    {
                        out.write(bytes, 0, bytesRead);
                    }
                }

                shift(mostRecentBytes, bytes, bytesRead);
            }
        }
        return bytesRead == -1;
    }

    private  ByteUtilities();

}