class CouponIborAverageFixingDatesCompoundingFlatSpreadDiscountingMethod {

  public MultipleCurrencyAmount presentValue(final CouponIborAverageFixingDatesCompoundingFlatSpread coupon, final MulticurveProviderInterface multicurves) {
    ArgumentChecker.notNull(coupon, "Coupon");
    ArgumentChecker.notNull(multicurves, "Multi-curves provider");
    final int nPeriods = coupon.getFixingTime().length;
    double payoff = coupon.getRateFixed();
    for (int i = 0; i < nPeriods; ++i) {
      double forwardAverage = ((i == 0) ? coupon.getAmountAccrued() : 0.0);
      final int nDates = coupon.getFixingTime()[i].length;
      for (int j = 0; j < nDates; ++j) {
        final double forward1 = multicurves.getSimplyCompoundForwardRate(coupon.getIndex(), coupon.getFixingPeriodStartTime()[i][j], coupon.getFixingPeriodEndTime()[i][j],
            coupon.getFixingPeriodAccrualFactor()[i][j]);
        forwardAverage += coupon.getWeight()[i][j] * forward1;
      }
      payoff += (forwardAverage + coupon.getSpread() + forwardAverage * payoff) * coupon.getPaymentAccrualFactors()[i];
    }
    final double df = multicurves.getDiscountFactor(coupon.getCurrency(), coupon.getPaymentTime());
    final double pv = coupon.getNotional() * payoff * df;
    return MultipleCurrencyAmount.of(coupon.getCurrency(), pv);
  }

  private  CouponIborAverageFixingDatesCompoundingFlatSpreadDiscountingMethod();

}