public double protectionLeg(IsdaCompliantCreditCurve creditCurve) {

      double ht0 = creditCurve.getRT(_proLegIntPoints[0]);
      double rt0 = _proYieldCurveRT[0];
      double b0 = _proDF[0] * Math.exp(-ht0);

      double pv = 0.0;

      for (int i = 1; i < _nProPoints; ++i) {
        double ht1 = creditCurve.getRT(_proLegIntPoints[i]);
        double rt1 = _proYieldCurveRT[i];
        double b1 = _proDF[i] * Math.exp(-ht1);
        double dht = ht1 - ht0;
        double drt = rt1 - rt0;
        double dhrt = dht + drt;

        // this is equivalent to the ISDA code without explicitly calculating the time step - it
        // also handles the limit
        double dPV;
        if (Math.abs(dhrt) < 1e-5) {
          dPV = dht * b0 * epsilon(-dhrt);
        } else {
          dPV = (b0 - b1) * dht / dhrt;
        }
        pv += dPV;
        ht0 = ht1;
        rt0 = rt1;
        b0 = b1;
      }
      pv *= _lgdDF; // multiply by LGD and adjust to valuation date

      return pv;
    }
    private double calculateSinglePeriodAccrualOnDefault(
        int paymentIndex, IsdaCompliantCreditCurve creditCurve) {

      double[] knots = _premLegIntPoints[paymentIndex];
      if (knots == null) {
        return 0.0;
      }
      double[] df = _premDF[paymentIndex];
      double[] deltaT = _premDt[paymentIndex];
      double[] rt = _rt[paymentIndex];
      double accRate = _accRate[paymentIndex];
      double accStart = _offsetAccStart[paymentIndex];

      double t = knots[0];
      double ht0 = creditCurve.getRT(t);
      double rt0 = rt[0];
      double b0 = df[0] * Math.exp(-ht0);

      double t0 = t - accStart + _omega;
      double pv = 0.0;
      int nItems = knots.length;
      for (int j = 1; j < nItems; ++j) {
        t = knots[j];
        double ht1 = creditCurve.getRT(t);
        double rt1 = rt[j];
        double b1 = df[j] * Math.exp(-ht1);
        double dt = deltaT[j - 1];

        double dht = ht1 - ht0;
        double drt = rt1 - rt0;
        double dhrt = dht + drt + 1e-50; // to keep consistent with ISDA c code

        double tPV;
        if (getAccOnDefaultFormula() == AccrualOnDefaultFormulae.MARKIT_FIX) {
          if (Math.abs(dhrt) < 1e-5) {
            tPV = dht * dt * b0 * epsilonP(-dhrt);
          } else {
            tPV = dht * dt / dhrt * ((b0 - b1) / dhrt - b1);
          }
        } else {
          double t1 = t - accStart + _omega;
          if (Math.abs(dhrt) < 1e-5) {
            tPV = dht * b0 * (t0 * epsilon(-dhrt) + dt * epsilonP(-dhrt));
          } else {
            tPV = dht / dhrt * (t0 * b0 - t1 * b1 + dt / dhrt * (b0 - b1));
          }
          t0 = t1;
        }
        pv += tPV;
        ht0 = ht1;
        rt0 = rt1;
        b0 = b1;
      }
      return accRate * pv;
    }