public EndOfDayBalance toEndOfDayBalanceBoundedBy(
      final Money openingBalance, final LocalDateInterval boundedBy) {

    MonetaryCurrency currency = openingBalance.getCurrency();
    Money endOfDayBalance = openingBalance.copy();

    int numberOfDaysOfBalance = this.balanceNumberOfDays;

    LocalDate balanceStartDate = getTransactionLocalDate();
    LocalDate balanceEndDate = getEndOfBalanceLocalDate();

    if (boundedBy.startDate().isAfter(balanceStartDate)) {
      balanceStartDate = boundedBy.startDate();
      LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
      numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
    } else {
      if (isDeposit()) {
        endOfDayBalance = openingBalance.plus(getAmount(currency));
      } else if (isWithdrawal() || isWithdrawalFee()) {
        endOfDayBalance = openingBalance.minus(getAmount(currency));
      }
    }

    if (balanceEndDate.isAfter(boundedBy.endDate())) {
      balanceEndDate = boundedBy.endDate();
      LocalDateInterval spanOfBalance = LocalDateInterval.create(balanceStartDate, balanceEndDate);
      numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
    }

    return EndOfDayBalance.from(
        balanceStartDate, openingBalance, endOfDayBalance, numberOfDaysOfBalance);
  }
  public EndOfDayBalance toEndOfDayBalance(final Money openingBalance) {
    MonetaryCurrency currency = openingBalance.getCurrency();
    Money endOfDayBalance = openingBalance.copy();
    if (isDeposit()) {
      endOfDayBalance = openingBalance.plus(getAmount(currency));
    } else if (isWithdrawal() || isWithdrawalFee()) {
      endOfDayBalance = openingBalance.minus(getAmount(currency));
    }

    return EndOfDayBalance.from(
        getTransactionLocalDate(), openingBalance, endOfDayBalance, this.balanceNumberOfDays);
  }
  public EndOfDayBalance toEndOfDayBalance(
      final LocalDateInterval periodInterval, final MonetaryCurrency currency) {

    Money endOfDayBalance = Money.of(currency, this.runningBalance);
    Money openingBalance = endOfDayBalance;

    LocalDate balanceDate = periodInterval.startDate();

    int numberOfDays = periodInterval.daysInPeriodInclusiveOfEndDate();
    if (periodInterval.contains(getTransactionLocalDate())) {
      balanceDate = getTransactionLocalDate();
      LocalDateInterval newInterval =
          LocalDateInterval.create(getTransactionLocalDate(), periodInterval.endDate());
      numberOfDays = newInterval.daysInPeriodInclusiveOfEndDate();
    }

    return EndOfDayBalance.from(balanceDate, openingBalance, endOfDayBalance, numberOfDays);
  }
  public EndOfDayBalance toEndOfDayBalance(
      final Money openingBalance, final LocalDate nextTransactionDate) {

    MonetaryCurrency currency = openingBalance.getCurrency();
    Money endOfDayBalance = openingBalance.copy();
    if (isDeposit()) {
      endOfDayBalance = openingBalance.plus(getAmount(currency));
    } else if (isWithdrawal() || isWithdrawalFee()) {
      endOfDayBalance = openingBalance.minus(getAmount(currency));
    }

    int numberOfDays =
        LocalDateInterval.create(getTransactionLocalDate(), nextTransactionDate)
            .daysInPeriodInclusiveOfEndDate();
    if (!openingBalance.isEqualTo(endOfDayBalance) && numberOfDays > 1) {
      numberOfDays = numberOfDays - 1;
    }
    return EndOfDayBalance.from(
        getTransactionLocalDate(), openingBalance, endOfDayBalance, numberOfDays);
  }