class AnnuityDefinitionBuilder {

  public static AnnuityCouponIborDefinition couponIborRollDate(final ZonedDateTime startDate, final int startNumberRollDate, final int endNumberRollDate,
      final RollDateAdjuster adjuster, final IborIndex index, final double notional, final boolean isPayer, final DayCount dayCount, final Calendar calendar) {
    final List<ZonedDateTime> legDates = new ArrayList<>();
    ZonedDateTime currentDate = RollDateAdjusterUtils.nthDate(startDate, adjuster, startNumberRollDate);
    legDates.add(ScheduleCalculator.getAdjustedDate(currentDate, 0, calendar));
    for (int looproll = 1; looproll <= endNumberRollDate - startNumberRollDate; looproll++) {
      currentDate = RollDateAdjusterUtils.nthDate(currentDate.plusDays(1), adjuster, 1);
      legDates.add(ScheduleCalculator.getAdjustedDate(currentDate, 0, calendar));
    }
    final double sign = isPayer ? -1.0 : 1.0;
    final int nbCpn = legDates.size() - 1;
    final CouponIborDefinition[] coupons = new CouponIborDefinition[nbCpn];
    for (int loopcpn = 0; loopcpn < nbCpn; loopcpn++) {
      final ZonedDateTime fixingDate = ScheduleCalculator.getAdjustedDate(legDates.get(loopcpn), -index.getSpotLag(), calendar);
      coupons[loopcpn] = new CouponIborDefinition(index.getCurrency(), legDates.get(loopcpn), legDates.get(loopcpn), legDates.get(loopcpn + 1),
          dayCount.getDayCountFraction(legDates.get(loopcpn), legDates.get(loopcpn + 1), calendar), sign * notional, fixingDate, index, calendar);
    }
    return new AnnuityCouponIborDefinition(coupons, index, calendar);
  }

}