void apply(BlockImpl block) {
   block.apply();
   for (TransactionImpl transaction : block.getTransactions()) {
     if (!unconfirmedTransactions.containsKey(transaction.getId())) {
       transaction.applyUnconfirmed();
     }
     // TODO: Phaser not yet implemented
     // Phaser.processTransaction(transaction);
     transaction.apply();
     transactionHashes.put(transaction.getHash(), new TransactionHashInfo(transaction));
   }
   purgeExpiredHashes(block.getTimestamp());
 }
  private List<Transaction> processTransactions(
      List<TransactionImpl> transactions, final boolean sendToPeers) {
    List<Transaction> sendToPeersTransactions = new ArrayList<>();
    List<Transaction> addedUnconfirmedTransactions = new ArrayList<>();
    List<Transaction> addedDoubleSpendingTransactions = new ArrayList<>();

    for (TransactionImpl transaction : transactions) {

      try {

        int curTime = Convert.getEpochTime();
        if (transaction.getTimestamp() > curTime + 15
            || transaction.getExpiration() < curTime
            || transaction.getDeadline() > 1440) {
          continue;
        }

        synchronized (BlockchainImpl.getInstance()) {
          Long id = transaction.getId();
          if (TransactionDb.hasTransaction(id)
              || unconfirmedTransactions.containsKey(id)
              || !transaction.verify()) {
            continue;
          }

          if (transactionHashes.containsKey(transaction.getHash())
              || unconfirmedTransactionHashes.containsKey(transaction.getHash())) {
            continue;
          }

          if (transaction.applyUnconfirmed()) {
            if (sendToPeers) {
              if (nonBroadcastedTransactions.containsKey(id)) {
                Logger.logDebugMessage(
                    "Received back transaction "
                        + transaction.getStringId()
                        + " that we generated, will not forward to peers");
                nonBroadcastedTransactions.remove(id);
              } else {
                sendToPeersTransactions.add(transaction);
              }
            }
            unconfirmedTransactions.put(id, transaction);
            unconfirmedTransactionHashes.put(transaction.getHash(), transaction);
            addedUnconfirmedTransactions.add(transaction);
          } else {
            addedDoubleSpendingTransactions.add(transaction);
          }
        }

      } catch (RuntimeException e) {
        Logger.logMessage("Error processing transaction", e);
      }
    }

    if (sendToPeersTransactions.size() > 0) {
      Peers.sendToSomePeers(sendToPeersTransactions);
    }

    if (addedUnconfirmedTransactions.size() > 0) {
      transactionListeners.notify(
          addedUnconfirmedTransactions, Event.ADDED_UNCONFIRMED_TRANSACTIONS);
    }
    if (addedDoubleSpendingTransactions.size() > 0) {
      transactionListeners.notify(
          addedDoubleSpendingTransactions, Event.ADDED_DOUBLESPENDING_TRANSACTIONS);
    }
    return addedUnconfirmedTransactions;
  }