Program: 86019
Project: 86019
Buggy source:
/** 
 * Updates the wallet by checking if this TX spends any of our outputs. This is not used normally because when we receive our own spends, we've already marked the outputs as spent previously (during tx creation) so there's no need to go through and do it again.
 */
private void updateForSpends(Transaction tx) throws VerificationException {
  for (  TransactionInput input : tx.inputs) {
    TransactionInput.ConnectionResult result=input.connect(unspent,false);
    if (result == TransactionInput.ConnectionResult.NO_SUCH_TX) {
      continue;
    }
 else     if (result == TransactionInput.ConnectionResult.ALREADY_SPENT) {
      Transaction doubleSpent=input.outpoint.fromTx;
      Transaction connected=doubleSpent.outputs.get((int)input.outpoint.index).getSpentBy().parentTransaction;
      if (pending.containsKey(connected.getHash())) {
        log.info("String_Node_Str",connected.getHashAsString());
        log.info("String_Node_Str");
        pending.remove(connected.getHash());
        dead.put(connected.getHash(),connected);
        input.connect(unspent,true);
        for (        WalletEventListener listener : eventListeners) {
synchronized (listener) {
            listener.onDeadTransaction(connected,tx);
          }
        }
      }
    }
 else     if (result == TransactionInput.ConnectionResult.SUCCESS) {
      Transaction connected=input.outpoint.fromTx;
      if (connected.getValueSentToMe(this,false).equals(BigInteger.ZERO)) {
        if (unspent.remove(connected.getHash()) != null) {
          log.info("String_Node_Str");
          log.info("String_Node_Str");
          spent.put(connected.getHash(),connected);
        }
      }
    }
  }
}

Fixed version (ground truth):
/** 
 * Updates the wallet by checking if this TX spends any of our outputs. This is not used normally because when we receive our own spends, we've already marked the outputs as spent previously (during tx creation) so there's no need to go through and do it again.
 */
private void updateForSpends(Transaction tx) throws VerificationException {
  for (  TransactionInput input : tx.inputs) {
    TransactionInput.ConnectionResult result=input.connect(unspent,false);
    if (result == TransactionInput.ConnectionResult.NO_SUCH_TX) {
      continue;
    }
 else     if (result == TransactionInput.ConnectionResult.ALREADY_SPENT) {
      Transaction doubleSpent=input.outpoint.fromTx;
      int index=(int)input.outpoint.index;
      TransactionOutput output=doubleSpent.outputs.get(index);
      TransactionInput spentBy=output.getSpentBy();
      Transaction connected=spentBy.parentTransaction;
      if (pending.containsKey(connected.getHash())) {
        log.info("String_Node_Str",connected.getHashAsString());
        log.info("String_Node_Str");
        pending.remove(connected.getHash());
        dead.put(connected.getHash(),connected);
        input.connect(unspent,true);
        for (        WalletEventListener listener : eventListeners) {
synchronized (listener) {
            listener.onDeadTransaction(connected,tx);
          }
        }
      }
    }
 else     if (result == TransactionInput.ConnectionResult.SUCCESS) {
      Transaction connected=input.outpoint.fromTx;
      if (connected.getValueSentToMe(this,false).equals(BigInteger.ZERO)) {
        if (unspent.remove(connected.getHash()) != null) {
          log.info("String_Node_Str");
          log.info("String_Node_Str");
          spent.put(connected.getHash(),connected);
        }
      }
    }
  }
}