/// <returns>true if any errors are found at this level or below</returns>
        /// Guard against a mistake in the tree that causes infinite recursion.
        private static bool GetErrors2(FunctionCalc fnCalc, ref IList <FunCalcError> lowestErrors, ref IList <FunCalcError> allErrors, string NumberFormat, IList <SingleResult> callStack)
        {
            bool         bRet         = false;
            FunCalcError funCalcError = null;

            // ----------------------
            if (fnCalc.GetCalcStatus() == CalcStatus.Bad)
            {
                funCalcError = new FunCalcError(fnCalc.CalcQuantity?.Message, fnCalc);
                allErrors.Add(funCalcError);
                bRet = true;
            }

            // ----------------------
            bool bFoundLower = false;

            foreach (SingleResult input in fnCalc.Inputs)
            {
                bool bFoundMore = false;
                if (input is FunctionCalc)
                {
                    if (callStack.IndexOf(input) >= 0)
                    {
                        throw new UnspecifiedException("Infinite recursion in Expression Tree");
                    }
                    callStack.Add(input);
                    bFoundMore = GetErrors2(((FunctionCalc)input), ref lowestErrors, ref allErrors, NumberFormat, callStack);
                    callStack.Remove(input);
                }
                else
                {
                    bFoundMore = GetErrors3(input, ref lowestErrors, ref allErrors, NumberFormat);
                }

                if (bFoundMore)
                {
                    bFoundLower = true;
                }
            }

            // ----------------------
            if (bFoundLower)
            {
                bRet = true;
            }
            else if (funCalcError != null)
            {
                lowestErrors.Add(funCalcError);
            }

            return(bRet);
        }
        /// Guard against a mistake in the tree that causes infinite recursion.
        private static void GetCalculationTreeText2(FunctionCalc fnCalc, ref string calculationTree, string sCurrentIndent, string sIndentStep, string NumberFormat, IList <SingleResult> callStack)
        {
            if (fnCalc.Function is FnEquals)
            {
                calculationTree += string.Format("{0}{1} ({2}) {3}\n",
                                                 sCurrentIndent, fnCalc.Function.Name, fnCalc.Function.AsciiSymbol,
                                                 (fnCalc.CalcQuantity.Message.Length == 0) ? "" : (" // " + fnCalc.CalcQuantity.Message));
            }
            else
            {
                calculationTree += string.Format("{0}{1} ({2}) = {3}{4}\n",
                                                 sCurrentIndent, fnCalc.Function.Name, fnCalc.Function.AsciiSymbol,
                                                 ((fnCalc.GetCalcStatus() == CalcStatus.Good) ?
                                                  string.Format("{0:" + NumberFormat + "}", fnCalc.CalcQuantity.Value) :
                                                  "!"),
                                                 (fnCalc.CalcQuantity.Message.Length == 0) ? "" : (" // " + fnCalc.CalcQuantity.Message));
            }

            // ----------------------
            foreach (SingleResult input in fnCalc.Inputs)
            {
                if (input is FunctionCalc)
                {
                    if (callStack.IndexOf(input) >= 0)
                    {
                        throw new UnspecifiedException("Infinite recursion in Expression Tree");
                    }
                    callStack.Add(input);
                    GetCalculationTreeText2(((FunctionCalc)input), ref calculationTree, (sCurrentIndent + sIndentStep), sIndentStep, NumberFormat, callStack);
                    callStack.Remove(input);
                }
                else
                {
                    FunctionCalc.GetCalculationTreeText3(input, ref calculationTree, (sCurrentIndent + sIndentStep), NumberFormat);
                }
            }
        }