package org.bitcoinj.quorums;

import org.bitcoinj.core.*;
import org.bitcoinj.crypto.BLSLazySignature;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;

public class InstantSendLock extends Message {

    static final String ISLOCK_REQUESTID_PREFIX = "islock";

    ArrayList<TransactionOutPoint> inputs;
    Sha256Hash txid;
    BLSLazySignature signature;

    public InstantSendLock() {

    }

    public InstantSendLock(NetworkParameters params, byte [] payload) {
        super(params, payload, 0);
    }

    @Override
    protected void parse() throws ProtocolException {
        int countInputs = (int)readVarInt();
        inputs = new ArrayList<TransactionOutPoint>(countInputs);
        for(int i = 0; i < countInputs; ++i) {
            TransactionOutPoint outpoint = new TransactionOutPoint(params, payload, cursor);
            cursor += outpoint.getMessageSize();
            inputs.add(outpoint);
        }

        txid = readHash();

        signature = new BLSLazySignature(params, payload, cursor);
        cursor += signature.getMessageSize();
        length = cursor - offset;
    }

    @Override
    protected void bitcoinSerializeToStream(OutputStream stream) throws IOException {
        stream.write(new VarInt(inputs.size()).encode());
        for(int i = 0; i < inputs.size(); ++i) {
            inputs.get(i).bitcoinSerialize(stream);
        }
        stream.write(txid.getReversedBytes());
        signature.bitcoinSerialize(stream);
    }

    public Sha256Hash getRequestId() {
        try {
            ByteArrayOutputStream bos = new UnsafeByteArrayOutputStream();
            Utils.stringToByteStream(ISLOCK_REQUESTID_PREFIX, bos);
            bos.write(new VarInt(inputs.size()).encode());
            for(TransactionOutPoint outpoint : inputs) {
                outpoint.bitcoinSerialize(bos);
            }
            return Sha256Hash.wrap(Sha256Hash.hashTwice(bos.toByteArray()));
        } catch (IOException x) {
            throw new RuntimeException(x);
        }
    }

    public Sha256Hash getHash() {
        try {
            UnsafeByteArrayOutputStream bos = new UnsafeByteArrayOutputStream(getMessageSize());
            bitcoinSerializeToStream(bos);
            return Sha256Hash.wrapReversed(Sha256Hash.hashTwice(bos.toByteArray()));
        } catch (IOException x) {
            throw new RuntimeException(x);
        }
    }

    @Override
    public String toString() {
        return String.format("InstantSendLock(%d inputs, txid=%s, sig=%s)", inputs.size(), txid, signature);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        InstantSendLock islock = (InstantSendLock)o;

        return getHash().equals(islock.getHash());
    }
}

@@ -220,16 +220,39 @@
 rayList;
+%0Aimport java.util.List;
 %0A%0Apublic
@@ -358,21 +358,16 @@
 %22;%0A%0A    
-Array
 List%3CTra
@@ -473,20 +473,237 @@
 endLock(
-) %7B%0A
+NetworkParameters params, List%3CTransactionOutPoint%3E inputs, Sha256Hash txid, BLSLazySignature signature) %7B%0A        super(params);%0A        this.inputs = inputs;%0A        this.txid = txid;%0A        this.signature = signature;
 %0A    %7D%0A%0A
@@ -960,35 +960,16 @@
 rayList%3C
-TransactionOutPoint
 %3E(countI
@@ -1565,42 +1565,44 @@
  for
-(int i = 0; i %3C inputs.size(); ++i
+ (TransactionOutPoint input : inputs
 ) %7B%0A
@@ -1622,16 +1622,8 @@
 nput
-s.get(i)
 .bit
@@ -2818,32 +2818,113 @@
 nature);%0A    %7D%0A%0A
+    @Override%0A    public int hashCode() %7B%0A        return txid.hashCode();%0A    %7D%0A%0A
     @Override%0A  
@@ -3117,16 +3117,16 @@
 ock)o;%0A%0A
-
         
@@ -3173,11 +3173,232 @@
 );%0A    %7D
+%0A%0A    public List%3CTransactionOutPoint%3E getInputs() %7B%0A        return inputs;%0A    %7D%0A%0A    public BLSLazySignature getSignature() %7B%0A        return signature;%0A    %7D%0A%0A    public Sha256Hash getTxId() %7B%0A        return txid;%0A    %7D
 %0A%7D%0A

Add constructor, getters, hashCode