/**
   * Compute Basket's Custom Scenario Measures
   *
   * @param valParams Valuation Parameters
   * @param pricerParams Pricer Parameters
   * @param mpc Market Parameters Container
   * @param strCustomScenName Custom Scenario Name
   * @param quotingParams Quoting Parameters
   * @param mapBase Map of Base Measures
   * @return Basket's Custom Scenario Measures
   */
  public org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double>
      calcCustomScenarioMeasures(
          final org.drip.param.valuation.ValuationParams valParams,
          final org.drip.param.pricer.PricerParams pricerParams,
          final org.drip.param.definition.MarketParams mpc,
          final java.lang.String strCustomScenName,
          final org.drip.param.valuation.QuotingParams quotingParams,
          org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> mapBase) {
    if (null == valParams || null == mpc) return null;

    if (null == mapBase && null == mpc.getScenBMP(this, "Base")) return null;

    if (null == mapBase) {
      org.drip.param.definition.BasketMarketParams bmp = mpc.getScenBMP(this, "Base");

      if (null == bmp || null == (mapBase = value(valParams, pricerParams, bmp, quotingParams)))
        return null;
    }

    org.drip.param.definition.BasketMarketParams bmpScen = mpc.getScenBMP(this, strCustomScenName);

    if (null == bmpScen) return null;

    org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> mapScenMeasures =
        value(valParams, pricerParams, bmpScen, quotingParams);

    if (null == mapScenMeasures || null != mapScenMeasures.entrySet()) return null;

    org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> mapOP =
        new org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double>();

    for (java.util.Map.Entry<java.lang.String, java.lang.Double> me : mapScenMeasures.entrySet()) {
      if (null == me || null == me.getKey()) continue;

      mapOP.put(me.getKey(), me.getValue() - mapBase.get(me.getKey()));
    }

    return mapOP;
  }
  /**
   * Generate a full list of the basket product measures for the set of scenario market parameters
   * present in the org.drip.param.definition.MarketParams
   *
   * @param valParams ValuationParams
   * @param pricerParams PricerParams
   * @param mpc org.drip.param.definition.MarketParams
   * @param quotingParams Quoting Parameters
   * @return BasketOutput object
   */
  public org.drip.analytics.output.BasketMeasures calcMeasures(
      final org.drip.param.valuation.ValuationParams valParams,
      final org.drip.param.pricer.PricerParams pricerParams,
      final org.drip.param.definition.MarketParams mpc,
      final org.drip.param.valuation.QuotingParams quotingParams) {
    if (null == valParams || null == mpc) return null;

    long lStart = System.nanoTime();

    org.drip.analytics.output.BasketMeasures bkop = new org.drip.analytics.output.BasketMeasures();

    if (null
        == (bkop._mBase =
            value(valParams, pricerParams, mpc.getScenBMP(this, "Base"), quotingParams)))
      return null;

    FlatDeltaGammaMeasureMap dgmmCredit =
        accumulateDeltaGammaMeasures(
            valParams,
            pricerParams,
            mpc.getScenBMP(this, "FlatCreditBumpUp"),
            mpc.getScenBMP(this, "FlatCreditBumpDn"),
            quotingParams,
            bkop._mBase);

    if (null != dgmmCredit && null != (bkop._mFlatCreditDelta = dgmmCredit._mapDelta))
      bkop._mFlatCreditGamma = dgmmCredit._mapGamma;

    FlatDeltaGammaMeasureMap dgmmRates =
        accumulateDeltaGammaMeasures(
            valParams,
            pricerParams,
            mpc.getScenBMP(this, "FlatIRBumpUp"),
            mpc.getScenBMP(this, "FlatIRBumpDn"),
            quotingParams,
            bkop._mBase);

    if (null != dgmmRates && null != (bkop._mFlatIRDelta = dgmmRates._mapDelta))
      bkop._mFlatIRGamma = dgmmRates._mapGamma;

    FlatDeltaGammaMeasureMap dgmmRecovery =
        accumulateDeltaGammaMeasures(
            valParams,
            pricerParams,
            mpc.getScenBMP(this, "FlatRRBumpUp"),
            mpc.getScenBMP(this, "FlatRRBumpDn"),
            quotingParams,
            bkop._mBase);

    if (null != dgmmRecovery && null != (bkop._mFlatRRDelta = dgmmRates._mapDelta))
      bkop._mFlatRRGamma = dgmmRates._mapGamma;

    org.drip.analytics.support.CaseInsensitiveTreeMap<org.drip.param.definition.BasketMarketParams>
        mapBMPIRTenorUp = mpc.getIRBumpBMP(this, true);

    org.drip.analytics.support.CaseInsensitiveTreeMap<org.drip.param.definition.BasketMarketParams>
        mapBMPIRTenorDown = mpc.getIRBumpBMP(this, false);

    TenorDeltaGammaMeasureMap mapDGMMRatesTenor =
        accumulateTenorDeltaGammaMeasures(
            valParams,
            pricerParams,
            mapBMPIRTenorUp,
            mapBMPIRTenorDown,
            quotingParams,
            bkop._mBase,
            null);

    if (null != mapDGMMRatesTenor) {
      bkop._mmIRDelta = mapDGMMRatesTenor._mmDelta;
      bkop._mmIRGamma = mapDGMMRatesTenor._mmGamma;
    }

    org.drip.analytics.support.CaseInsensitiveTreeMap<org.drip.param.definition.BasketMarketParams>
        mapBMPCreditTenorUp = mpc.getCreditBumpBMP(this, true);

    org.drip.analytics.support.CaseInsensitiveTreeMap<org.drip.param.definition.BasketMarketParams>
        mapBMPCreditTenorDown = mpc.getCreditBumpBMP(this, false);

    TenorDeltaGammaMeasureMap mapDGMMCreditComp =
        accumulateTenorDeltaGammaMeasures(
            valParams,
            pricerParams,
            mapBMPCreditTenorUp,
            mapBMPCreditTenorDown,
            quotingParams,
            bkop._mBase,
            null);

    if (null != mapDGMMCreditComp) {
      bkop._mmCreditDelta = mapDGMMCreditComp._mmDelta;
      bkop._mmCreditGamma = mapDGMMCreditComp._mmGamma;
    }

    TenorDeltaGammaMeasureMap mapDGMMRecoveryTenor =
        accumulateTenorDeltaGammaMeasures(
            valParams,
            pricerParams,
            mpc.getRecoveryBumpBMP(this, true),
            mpc.getRecoveryBumpBMP(this, false),
            quotingParams,
            bkop._mBase,
            null);

    if (null != mapDGMMRecoveryTenor) {
      bkop._mmRRDelta = mapDGMMRecoveryTenor._mmDelta;
      bkop._mmRRGamma = mapDGMMRecoveryTenor._mmGamma;
    }

    ComponentFactorTenorDeltaGammaMeasureMap mapCompRatesTenorDGMM =
        accumulateComponentWiseTenorDeltaGammaMeasures(
            valParams,
            pricerParams,
            mapBMPCreditTenorUp,
            mapBMPIRTenorUp,
            mapBMPIRTenorDown,
            quotingParams,
            bkop._mBase);

    if (null != mapCompRatesTenorDGMM) {
      bkop._mmmIRTenorDelta = mapCompRatesTenorDGMM._mmmDelta;
      bkop._mmmIRTenorGamma = mapCompRatesTenorDGMM._mmmGamma;
    }

    ComponentFactorTenorDeltaGammaMeasureMap mapCompCreditTenorDGMM =
        accumulateComponentWiseTenorDeltaGammaMeasures(
            valParams,
            pricerParams,
            mapBMPCreditTenorUp,
            mapBMPCreditTenorUp,
            mapBMPCreditTenorDown,
            quotingParams,
            bkop._mBase);

    if (null != mapCompCreditTenorDGMM) {
      bkop._mmmCreditTenorDelta = mapCompCreditTenorDGMM._mmmDelta;
      bkop._mmmCreditTenorGamma = mapCompCreditTenorDGMM._mmmGamma;
    }

    bkop._dblCalcTime = (System.nanoTime() - lStart) * 1.e-09;

    return bkop;
  }