class AnnuityCapFloorCMSSpreadDefinition extends AnnuityDefinition<CapFloorCMSSpreadDefinition> {

  public static AnnuityCapFloorCMSSpreadDefinition from(final ZonedDateTime settlementDate, final ZonedDateTime maturityDate, final double notional, final IndexSwap index1, final IndexSwap index2,
      final Period paymentPeriod, final DayCount dayCount, final boolean isPayer, final double strike, final boolean isCap, final Calendar calendar1, final Calendar calendar2) {
    ArgumentChecker.notNull(settlementDate, "settlement date");
    ArgumentChecker.notNull(maturityDate, "maturity date");
    ArgumentChecker.notNull(index1, "First index");
    ArgumentChecker.notNull(index2, "Second index");
    ArgumentChecker.isTrue(notional > 0, "notional <= 0");
    ArgumentChecker.notNull(paymentPeriod, "Payment period");
    final ZonedDateTime[] paymentDatesUnadjusted = ScheduleCalculator.getUnadjustedDateSchedule(settlementDate, maturityDate, paymentPeriod, true, false);
    final ZonedDateTime[] paymentDates = ScheduleCalculator.getAdjustedDateSchedule(paymentDatesUnadjusted, index1.getIborIndex().getBusinessDayConvention(), calendar1,
        false);
    final double sign = isPayer ? -1.0 : 1.0;
    final CapFloorCMSSpreadDefinition[] coupons = new CapFloorCMSSpreadDefinition[paymentDates.length];
    coupons[0] = CapFloorCMSSpreadDefinition.from(paymentDates[0], settlementDate, paymentDates[0], dayCount.getDayCountFraction(settlementDate, paymentDates[0], calendar1),
        sign * notional, index1, index2, strike, isCap, calendar1, calendar2);
    for (int loopcpn = 1; loopcpn < paymentDates.length; loopcpn++) {
      coupons[loopcpn] = CapFloorCMSSpreadDefinition.from(paymentDates[loopcpn], paymentDates[loopcpn - 1], paymentDates[loopcpn],
          dayCount.getDayCountFraction(paymentDates[loopcpn - 1], paymentDates[loopcpn], calendar1), sign * notional, index1, index2, strike, isCap, calendar1, calendar2);
    }
    return new AnnuityCapFloorCMSSpreadDefinition(coupons, calendar1);
  }

  public  AnnuityCapFloorCMSSpreadDefinition(final CapFloorCMSSpreadDefinition[] payments, final Calendar calendar);

}