class CouponIborAverageDiscountingMethod {

  public MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final CouponIborAverage coupon, final MulticurveProviderInterface multicurve) {
    ArgumentChecker.notNull(coupon, "Coupon");
    ArgumentChecker.notNull(multicurve, "Curves");
    final double forward1 = multicurve.getSimplyCompoundForwardRate(coupon.getIndex1(), coupon.getFixingPeriodStartTime1(), coupon.getFixingPeriodEndTime1(), coupon.getFixingAccrualFactor1());
    final double forward2 = multicurve.getSimplyCompoundForwardRate(coupon.getIndex2(), coupon.getFixingPeriodStartTime2(), coupon.getFixingPeriodEndTime2(), coupon.getFixingAccrualFactor2());
    final double forward = coupon.getWeight1() * forward1 + coupon.getWeight2() * forward2;
    final double df = multicurve.getDiscountFactor(coupon.getCurrency(), coupon.getPaymentTime());
    // Backward sweep
    final double pvBar = 1.0;
    final double forwardBar = coupon.getNotional() * coupon.getPaymentYearFraction() * df * pvBar;
    final double dfBar = coupon.getNotional() * coupon.getPaymentYearFraction() * forward * pvBar;
    final double forward1Bar = coupon.getWeight1() * forwardBar;
    final double forward2Bar = coupon.getWeight2() * forwardBar;
    final Map<String, List<DoublesPair>> mapDsc = new HashMap<>();
    final List<DoublesPair> listDiscounting = new ArrayList<>();
    listDiscounting.add(DoublesPair.of(coupon.getPaymentTime(), -coupon.getPaymentTime() * df * dfBar));
    mapDsc.put(multicurve.getName(coupon.getCurrency()), listDiscounting);
    final Map<String, List<ForwardSensitivity>> mapFwd = new HashMap<>();
    final List<ForwardSensitivity> listForward1 = new ArrayList<>();
    final List<ForwardSensitivity> listForward2 = new ArrayList<>();
    listForward1.add(new SimplyCompoundedForwardSensitivity(coupon.getFixingPeriodStartTime1(), coupon.getFixingPeriodEndTime1(), coupon.getFixingAccrualFactor1(), forward1Bar));
    mapFwd.put(multicurve.getName(coupon.getIndex1()), listForward1);
    listForward2.add(new SimplyCompoundedForwardSensitivity(coupon.getFixingPeriodStartTime2(), coupon.getFixingPeriodEndTime2(), coupon.getFixingAccrualFactor2(), forward2Bar));
    mapFwd.put(multicurve.getName(coupon.getIndex2()), listForward2);
    return MultipleCurrencyMulticurveSensitivity.of(coupon.getCurrency(), MulticurveSensitivity.of(mapDsc, mapFwd));
  }

  private  CouponIborAverageDiscountingMethod();

}