// -------------------------------------------------------------------------
  public void test_cashFlowEquivalentAndSensitivity() {
    Swap swap = Swap.builder().legs(IBOR_LEG, FIXED_LEG).build();
    ImmutableMap<NotionalExchange, PointSensitivityBuilder> computedFull =
        CashFlowEquivalentCalculator.cashFlowEquivalentAndSensitivitySwap(swap.expand(), PROVIDER);
    ImmutableList<NotionalExchange> keyComputedFull = computedFull.keySet().asList();
    ImmutableList<PointSensitivityBuilder> valueComputedFull = computedFull.values().asList();
    ImmutableMap<NotionalExchange, PointSensitivityBuilder> computedIborLeg =
        CashFlowEquivalentCalculator.cashFlowEquivalentAndSensitivityIborLeg(
            IBOR_LEG.expand(), PROVIDER);
    ImmutableMap<NotionalExchange, PointSensitivityBuilder> computedFixedLeg =
        CashFlowEquivalentCalculator.cashFlowEquivalentAndSensitivityFixedLeg(
            FIXED_LEG.expand(), PROVIDER);
    assertEquals(computedFixedLeg.keySet().asList(), keyComputedFull.subList(0, 2));
    assertEquals(computedIborLeg.keySet().asList(), keyComputedFull.subList(2, 6));
    assertEquals(computedFixedLeg.values().asList(), valueComputedFull.subList(0, 2));
    assertEquals(computedIborLeg.values().asList(), valueComputedFull.subList(2, 6));

    double eps = 1.0e-7;
    RatesFiniteDifferenceSensitivityCalculator calc =
        new RatesFiniteDifferenceSensitivityCalculator(eps);
    int size = keyComputedFull.size();
    for (int i = 0; i < size; ++i) {
      final int index = i;
      CurveCurrencyParameterSensitivities expected =
          calc.sensitivity(
              PROVIDER,
              p ->
                  ((NotionalExchange)
                          CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap.expand(), p)
                              .getPaymentEvents()
                              .get(index))
                      .getPaymentAmount());
      PointSensitivityBuilder point =
          computedFull.get(
              CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap.expand(), PROVIDER)
                  .getPaymentEvents()
                  .get(index));
      CurveCurrencyParameterSensitivities computed =
          PROVIDER.curveParameterSensitivity(point.build());
      assertTrue(computed.equalWithTolerance(expected, eps * NOTIONAL));
    }
  }
  public void test_cashFlowEquivalent() {
    Swap swap = Swap.builder().legs(IBOR_LEG, FIXED_LEG).build();
    ExpandedSwapLeg computed =
        CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap.expand(), PROVIDER);
    ExpandedSwapLeg computedIborLeg =
        CashFlowEquivalentCalculator.cashFlowEquivalentIborLeg(IBOR_LEG.expand(), PROVIDER);
    ExpandedSwapLeg computedFixedLeg =
        CashFlowEquivalentCalculator.cashFlowEquivalentFixedLeg(FIXED_LEG.expand(), PROVIDER);
    assertEquals(computedFixedLeg.getPaymentEvents(), computed.getPaymentEvents().subList(0, 2));
    assertEquals(computedIborLeg.getPaymentEvents(), computed.getPaymentEvents().subList(2, 6));

    // expected payments from fixed leg
    NotionalExchange fixedPayment1 =
        NotionalExchange.of(PAYMENT1, CurrencyAmount.of(GBP, NOTIONAL * RATE * PAY_YC1));
    NotionalExchange fixedPayment2 =
        NotionalExchange.of(PAYMENT2, CurrencyAmount.of(GBP, NOTIONAL * RATE * PAY_YC2));
    // expected payments from ibor leg
    LocalDate fixingSTART1 = GBP_LIBOR_3M.calculateEffectiveFromFixing(FIXING1);
    double fixedYearFraction1 =
        GBP_LIBOR_3M
            .getDayCount()
            .relativeYearFraction(
                fixingSTART1, GBP_LIBOR_3M.calculateMaturityFromEffective(fixingSTART1));
    double beta1 =
        (1d + fixedYearFraction1 * PROVIDER.iborIndexRates(GBP_LIBOR_3M).rate(FIXING1))
            * PROVIDER.discountFactor(GBP, PAYMENT1)
            / PROVIDER.discountFactor(GBP, fixingSTART1);
    NotionalExchange iborPayment11 =
        NotionalExchange.of(
            fixingSTART1, CurrencyAmount.of(GBP, -NOTIONAL * beta1 * PAY_YC1 / fixedYearFraction1));
    NotionalExchange iborPayment12 =
        NotionalExchange.of(
            PAYMENT1, CurrencyAmount.of(GBP, NOTIONAL * PAY_YC1 / fixedYearFraction1));
    LocalDate fixingSTART2 = GBP_LIBOR_3M.calculateEffectiveFromFixing(FIXING2);
    double fixedYearFraction2 =
        GBP_LIBOR_3M
            .getDayCount()
            .relativeYearFraction(
                fixingSTART2, GBP_LIBOR_3M.calculateMaturityFromEffective(fixingSTART2));
    double beta2 =
        (1d + fixedYearFraction2 * PROVIDER.iborIndexRates(GBP_LIBOR_3M).rate(FIXING2))
            * PROVIDER.discountFactor(GBP, PAYMENT2)
            / PROVIDER.discountFactor(GBP, fixingSTART2);
    NotionalExchange iborPayment21 =
        NotionalExchange.of(
            fixingSTART2, CurrencyAmount.of(GBP, -NOTIONAL * beta2 * PAY_YC2 / fixedYearFraction2));
    NotionalExchange iborPayment22 =
        NotionalExchange.of(
            PAYMENT2, CurrencyAmount.of(GBP, NOTIONAL * PAY_YC2 / fixedYearFraction2));

    ExpandedSwapLeg expected =
        ExpandedSwapLeg.builder()
            .type(OTHER)
            .payReceive(RECEIVE)
            .paymentEvents(
                fixedPayment1,
                fixedPayment2,
                iborPayment11,
                iborPayment12,
                iborPayment21,
                iborPayment22)
            .build();

    double eps = 1.0e-12;
    assertEquals(computed.getPaymentEvents().size(), expected.getPaymentEvents().size());
    for (int i = 0; i < 6; ++i) {
      NotionalExchange payCmp = (NotionalExchange) computed.getPaymentEvents().get(i);
      NotionalExchange payExp = (NotionalExchange) expected.getPaymentEvents().get(i);
      assertEquals(payCmp.getCurrency(), payExp.getCurrency());
      assertEquals(payCmp.getPaymentDate(), payExp.getPaymentDate());
      assertTrue(
          DoubleMath.fuzzyEquals(
              payCmp.getPaymentAmount().getAmount(),
              payExp.getPaymentAmount().getAmount(),
              NOTIONAL * eps));
    }
  }