@Override
  public boolean setNodeValue(final int iNodeIndex, final double dblNodeDF) {
    if (!org.drip.quant.common.NumberUtil.IsValid(dblNodeDF)) return false;

    int iNumDate = _adblDate.length;

    if (iNodeIndex > iNumDate) return false;

    if (0 == iNodeIndex) {
      _dblLeftFlatForwardRate =
          -365.25 * java.lang.Math.log(_dblLeftNodeDF = dblNodeDF) / (_adblDate[0] - _dblEpochDate);

      return true;
    }

    if (1 == iNodeIndex)
      return _msr.setLeftNode(_dblLeftNodeDF, _dblLeftNodeDFSlope, dblNodeDF, null);

    if (iNumDate - 1 == iNodeIndex) {
      try {
        _dblRightFlatForwardRate =
            -365.25
                * java.lang.Math.log(_msr.responseValue(_adblDate[iNodeIndex]))
                / (_adblDate[iNodeIndex] - _dblEpochDate);
      } catch (java.lang.Exception e) {
        e.printStackTrace();

        return false;
      }
    }

    return _msr.resetNode(iNodeIndex, dblNodeDF);
  }
  /**
   * Create a Regression Spline Instance over the specified array of Predictor Ordinate Knot Points
   * and the Set of the Points to be Best Fit.
   *
   * @param strName Name of the Stretch
   * @param adblKnotPredictorOrdinate Array of the Predictor Ordinate Knots
   * @param aSCBC Array of Segment Builder Parameters
   * @param sbfr Stretch Fitness Weighted Response
   * @param bs The Calibration Boundary Condition
   * @param iCalibrationDetail The Calibration Detail
   * @return Stretch instance
   */
  public static final org.drip.spline.stretch.MultiSegmentSequence CreateRegressionSplineEstimator(
      final java.lang.String strName,
      final double[] adblKnotPredictorOrdinate,
      final org.drip.spline.params.SegmentCustomBuilderControl[] aSCBC,
      final org.drip.spline.params.StretchBestFitResponse sbfr,
      final org.drip.spline.stretch.BoundarySettings bs,
      final int iCalibrationDetail) {
    org.drip.spline.stretch.MultiSegmentSequence mss =
        CreateUncalibratedStretchEstimator(strName, adblKnotPredictorOrdinate, aSCBC);

    if (null == mss) return null;

    return mss.setup(null, null, sbfr, bs, iCalibrationDetail) ? mss : null;
  }
  /**
   * Create a calibrated Stretch Instance over the specified Predictor Ordinates and the Response
   * Value Constraints, with the Segment Builder Parameters.
   *
   * @param strName Name of the Stretch
   * @param adblPredictorOrdinate Predictor Ordinate Array
   * @param srvcStretchLeft Stretch Left Constraint
   * @param aSRVC Array of Segment Constraints - One per Segment
   * @param aSCBC Array of Segment Builder Parameters - One per Segment
   * @param sbfr Stretch Fitness Weighted Response
   * @param bs The Calibration Boundary Condition
   * @param iCalibrationDetail The Calibration Detail
   * @return Stretch Instance
   */
  public static final org.drip.spline.stretch.MultiSegmentSequence CreateCalibratedStretchEstimator(
      final java.lang.String strName,
      final double[] adblPredictorOrdinate,
      final org.drip.spline.params.SegmentResponseValueConstraint srvcStretchLeft,
      final org.drip.spline.params.SegmentResponseValueConstraint[] aSRVC,
      final org.drip.spline.params.SegmentCustomBuilderControl[] aSCBC,
      final org.drip.spline.params.StretchBestFitResponse sbfr,
      final org.drip.spline.stretch.BoundarySettings bs,
      final int iCalibrationDetail) {
    org.drip.spline.stretch.MultiSegmentSequence mss =
        CreateUncalibratedStretchEstimator(strName, adblPredictorOrdinate, aSCBC);

    return null == mss
        ? null
        : mss.setup(srvcStretchLeft, aSRVC, sbfr, bs, iCalibrationDetail) ? mss : null;
  }
  @Override
  public org.drip.quant.calculus.WengertJacobian jackDDFDManifestMeasure(
      final double dblDate, final java.lang.String strManifestMeasure) {
    if (!org.drip.quant.common.NumberUtil.IsValid(dblDate)) return null;

    org.drip.quant.calculus.WengertJacobian wj = null;

    try {
      wj = new org.drip.quant.calculus.WengertJacobian(1, _adblDate.length);
    } catch (java.lang.Exception e) {
      e.printStackTrace();

      return null;
    }

    for (int i = 0; i < _adblDate.length; ++i) {
      if (!wj.accumulatePartialFirstDerivative(0, i, 0.)) return null;
    }

    if (dblDate <= _dblEpochDate) return wj;

    if (dblDate <= _adblDate[0]) {
      try {
        return wj.accumulatePartialFirstDerivative(
                0,
                0,
                (dblDate - _dblEpochDate)
                    / (_adblDate[0] - _dblEpochDate)
                    * java.lang.Math.exp(
                        _dblLeftFlatForwardRate * (_adblDate[0] - dblDate) / 365.25))
            ? wj
            : null;
      } catch (java.lang.Exception e) {
        e.printStackTrace();

        return null;
      }
    }

    if (dblDate <= _adblDate[_adblDate.length - 1])
      return _msr.jackDResponseDCalibrationInput(dblDate, 1);

    try {
      return wj.accumulatePartialFirstDerivative(
              0,
              _adblDate.length - 1,
              (dblDate - _dblEpochDate)
                  / (_adblDate[_adblDate.length - 1] - _dblEpochDate)
                  * java.lang.Math.exp(
                      _dblRightFlatForwardRate
                          * (_adblDate[_adblDate.length - 1] - dblDate)
                          / 365.25))
          ? wj
          : null;
    } catch (java.lang.Exception e) {
      e.printStackTrace();
    }

    return null;
  }
  /**
   * Create a calibrated Stretch Instance over the specified array of Predictor Ordinates and
   * Response Values using the specified Basis Splines.
   *
   * @param strName Name of the Stretch
   * @param adblPredictorOrdinate Predictor Ordinate Array
   * @param adblResponseValue Response Value Array
   * @param aSCBC Array of Segment Builder Parameters
   * @param rbfr Stretch Fitness Weighted Response
   * @param bs The Calibration Boundary Condition
   * @param iCalibrationDetail The Calibration Detail
   * @return Stretch instance
   */
  public static final org.drip.spline.stretch.MultiSegmentSequence CreateCalibratedStretchEstimator(
      final java.lang.String strName,
      final double[] adblPredictorOrdinate,
      final double[] adblResponseValue,
      final org.drip.spline.params.SegmentCustomBuilderControl[] aSCBC,
      final org.drip.spline.params.StretchBestFitResponse rbfr,
      final org.drip.spline.stretch.BoundarySettings bs,
      final int iCalibrationDetail) {
    org.drip.spline.stretch.MultiSegmentSequence mss =
        CreateUncalibratedStretchEstimator(strName, adblPredictorOrdinate, aSCBC);

    if (null == mss || null == adblResponseValue) return null;

    int iNumRightNode = adblResponseValue.length - 1;
    double[] adblResponseValueRight = new double[iNumRightNode];

    if (0 == iNumRightNode) return null;

    for (int i = 0; i < iNumRightNode; ++i) adblResponseValueRight[i] = adblResponseValue[i + 1];

    return mss.setup(adblResponseValue[0], adblResponseValueRight, rbfr, bs, iCalibrationDetail)
        ? mss
        : null;
  }
  @Override
  public double df(final double dblDate) throws java.lang.Exception {
    if (!org.drip.quant.common.NumberUtil.IsValid(dblDate))
      throw new java.lang.Exception("NonlinearDiscountFactorDiscountCurve::df => Invalid Inputs");

    if (dblDate <= _dblEpochDate) return 1.;

    if (dblDate <= _adblDate[0])
      return java.lang.Math.exp(-1. * _dblLeftFlatForwardRate * (dblDate - _dblEpochDate) / 365.25);

    return (dblDate <= _adblDate[_adblDate.length - 1]
            ? _msr.responseValue(dblDate)
            : java.lang.Math.exp(
                -1. * _dblRightFlatForwardRate * (dblDate - _dblEpochDate) / 365.25))
        * turnAdjust(epoch().julian(), dblDate);
  }
 /**
  * Calculate the calibration metric for the node
  *
  * @return Calibration Metric
  * @throws java.lang.Exception
  */
 public double getCalibrationMetric() throws java.lang.Exception {
   return _msr.calcRightEdgeDerivative(2);
 }