/// <summary>
        /// Test the rho = -1 edge case
        /// </summary>
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void testVolatilityAdjointRhoM1()
        public virtual void testVolatilityAdjointRhoM1()
        {
            double          eps  = 1e-5;
            double          tol  = 1e-6;
            SabrFormulaData data = DATA.withRho(-1.0);

            testVolatilityAdjoint(F, CALL_ATM, data, eps, tol);
            testVolatilityAdjoint(F, CALL_ITM, data, eps, tol);
            testVolatilityAdjoint(F, CALL_OTM, data, eps, tol);
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("null") private double fdSensitivity(com.opengamma.strata.pricer.impl.option.EuropeanVanillaOption optionData, double forward, SabrFormulaData sabrData, SabrParameter param, double delta)
        private double fdSensitivity(EuropeanVanillaOption optionData, double forward, SabrFormulaData sabrData, SabrParameter param, double delta)
        {
            System.Func <SabrFormulaData, double> funcC = null;
            System.Func <SabrFormulaData, double> funcB = null;
            System.Func <SabrFormulaData, double> funcA = null;
            SabrFormulaData dataC = null;
            SabrFormulaData dataB = sabrData;
            SabrFormulaData dataA = null;

            System.Func <SabrFormulaData, double> func = getVolatilityFunction(optionData, forward);

            FiniteDifferenceType fdType = null;

            switch (param)
            {
            case com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProviderTest.SabrParameter.Strike:
                double strike = optionData.Strike;
                if (strike >= delta)
                {
                    fdType = FiniteDifferenceType.CENTRAL;
                    funcA  = getVolatilityFunction(withStrike(optionData, strike - delta), forward);
                    funcC  = getVolatilityFunction(withStrike(optionData, strike + delta), forward);
                }
                else
                {
                    fdType = FiniteDifferenceType.FORWARD;
                    funcA  = func;
                    funcB  = getVolatilityFunction(withStrike(optionData, strike + delta), forward);
                    funcC  = getVolatilityFunction(withStrike(optionData, strike + 2 * delta), forward);
                }
                dataC = sabrData;
                dataB = sabrData;
                dataA = sabrData;
                break;

            case com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProviderTest.SabrParameter.Forward:
                if (forward > delta)
                {
                    fdType = FiniteDifferenceType.CENTRAL;
                    funcA  = getVolatilityFunction(optionData, forward - delta);
                    funcC  = getVolatilityFunction(optionData, forward + delta);
                }
                else
                {
                    fdType = FiniteDifferenceType.FORWARD;
                    funcA  = func;
                    funcB  = getVolatilityFunction(optionData, forward + delta);
                    funcC  = getVolatilityFunction(optionData, forward + 2 * delta);
                }
                dataC = sabrData;
                dataB = sabrData;
                dataA = sabrData;
                break;

            case com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProviderTest.SabrParameter.Alpha:
                double a = sabrData.Alpha;
                if (a >= delta)
                {
                    fdType = FiniteDifferenceType.CENTRAL;
                    dataA  = sabrData.withAlpha(a - delta);
                    dataC  = sabrData.withAlpha(a + delta);
                }
                else
                {
                    fdType = FiniteDifferenceType.FORWARD;
                    dataA  = sabrData;
                    dataB  = sabrData.withAlpha(a + delta);
                    dataC  = sabrData.withAlpha(a + 2 * delta);
                }
                funcC = func;
                funcB = func;
                funcA = func;
                break;

            case com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProviderTest.SabrParameter.Beta:
                double b = sabrData.Beta;
                if (b >= delta)
                {
                    fdType = FiniteDifferenceType.CENTRAL;
                    dataA  = sabrData.withBeta(b - delta);
                    dataC  = sabrData.withBeta(b + delta);
                }
                else
                {
                    fdType = FiniteDifferenceType.FORWARD;
                    dataA  = sabrData;
                    dataB  = sabrData.withBeta(b + delta);
                    dataC  = sabrData.withBeta(b + 2 * delta);
                }
                funcC = func;
                funcB = func;
                funcA = func;
                break;

            case com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProviderTest.SabrParameter.Nu:
                double n = sabrData.Nu;
                if (n >= delta)
                {
                    fdType = FiniteDifferenceType.CENTRAL;
                    dataA  = sabrData.withNu(n - delta);
                    dataC  = sabrData.withNu(n + delta);
                }
                else
                {
                    fdType = FiniteDifferenceType.FORWARD;
                    dataA  = sabrData;
                    dataB  = sabrData.withNu(n + delta);
                    dataC  = sabrData.withNu(n + 2 * delta);
                }
                funcC = func;
                funcB = func;
                funcA = func;
                break;

            case com.opengamma.strata.pricer.impl.volatility.smile.SabrHaganVolatilityFunctionProviderTest.SabrParameter.Rho:
                double r = sabrData.Rho;
                if ((r + 1) < delta)
                {
                    fdType = FiniteDifferenceType.FORWARD;
                    dataA  = sabrData;
                    dataB  = sabrData.withRho(r + delta);
                    dataC  = sabrData.withRho(r + 2 * delta);
                }
                else if ((1 - r) < delta)
                {
                    fdType = FiniteDifferenceType.BACKWARD;
                    dataA  = sabrData.withRho(r - 2 * delta);
                    dataB  = sabrData.withRho(r - delta);
                    dataC  = sabrData;
                }
                else
                {
                    fdType = FiniteDifferenceType.CENTRAL;
                    dataC  = sabrData.withRho(r + delta);
                    dataA  = sabrData.withRho(r - delta);
                }
                funcC = func;
                funcB = func;
                funcA = func;
                break;

            default:
                throw new MathException("enum not found");
            }

            if (fdType != null)
            {
                switch (fdType)
                {
                case FiniteDifferenceType.FORWARD:
                    return((-1.5 * funcA(dataA) + 2.0 * funcB(dataB) - 0.5 * funcC(dataC)) / delta);

                case FiniteDifferenceType.BACKWARD:
                    return((0.5 * funcA(dataA) - 2.0 * funcB(dataB) + 1.5 * funcC(dataC)) / delta);

                case FiniteDifferenceType.CENTRAL:
                    return((funcC(dataC) - funcA(dataA)) / 2.0 / delta);

                default:
                    throw new MathException("enum not found");
                }
            }
            throw new MathException("enum not found");
        }