/**
   * The CS01 (or credit DV01) of a CDS - the sensitivity of the PV to a finite increase of market
   * spread (on NOT the CDS's coupon). If the CDS is quoted as points up-front, this is first
   * converted to a quoted spread, and <b>this</b> is bumped
   *
   * @param cds analytic description of a CDS traded at a certain time - it is this CDS that we are
   *     calculation CDV01 for
   * @param quote The market quote for the CDS - these can be ParSpread, PointsUpFront or
   *     QuotedSpread
   * @param yieldCurve The yield (or discount) curve
   * @param fracBumpAmount The fraction bump amount of the spread so a 1pb bump is 1e-4
   * @return the parallel CS01
   */
  public double parallelCS01(
      CdsAnalytic cds,
      CdsQuoteConvention quote,
      IsdaCompliantYieldCurve yieldCurve,
      double fracBumpAmount) {

    if (quote instanceof CdsQuotedSpread) {
      CdsQuotedSpread qSpread = (CdsQuotedSpread) quote;
      return parallelCS01FromParSpreads(
          cds,
          qSpread.getCoupon(),
          yieldCurve,
          new CdsAnalytic[] {cds},
          new double[] {qSpread.getQuotedSpread()},
          fracBumpAmount,
          ShiftType.ABSOLUTE);
    } else if (quote instanceof PointsUpFront) {
      PointsUpFront puf = (PointsUpFront) quote;
      return parallelCS01FromPUF(
          cds, puf.getCoupon(), yieldCurve, puf.getPointsUpFront(), fracBumpAmount);
    } else if (quote instanceof CdsParSpread) {
      return parallelCS01FromParSpreads(
          cds,
          quote.getCoupon(),
          yieldCurve,
          new CdsAnalytic[] {cds},
          new double[] {quote.getCoupon()},
          fracBumpAmount,
          ShiftType.ABSOLUTE);
    }
    throw new IllegalArgumentException("unknow type " + quote.getClass());
  }
 /**
  * Bump a market quote by a specified amount, eps. If the quote is a spread type (ParSpread or
  * QuotedSpread) the amount is simply bumped by given amount; however if the quote is
  * PointsUpFront this is first converted to a QuotedSpread, bumped by eps, then converted back to
  * PointsUpFront
  *
  * @param cds analytic description of a CDS traded at a certain time
  * @param quote The market quote
  * @param yieldCurve The yield curve
  * @param eps Bump amount (as a fraction, so a 1bps bumps is 1e-4)
  * @return The bumped quote
  */
 public CdsQuoteConvention bumpQuote(
     CdsAnalytic cds, CdsQuoteConvention quote, IsdaCompliantYieldCurve yieldCurve, double eps) {
   if (quote instanceof CdsParSpread) {
     return new CdsParSpread(quote.getCoupon() + eps);
   } else if (quote instanceof CdsQuotedSpread) {
     CdsQuotedSpread qSpread = (CdsQuotedSpread) quote;
     return new CdsQuotedSpread(qSpread.getCoupon(), qSpread.getQuotedSpread() + eps);
   } else if (quote instanceof PointsUpFront) {
     PointsUpFront puf = (PointsUpFront) quote;
     double bumpedQSpread =
         _pufConverter.pufToQuotedSpread(cds, puf.getCoupon(), yieldCurve, puf.getPointsUpFront())
             + eps;
     return new PointsUpFront(
         puf.getCoupon(),
         _pufConverter.quotedSpreadToPUF(cds, puf.getCoupon(), yieldCurve, bumpedQSpread));
   } else {
     throw new IllegalArgumentException("unknow type " + quote.getClass());
   }
 }