@Override
 public Map<String, List<DoublesPair>> visitSwap(
     final Swap<?, ?> swap, final YieldCurveBundle curves) {
   final Map<String, List<DoublesPair>> senseR = visit(swap.getSecondLeg(), curves);
   final Map<String, List<DoublesPair>> senseP = visit(swap.getFirstLeg(), curves);
   return addSensitivity(senseR, senseP);
 }
 @Override
 public MultipleCurrencyCurveSensitivityMarket visitSwap(
     final Swap<?, ?> swap, final IMarketBundle market) {
   final MultipleCurrencyCurveSensitivityMarket sensitivity1 = visit(swap.getFirstLeg(), market);
   final MultipleCurrencyCurveSensitivityMarket sensitivity2 = visit(swap.getSecondLeg(), market);
   return sensitivity1.plus(sensitivity2);
 }
 /**
  * For swaps the ParSpread is the spread to be added on each coupon of the first leg to obtain a
  * present value of zero. It is computed as the opposite of the present value of the swap divided
  * by the present value of a basis point of the first leg (as computed by the
  * PresentValueBasisPointCalculator).
  *
  * @param swap The swap.
  * @param curves The yield curve bundle.
  * @return The par spread.
  */
 @Override
 public Double visitSwap(final Swap<?, ?> swap, final YieldCurveBundle curves) {
   Validate.notNull(curves);
   Validate.notNull(swap);
   return -curves
           .getFxRates()
           .convert(swap.accept(PVMCC, curves), swap.getFirstLeg().getCurrency())
           .getAmount()
       / swap.getFirstLeg().accept(PVBPC, curves);
 }
  @Override
  public MulticurveSensitivity visitSwap(
      final Swap<?, ?> swap, final MulticurveProviderInterface multicurves) {
    ArgumentChecker.notNull(multicurves, "multicurve");
    ArgumentChecker.notNull(swap, "Swap");
    // if the swap is an On compounded (ie Brazilian like), the parspread formula is not the same.
    if (swap.getSecondLeg().getNthPayment(0) instanceof CouponONCompounded
        && swap.getFirstLeg().getNthPayment(0) instanceof CouponFixedAccruedCompounding
        && swap.getFirstLeg().getNumberOfPayments() == 1) {
      // Implementation note: check if the swap is a Brazilian swap.

      final MulticurveSensitivity pvcsFirstLeg =
          swap.getFirstLeg()
              .accept(PVCSMC, multicurves)
              .getSensitivity(swap.getFirstLeg().getCurrency());
      final MulticurveSensitivity pvcsSecondLeg =
          swap.getSecondLeg()
              .accept(PVCSMC, multicurves)
              .getSensitivity(swap.getSecondLeg().getCurrency());

      final CouponFixedAccruedCompounding cpnFixed =
          (CouponFixedAccruedCompounding) swap.getFirstLeg().getNthPayment(0);
      final double pvONCompoundedLeg =
          swap.getSecondLeg()
              .accept(PVMC, multicurves)
              .getAmount(swap.getSecondLeg().getCurrency());
      final double discountFactor =
          multicurves.getDiscountFactor(
              swap.getFirstLeg().getCurrency(), cpnFixed.getPaymentTime());
      final double paymentYearFraction = cpnFixed.getPaymentYearFraction();

      final double notional =
          ((CouponONCompounded) swap.getSecondLeg().getNthPayment(0)).getNotional();
      final double intermediateVariable =
          (1 / paymentYearFraction)
              * Math.pow(pvONCompoundedLeg / discountFactor / notional, 1 / paymentYearFraction - 1)
              / (discountFactor * notional);
      final MulticurveSensitivity modifiedpvcsFirstLeg =
          pvcsFirstLeg.multipliedBy(pvONCompoundedLeg * intermediateVariable / discountFactor);
      final MulticurveSensitivity modifiedpvcsSecondLeg =
          pvcsSecondLeg.multipliedBy(-intermediateVariable);

      return modifiedpvcsFirstLeg.plus(modifiedpvcsSecondLeg);
    }
    final Currency ccy1 = swap.getFirstLeg().getCurrency();
    final MultipleCurrencyMulticurveSensitivity pvcs = swap.accept(PVCSMC, multicurves);
    final MulticurveSensitivity pvcs1 =
        pvcs.converted(ccy1, multicurves.getFxRates()).getSensitivity(ccy1);
    final MulticurveSensitivity pvmqscs = swap.getFirstLeg().accept(PVMQSCSMC, multicurves);
    final double pvmqs = swap.getFirstLeg().accept(PVMQSMC, multicurves);
    final double pv =
        multicurves.getFxRates().convert(swap.accept(PVMC, multicurves), ccy1).getAmount();
    // Implementation note: Total pv in currency 1.
    return pvcs1.multipliedBy(-1.0 / pvmqs).plus(pvmqscs.multipliedBy(pv / (pvmqs * pvmqs)));
  }