public TenorLabelledMatrix1D getBucketedCS01(
     CDSAnalytic analytic,
     CDSAnalytic[] buckets,
     Tenor[] tenors,
     CDSQuoteConvention quote,
     double notional,
     ISDACompliantYieldCurve yieldCurve,
     ISDACompliantCreditCurve creditCurve) {
   // TODO: Check quote.getCoupon() is spread value for IMM & 0.01 (or 0.05) for non IMM
   double[] cs01Values;
   if (quote instanceof ParSpread) {
     cs01Values =
         CALCULATOR.bucketedCS01FromCreditCurve(
             analytic, quote.getCoupon(), buckets, yieldCurve, creditCurve, ONE_BPS);
   } else if (quote instanceof PointsUpFront) {
     cs01Values =
         CALCULATOR.bucketedCS01FromPUF(
             analytic, (PointsUpFront) quote, yieldCurve, buckets, ONE_BPS);
   } else {
     cs01Values =
         CALCULATOR.bucketedCS01FromCreditCurve(
             analytic,
             quote.getCoupon() /*coupon * ONE_BPS*/,
             buckets,
             yieldCurve,
             creditCurve,
             ONE_BPS);
   }
   for (int i = 0; i < cs01Values.length; i++) {
     cs01Values[i] *= notional * ONE_BPS;
   }
   return new TenorLabelledMatrix1D(tenors, cs01Values);
 }
 public double getParallelCS01(
     CDSQuoteConvention quote,
     CDSAnalytic analytic,
     ISDACompliantYieldCurve yieldCurve,
     double notional,
     CDSAnalytic[] pillars,
     double[] pillarSpreads) {
   double cs01;
   if (quote instanceof ParSpread) {
     cs01 =
         CALCULATOR.parallelCS01FromParSpreads(
             analytic,
             quote.getCoupon(), // ParSpread
             yieldCurve,
             pillars,
             pillarSpreads,
             ONE_BPS,
             BumpType.ADDITIVE);
   } else {
     cs01 = CALCULATOR.parallelCS01(analytic, quote, yieldCurve, ONE_BPS);
   }
   return Double.valueOf(cs01 * notional * ONE_BPS);
 }