//-------------------------------------------------------------------------
        private double[] computesFittingParameters()
        {
            double[] param = new double[3];     // Implementation note: called a,b,c in the note.
            // Computes derivatives at cut-off.
            double[] vD = new double[6];
//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: double[][] vD2 = new double[2][2];
            double[][] vD2 = RectangularArrays.ReturnRectangularDoubleArray(2, 2);
            volatilityK = sabrFunction.volatilityAdjoint2(forward, cutOffStrike, timeToExpiry, sabrData, vD, vD2);
            Pair <ValueDerivatives, double[][]> pa2 = BlackFormulaRepository.priceAdjoint2(forward, cutOffStrike, timeToExpiry, volatilityK, true);

            double[]   bsD  = pa2.First.Derivatives.toArrayUnsafe();
            double[][] bsD2 = pa2.Second;
            priceK[0] = pa2.First.Value;
            priceK[1] = bsD[1] + bsD[3] * vD[1];
            priceK[2] = bsD2[1][1] + bsD2[1][2] * vD[1] + (bsD2[2][1] + bsD2[2][2] * vD[1]) * vD[1] + bsD[3] * vD2[1][1];
            if (Math.Abs(priceK[0]) < SMALL_PRICE && Math.Abs(priceK[1]) < SMALL_PRICE && Math.Abs(priceK[2]) < SMALL_PRICE)
            {
                // Implementation note: If value and its derivatives is too small, then parameters are such that the extrapolated price is "very small".
                return(new double[] { -100.0, 0, 0 });
            }
            System.Func <double, double> toSolveC = getCFunction(priceK, cutOffStrike, mu);
            BracketRoot            bracketer      = new BracketRoot();
            double                 accuracy       = 1.0E-5;
            RidderSingleRootFinder rootFinder     = new RidderSingleRootFinder(accuracy);

            double[] range = bracketer.getBracketedPoints(toSolveC, -1.0, 1.0);
            param[2] = rootFinder.getRoot(toSolveC, range[0], range[1]).Value;
            param[1] = -2 * param[2] / cutOffStrike - (priceK[1] / priceK[0] * cutOffStrike + mu) * cutOffStrike;
            param[0] = Math.Log(priceK[0] / Math.Pow(cutOffStrike, -mu)) - param[1] / cutOffStrike - param[2] / (cutOffStrike * cutOffStrike);
            return(param);
        }
        /// <summary>
        /// Calculates the common part of the exercise boundary of European swaptions forward.
        /// <para>
        /// This is intended to be used in particular for Bermudan swaption first step of the pricing.
        /// </para>
        /// <para>
        /// Reference: Henrard, "M. Bermudan Swaptions in Gaussian HJM One-Factor Model: Analytical and Numerical Approaches".
        /// SSRN, October 2008. Available at SSRN: http://ssrn.com/abstract=1287982
        ///
        /// </para>
        /// </summary>
        /// <param name="discountedCashFlow">  the swap discounted cash flows </param>
        /// <param name="alpha2">  square of the alpha parameter </param>
        /// <param name="hwH">  the H factors </param>
        /// <returns> the exercise boundary </returns>
        public double lambda(DoubleArray discountedCashFlow, DoubleArray alpha2, DoubleArray hwH)
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final java.util.function.Function<double, double> swapValue = new java.util.function.Function<double, double>()
            System.Func <double, double> swapValue = (double?x) =>
            {
                double value = 0.0;
                for (int loopcf = 0; loopcf < alpha2.size(); loopcf++)
                {
                    value += discountedCashFlow.get(loopcf) * Math.Exp(-0.5 * alpha2.get(loopcf) - hwH.get(loopcf) * x);
                }
                return(value);
            };
            BracketRoot            bracketer  = new BracketRoot();
            double                 accuracy   = 1.0E-8;
            RidderSingleRootFinder rootFinder = new RidderSingleRootFinder(accuracy);

            double[] range = bracketer.getBracketedPoints(swapValue, -2.0, 2.0);
            return(rootFinder.getRoot(swapValue, range[0], range[1]).Value);
        }