/**
   * Transfer resources between two stocks. This method uses compensation to recover from race
   * conditions instead of locking to avoid them altogether. Arguably, this scheme provides better
   * concurrency performance.
   *
   * @param buyer
   * @param seller
   * @return the amount transfered
   */
  @Override
  protected int transfer(ResourceStock buyer, ResourceStock seller) {
    while (true) {
      int wanted = buying.count(buyer);
      int available = selling.count(seller);
      int transfer = Math.min(available, wanted);

      if (transfer == 0) {
        return 0;
      }

      boolean procured = selling.setCount(seller, available, available - transfer);
      if (procured) {
        boolean sent = buying.setCount(buyer, wanted, wanted - transfer);
        if (sent) {
          try {
            seller.remove(transfer);
          } catch (RuntimeException e) {
            selling.add(seller, transfer);
            buying.remove(buyer, transfer);
            continue;
          }
          try {
            buyer.add(transfer);
          } catch (RuntimeException e) {
            // market takes care of what was sold.
            // To fully solve this case, 2PCommit or 3PC is
            // required. Is it worth?
            buying.remove(buyer, transfer);
            continue;
          }
          logTransfer(seller, buyer, transfer);

          return transfer;
        } else {
          // Compensation. restore what we took from the order!
          selling.add(seller, transfer);
        }
      }
      // Reaching here mean we hit a race condition. Try again.
    }
  }