class RLP {

	public static DecodeResult decode(byte[] data, int pos) {
		if (data == null || data.length < 1) {
			return null;
		}
		int prefix = data[pos] & 0xFF;
		if (prefix == OFFSET_SHORT_ITEM) {
			return new DecodeResult(pos+1, ""); // means no length or 0
		} else if (prefix < OFFSET_SHORT_ITEM) {
			return new DecodeResult(pos+1, new byte[] { data[pos] }); // byte is its own RLP encoding
		} else if (prefix < OFFSET_LONG_ITEM) {
			int len = prefix - OFFSET_SHORT_ITEM; // length of the encoded bytes
			return new DecodeResult(pos+1+len, copyOfRange(data, pos+1, pos+1+len));
		} else if (prefix < OFFSET_SHORT_LIST) {
			int lenlen = prefix - OFFSET_LONG_ITEM; // length of length the encoded bytes
			int lenbytes = byteArrayToInt(copyOfRange(data, pos+1, pos+1+lenlen)); // length of encoded bytes
			return new DecodeResult(pos+1+lenlen+lenbytes, copyOfRange(data, pos+1+lenlen, pos+1+lenlen+lenbytes));
		} else if (prefix <= OFFSET_LONG_LIST) {
			int len = prefix - OFFSET_SHORT_LIST; // length of the encoded list
			int prevPos = pos; pos++;
			return decodeList(data, pos, prevPos, len);
		} else if (prefix < 0xFF) {
			int lenlen = prefix - OFFSET_LONG_LIST; // length of length the encoded list
			int lenlist = byteArrayToInt(copyOfRange(data, pos+1, pos+1+lenlen)); // length of encoded bytes
		    pos = pos + lenlen + 1; // start at position of first element in list
		    int prevPos = lenlist;
		    return decodeList(data, pos, prevPos, lenlist);
		} else {
			throw new RuntimeException("Only byte values between 0x00 and 0xFF are supported, but got: " + prefix);
		}
	}

}