class ForwardRateAgreementDiscountingMethod {

  public MultipleCurrencyMulticurveSensitivity presentValueCurveSensitivity(final ForwardRateAgreement fra, final MulticurveProviderInterface multicurve) {
    ArgumentChecker.notNull(fra, "FRA");
    ArgumentChecker.notNull(multicurve, "Multiurves");
    final double df = multicurve.getDiscountFactor(fra.getCurrency(), fra.getPaymentTime());
    final double forward = multicurve.getSimplyCompoundForwardRate(fra.getIndex(), fra.getFixingPeriodStartTime(), fra.getFixingPeriodEndTime(), fra.getFixingYearFraction());
    // Backward sweep
    final double pvBar = 1.0;
    final double forwardBar = df * fra.getPaymentYearFraction() * fra.getNotional() * (1 - (forward - fra.getRate()) / (1 + fra.getPaymentYearFraction() * forward) * fra.getPaymentYearFraction())
        / (1 + fra.getPaymentYearFraction() * forward);
    final double dfBar = fra.getPaymentYearFraction() * fra.getNotional() * (forward - fra.getRate()) / (1 + fra.getFixingYearFraction() * forward) * pvBar;
    final Map<String, List<DoublesPair>> mapDsc = new HashMap<>();
    final List<DoublesPair> listDiscounting = new ArrayList<>();
    listDiscounting.add(DoublesPair.of(fra.getPaymentTime(), -fra.getPaymentTime() * df * dfBar));
    mapDsc.put(multicurve.getName(fra.getCurrency()), listDiscounting);
    final Map<String, List<ForwardSensitivity>> mapFwd = new HashMap<>();
    final List<ForwardSensitivity> listForward = new ArrayList<>();
    listForward.add(new SimplyCompoundedForwardSensitivity(fra.getFixingPeriodStartTime(), fra.getFixingPeriodEndTime(), fra.getFixingYearFraction(), forwardBar));
    mapFwd.put(multicurve.getName(fra.getIndex()), listForward);
    final MultipleCurrencyMulticurveSensitivity result = MultipleCurrencyMulticurveSensitivity.of(fra.getCurrency(), MulticurveSensitivity.of(mapDsc, mapFwd));
    return result;
  }

  private  ForwardRateAgreementDiscountingMethod();

}