/// <summary>
        /// Maps all opening and closing parentheses and packs them with their interpreted children into <see cref="FormulaTokenParameter"/>.
        /// </summary>
        private IEnumerable <IFormulaToken> InterpretBrackets(IEnumerable <IFormulaToken> tokens)
        {
            var parenthesesTokens = new Stack <List <IFormulaToken> >();
            var parentheses       = new Stack <IFormulaToken>();

            foreach (var context in tokens.WithContext())
            {
                if (IsCancellationRequested)
                {
                    yield break;
                }
                var previousToken = context[0];
                var token         = context[1];

                var parenthesisToken = token as FormulaTokenParenthesis;
                if (parenthesisToken != null)
                {
                    // handle opening parenthesis
                    if (parenthesisToken.IsOpening)
                    {
                        parenthesesTokens.Push(new List <IFormulaToken>());
                        parenthesesTokens.Peek().Add(token);
                        if (previousToken is FormulaNodeUnaryFunction)
                        {
                            parentheses.Push(FormulaTokenFactory.CreateUnaryParameterToken(null));
                        }
                        else if (previousToken is FormulaNodeBinaryFunction)
                        {
                            parentheses.Push(FormulaTokenFactory.CreateBinaryParameterToken(null, null));
                        }
                        else
                        {
                            parentheses.Push(FormulaTreeFactory.CreateParenthesesNode(null));
                        }
                    }

                    // handle closing parenthesis
                    else
                    {
                        if (parenthesesTokens.Count == 0)
                        {
                            if (previousToken is IFormulaFunction)
                            {
                                SetParsingError(Range.Empty(GetOrigin(parenthesisToken).Start), AppResourcesHelper.Get("FormulaInterpreter_Function_Empty"));
                            }
                            else
                            {
                                SetParsingError(parenthesisToken, AppResourcesHelper.Get("FormulaInterpreter_Brackets_UnmatchedClosingParenthesis"));
                            }
                            yield break;
                        }
                        parenthesesTokens.Peek().Add(token);

                        // interpret parentheses
                        var commonToken = parentheses.Pop();
                        InterpretChildren(commonToken, parenthesesTokens.Pop());
                        if (IsCancellationRequested)
                        {
                            yield break;
                        }
                        if (parenthesesTokens.Count != 0)
                        {
                            parenthesesTokens.Peek().Add(commonToken);
                        }
                        else
                        {
                            yield return(commonToken);
                        }
                    }
                    continue;
                }

                // last token
                if (token == null)
                {
                    if (parenthesesTokens.Count != 0)
                    {
                        SetParsingError(
                            source: Range.Empty(GetOrigin(parenthesesTokens.Peek().Last()).End),
                            message: AppResourcesHelper.Get("FormulaInterpreter_Brackets_UnmatchedOpeningParenthesis"));
                        yield break;
                    }
                    continue;
                }

                // stash tokens inside parentheses
                if (parenthesesTokens.Count != 0)
                {
                    parenthesesTokens.Peek().Add(token);
                    continue;
                }

                // yield any token outside parentheses
                yield return(token);
            }
        }