//-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the recovery01 of the CDS index product.
        /// <para>
        /// The recovery01 is defined as the present value sensitivity to the recovery rate.
        /// Since the ISDA standard model requires the recovery rate to be constant throughout the lifetime of the CDS index,
        /// one currency amount is returned by this method.
        ///
        /// </para>
        /// </summary>
        /// <param name="cdsIndex">  the product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="referenceDate">  the reference date </param>
        /// <param name="refData">  the reference data </param>
        /// <returns> the recovery01 </returns>
        public virtual CurrencyAmount recovery01(ResolvedCdsIndex cdsIndex, CreditRatesProvider ratesProvider, LocalDate referenceDate, ReferenceData refData)
        {
            if (isExpired(cdsIndex, ratesProvider))
            {
                return(CurrencyAmount.of(cdsIndex.Currency, 0d));
            }
            ResolvedCds cds                = cdsIndex.toSingleNameCds();
            LocalDate   stepinDate         = cds.StepinDateOffset.adjust(ratesProvider.ValuationDate, refData);
            LocalDate   effectiveStartDate = cds.calculateEffectiveStartDate(stepinDate);

            underlyingPricer.validateRecoveryRates(cds, ratesProvider);
            Triple <CreditDiscountFactors, LegalEntitySurvivalProbabilities, double> rates = reduceDiscountFactors(cds, ratesProvider);
            double protectionFull = underlyingPricer.protectionFull(cds, rates.First, rates.Second, referenceDate, effectiveStartDate);
            double amount         = -cds.BuySell.normalize(cds.Notional) * protectionFull * rates.Third;

            return(CurrencyAmount.of(cds.Currency, amount));
        }