private TransactionUpdater recalculate(List<TTransaction> list) {
    // the first one should not be updated at all (that is a pivot element)

    if (list.isEmpty()) {
      System.out.println(
          "[WARNING] pivot is null, list is empty. " + TransactionUpdater.class.getSimpleName());
      return this;
    }

    // list.isEmpty() == FALSE

    int offset;
    for (offset = 0; offset < list.size() && !list.get(offset).isPivot(); ++offset) ;

    /* in case when no pivot found: nothing to be done */
    if (offset == list.size()) return this;

    int balance = list.get(offset).getBalance();
    TChargeAccount ca = list.get(offset).getCa();

    info("offset = %d, list.size = %d", offset, list.size());
    for (int i = offset + 1; i < list.size(); ++i) {
      TTransaction t = list.get(i);

      if (t.isPivot()) {
        t.setAmount(t.getBalance() - balance);
        info("IS PIVOT: %s", t);

        /* henceforth use the new balance */
        balance = t.getBalance();
      } else {
        if (t.getCatransfer().equals(ca)) {
          /**
           * Transfer transaction (beneficiary side, who gets), balance: don't modify, because this
           * balance is that of the other one (who gives)
           */
          Assert.assertTrue(!t.getCa().equals(ca) && !t.getCa().equals(none));
          Assert.assertTrue(t.getCluster().equals(athelyezes) && athelyezes.getSgn() == -1);

          // t.setBalance(balance + t.getAmount());
          balance += t.getAmount();
        } else if (t.getCa().equals(ca)) {
          /**
           * Simple transaction, knowing the sign (direction: in/out) of the amount, which we are
           * talking about
           */
          Assert.assertTrue(!t.getCatransfer().equals(ca));

          t.setBalance(balance + t.getCluster().getSgn() * t.getAmount());
          balance = t.getBalance();
        }
      }
    }

    return this;
  }
  public void execute() {
    TTransaction old = args.getOldtr();
    TTransaction tr = args.getActtr();

    Assert.assertNotNull(tr.getCatransfer());
    Assert.assertTrue(!tr.getCa().equals(none));
    Assert.assertTrue(!tr.getCa().equals(tr.getCatransfer()));

    Date fromDate, toDate;
    if (old == null) {
      fromDate = tr.getDate();
      toDate = tr.getDate();
    } else {
      info("Old = " + old);
      info("New = " + tr);

      if (tr.getDate().getTime() < old.getDate().getTime()) {
        fromDate = tr.getDate();
        toDate = old.getDate();
      } else {
        fromDate = old.getDate();
        toDate = tr.getDate();
      }

      info("date from: " + Util.str(fromDate));
      info("date to: " + Util.str(toDate));
    }

    Assert.assertTrue(fromDate.getTime() <= toDate.getTime());

    /* update new from:ca */
    updateDirtyElements(fromDate, toDate, tr.getCa());

    /* update new to:ca */
    if (!tr.getCatransfer().equals(none)) {
      updateDirtyElements(fromDate, toDate, tr.getCatransfer());
    }

    // to be sure, tr.getCa() [new from:ca] & tr.getCatransfer() [new to:ca]
    // are already validated

    if (old == null) return;

    Assert.assertNotNull(old.getCatransfer());
    Assert.assertTrue(!old.getCa().equals(none));
    Assert.assertTrue(!old.getCa().equals(old.getCatransfer()));

    /* update old from:ca */
    if (!old.getCa().equals(tr.getCa()) && !old.getCa().equals(tr.getCatransfer())) {
      updateDirtyElements(fromDate, toDate, old.getCa());
    }

    /* update old to:ca */
    if (!old.getCatransfer().equals(none)
        && !old.getCatransfer().equals(tr.getCa())
        && !old.getCatransfer().equals(tr.getCatransfer())) {
      updateDirtyElements(fromDate, toDate, old.getCatransfer());
    }
  }