class HgOwnerKey implements Serializable {

    private final byte[] owner; // TODO: consider remove? since it seems to be useless
    private int keyCode = 0;// TODO: Be here OK?
    private byte[] key;
    // Sequence number, used for batch queries to ensure the order of returned results
    private int serialNo;

    /**
     * @param owner
     * @param key
     * @see HgOwnerKey:of(byte[] owner, byte[] key)
     */
    @Deprecated
    public HgOwnerKey(byte[] owner, byte[] key) {
        if (owner == null) {
            owner = EMPTY_BYTES;
        }
        if (key == null) {
            key = EMPTY_BYTES;
        }
        this.owner = owner;
        this.key = key;
    }

    public HgOwnerKey(int code, byte[] key) {
        if (key == null) {
            key = EMPTY_BYTES;
        }
        this.owner = EMPTY_BYTES;
        this.key = key;
        this.keyCode = code;
    }

    public static HgOwnerKey emptyOf() {
        return EMPTY_OWNER_KEY;
    }

    public static HgOwnerKey newEmpty() {
        return HgOwnerKey.of(EMPTY_BYTES, EMPTY_BYTES);
    }

    public static HgOwnerKey ownerOf(byte[] owner) {
        return new HgOwnerKey(owner, EMPTY_BYTES);
    }

    public static HgOwnerKey codeOf(int code) {
        return HgOwnerKey.of(EMPTY_BYTES, EMPTY_BYTES).setKeyCode(code);
    }

    public static HgOwnerKey of(byte[] owner, byte[] key) {
        return new HgOwnerKey(owner, key);
    }

    public static HgOwnerKey of(int keyCode, byte[] key) {
        return new HgOwnerKey(keyCode, key);
    }

    public byte[] getOwner() {
        return owner;
    }

    public byte[] getKey() {
        return key;
    }

    public int getKeyCode() {
        return keyCode;
    }

    public HgOwnerKey setKeyCode(int keyCode) {
        this.keyCode = keyCode;
        return this;
    }

    public HgOwnerKey codeToKey(int keyCode) {
        this.keyCode = keyCode;
        this.key = HgStoreClientUtil.toIntBytes(keyCode);
        return this;
    }

    public int getSerialNo() {
        return this.serialNo;
    }

    public HgOwnerKey setSerialNo(int serialNo) {
        this.serialNo = serialNo;
        return this;
    }

    @Override
    public boolean equals(Object o) {<FILL_FUNCTION_BODY>}

    @Override
    public int hashCode() {
        int result = Arrays.hashCode(owner);
        result = 31 * result + Arrays.hashCode(key);
        return result;
    }

    @Override
    public String toString() {
        return "HgOwnerKey{" +
               "owner=" + Arrays.toString(owner) +
               ", key=" + Arrays.toString(key) +
               ", code=" + keyCode +
               '}';
    }

}

        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        HgOwnerKey that = (HgOwnerKey) o;
        return Arrays.equals(owner, that.owner) && Arrays.equals(key, that.key);
    
<no_super_class>