class LzssCodec {

	public static void decompress(OutputStream dst, InputStream src) throws IOException {
		/* Ring buffer of size N, with extra F-1 bytes to aid string comparison */
		ByteBuffer textBuf = ByteBuffer.allocate(N + F - 1);

		int flags;

		for (int i = 0; i < N - F; i++) {
			textBuf.put((byte) ' ');
		}
		textBuf.position(N - F);
		flags = 0;
		for (;;) {
			if (((flags >>>= 1) & 0x100) == 0) {
				int c = src.read();
				if (c == -1) {
					break;
				}
				flags = c | 0xFF00; /* uses higher byte cleverly */
			} /* count to eight */
			if ((flags & 1) != 0) {
				int c = src.read();
				if (c == -1) {
					break;
				}
				dst.write(c);
				textBuf.put((byte) c);
				textBuf.position(textBuf.position() & (N - 1));
			}
			else {
				int i = src.read();
				if (i == -1) {
					break;
				}
				int j = src.read();
				if (j == -1) {
					break;
				}
				i |= ((j & 0xF0) << 4);
				j = (j & 0x0F) + THRESHOLD;
				for (int k = 0; k <= j; k++) {
					int c = textBuf.get((i + k) & (N - 1));
					dst.write(c);
					textBuf.put((byte) c);
					textBuf.position(textBuf.position() & (N - 1));
				}
			}
		}
		dst.flush();
	}

}