@SuppressWarnings("unused")
  @Test
  public void limitTest() {
    final LocalDate optionExpiry = getNextIMMDate(TRADE_DATE).minusDays(1);
    final double timeToExpiry = ACT365F.yearFraction(TRADE_DATE, optionExpiry);
    final CDSAnalytic fwdCDX = FACTORY.makeCDX(optionExpiry, Period.ofYears(5));
    final CDSAnalytic fwdStartingCDX = fwdCDX.withOffset(timeToExpiry);

    final double[] indexPUF = new double[] {0.0556, 0.0582, 0.0771, 0.0652};
    final CDSAnalytic[] indexCDS = FACTORY.makeCDX(TRADE_DATE, INDEX_PILLARS);

    final IntrinsicIndexDataBundle adjCurves =
        PSA.adjustCurves(indexPUF, indexCDS, INDEX_COUPON, YIELD_CURVE, INTRINSIC_DATA);
    final double fwdSpread =
        INDEX_CAL.defaultAdjustedForwardSpread(
            fwdStartingCDX, timeToExpiry, YIELD_CURVE, adjCurves);
    final double fwdAnnuity = INDEX_CAL.indexAnnuity(fwdStartingCDX, YIELD_CURVE, adjCurves);

    final BlackIndexOptionPricer pricerWithFwd =
        new BlackIndexOptionPricer(
            fwdCDX, timeToExpiry, YIELD_CURVE, INDEX_COUPON, fwdSpread, fwdAnnuity);
    final double modStrikeLimit = INDEX_COUPON + fwdCDX.getLGD() / fwdAnnuity;
    final double vol = 0.4;
    final double payLargeSpLimit =
        fwdAnnuity
            * BlackFormulaRepository.price(fwdSpread, modStrikeLimit, timeToExpiry, vol, true);
    final double recLargeSpLimit =
        fwdAnnuity
            * BlackFormulaRepository.price(fwdSpread, modStrikeLimit, timeToExpiry, vol, false);

    final double largeStrikeSp = 75.0;
    final double payLargeStrikeSp =
        pricerWithFwd.getOptionPriceForSpreadQuotedIndex(largeStrikeSp, vol, true);
    final double recLargeStrikeSp =
        pricerWithFwd.getOptionPriceForSpreadQuotedIndex(largeStrikeSp, vol, false);
    assertEquals(payLargeSpLimit, payLargeStrikeSp, 1.e-12);
    assertEquals(
        recLargeSpLimit,
        recLargeStrikeSp,
        1.e-3); // larger strike spread ends up with failure in root-finding

    /** Exception expected */
    final double negativeTime = -0.5;
    try {
      new BlackIndexOptionPricer(
          fwdCDX, negativeTime, YIELD_CURVE, INDEX_COUPON, fwdSpread, fwdAnnuity);
      throw new RuntimeException();
    } catch (final Exception e) {
      assertEquals("timeToExpiry must be positive. Value given " + negativeTime, e.getMessage());
    }
    try {
      new BlackIndexOptionPricer(
          fwdStartingCDX, timeToExpiry, YIELD_CURVE, INDEX_COUPON, fwdSpread, fwdAnnuity);
      throw new RuntimeException();
    } catch (final Exception e) {
      assertEquals("fwdCDS should be a Forward CDS", e.getMessage());
    }
    final double negativeCoupon = -150.0 * 1.0e-4;
    try {
      new BlackIndexOptionPricer(
          fwdCDX, timeToExpiry, YIELD_CURVE, negativeCoupon, fwdSpread, fwdAnnuity);
      throw new RuntimeException();
    } catch (final Exception e) {
      assertEquals("indexCoupon must be positive", e.getMessage());
    }
    final double negativeFwdSp = -0.5;
    try {
      new BlackIndexOptionPricer(
          fwdCDX, timeToExpiry, YIELD_CURVE, INDEX_COUPON, negativeFwdSp, fwdAnnuity);
      throw new RuntimeException();
    } catch (final Exception e) {
      assertEquals("defaultAdjustedFwdSpread must be positive", e.getMessage());
    }
    final double negativeAnn = -0.3;
    try {
      new BlackIndexOptionPricer(
          fwdCDX, timeToExpiry, YIELD_CURVE, INDEX_COUPON, fwdSpread, negativeAnn);
      throw new RuntimeException();
    } catch (final Exception e) {
      assertEquals("pvFwdAnnuity must be positive", e.getMessage());
    }
    final double largeAnn = fwdCDX.getProtectionEnd() * 2.0;
    try {
      new BlackIndexOptionPricer(
          fwdCDX, timeToExpiry, YIELD_CURVE, INDEX_COUPON, fwdSpread, largeAnn);
      throw new RuntimeException();
    } catch (final Exception e) {
      assertEquals(
          "Value of annuity of "
              + largeAnn
              + " is greater than length (in years) of forward CDS. Annuity should be given for unit notional",
          e.getMessage());
    }

    final double smallStrike = -0.9;
    try {
      pricerWithFwd.getOptionPriceForPriceQuotedIndex(smallStrike, vol, true);
      throw new RuntimeException();
    } catch (final Exception e) {
      assertTrue(e instanceof IllegalArgumentException);
    }
    final double largeStrike = 0.9;
    try {
      pricerWithFwd.getOptionPriceForPriceQuotedIndex(largeStrike, vol, true);
      throw new RuntimeException();
    } catch (final Exception e) {
      assertTrue(e instanceof IllegalArgumentException);
    }
    try {
      pricerWithFwd.getOptionPriceForSpreadQuotedIndex(smallStrike, vol, true);
      throw new RuntimeException();
    } catch (final Exception e) {
      assertTrue(e instanceof IllegalArgumentException);
    }
  }