/**
   * Broadcast outgoing transactions.
   *
   * <p>This method should only be called from the wallet manager
   *
   * @return false if synchronization failed due to failed blockchain connection
   */
  public synchronized boolean broadcastOutgoingTransactions() {
    checkNotArchived();
    List<Sha256Hash> broadcastedIds = new LinkedList<Sha256Hash>();
    Map<Sha256Hash, byte[]> transactions = _backing.getOutgoingTransactions();

    for (byte[] rawTransaction : transactions.values()) {
      TransactionEx tex = TransactionEx.fromUnconfirmedTransaction(rawTransaction);

      BroadcastResult result = broadcastTransaction(TransactionEx.toTransaction(tex));
      if (result == BroadcastResult.SUCCESS) {
        broadcastedIds.add(tex.txid);
        _backing.removeOutgoingTransaction(tex.txid);
      } else {
        if (result == BroadcastResult.REJECTED) {
          // invalid tx
          _backing.deleteTransaction(tex.txid);
          _backing.removeOutgoingTransaction(tex.txid);
        } else {
          // No connection --> retry next sync
        }
      }
    }
    if (!broadcastedIds.isEmpty()) {
      onTransactionsBroadcasted(broadcastedIds);
    }
    return true;
  }
  private void markTransactionAsSpent(Transaction transaction) {
    _backing.beginTransaction();
    try {
      // Remove inputs from unspent, marking them as spent
      for (TransactionInput input : transaction.inputs) {
        TransactionOutputEx parentOutput = _backing.getUnspentOutput(input.outPoint);
        if (parentOutput != null) {
          _backing.deleteUnspentOutput(input.outPoint);
          _backing.putParentTransactionOutput(parentOutput);
        }
      }

      // See if any of the outputs are for ourselves and store them as
      // unspent
      for (int i = 0; i < transaction.outputs.length; i++) {
        TransactionOutput output = transaction.outputs[i];
        if (isMine(output.script)) {
          _backing.putUnspentOutput(
              new TransactionOutputEx(
                  new OutPoint(transaction.getHash(), i),
                  -1,
                  output.value,
                  output.script.getScriptBytes(),
                  false));
        }
      }

      // Store transaction locally, so we have it in our history and don't
      // need to fetch it in a minute
      _backing.putTransaction(TransactionEx.fromUnconfirmedTransaction(transaction));
      _backing.setTransactionSuccessful();
    } finally {
      _backing.endTransaction();
    }

    // Tell account that we have a new transaction
    onNewTransaction(TransactionEx.fromUnconfirmedTransaction(transaction), transaction);

    // Calculate local balance cache. It has changed because we have done
    // some spending
    updateLocalBalance();
    persistContextIfNecessary();
  }