@Test
  public void testGetPaymentsAmortizedWithOverPayment() {

    AmortizationAttributes amAttrs = generateAmortizationAttributesObjectTemplate();
    amAttrs.setLoanAmount(ofUSD(10000));
    amAttrs.setInterestRateAsPercent(3.);
    amAttrs.setInterestOnly(false);
    amAttrs.setRegularPayment(ofUSD(400));
    amAttrs.setPaymentFrequency(TimePeriod.SemiMonthly.getPeriodsPerYear());
    int termInMonths = 24;
    amAttrs.setTermInMonths(termInMonths);
    amAttrs.setAmortizationPeriodInMonths(24);
    amAttrs.setCompoundingPeriodsPerYear(2);

    List<ScheduledPayment> schedule = AmortizationCalculator.generateSchedule(amAttrs);

    assertEquals(
        "Amortized payment count",
        amAttrs.getPaymentFrequency() * termInMonths / 12,
        schedule.size());

    MonetaryAmount interestTotal =
        schedule.stream().map(payment -> payment.getInterest()).reduce((a, b) -> a.add(b)).get();

    assertEquals("Amortized Interest total", ofUSD(164.81), interestTotal);
  }
  @Test
  public void testGenerateScheduleInterestOnlyArrayBounds() {
    AmortizationAttributes amAttrs = generateAmortizationAttributesObjectTemplate();
    amAttrs.setLoanAmount(ofUSD(10000));
    amAttrs.setInterestRateAsPercent(12.);
    amAttrs.setInterestOnly(true);
    amAttrs.setPaymentFrequency(TimePeriod.Weekly.getPeriodsPerYear());
    int termInMonths = 24;
    amAttrs.setTermInMonths(termInMonths);
    amAttrs.setAdjustmentDate(LocalDate.of(2016, Month.JANUARY, 1));

    List<ScheduledPayment> schedule = AmortizationCalculator.generateSchedule(amAttrs);

    try {
      schedule.get(-1);
      fail("Interest only schedule should not allow negative payment number");
    } catch (IndexOutOfBoundsException iobe) {
    }

    int expectedPayments =
        (int) Math.ceil(amAttrs.getPaymentFrequency() * amAttrs.getTermInMonths() / 12.);

    try {
      schedule.get(expectedPayments);
      fail("Interest only schedule should not allow payments beyond schedule bound");
    } catch (IndexOutOfBoundsException iobe) {
    }

    schedule.get(expectedPayments - 1);
  }