// Bubbles up a call. The returned pair consists of
            // 1. A sequence of statements to run before the call
            // 2. The call with all (outer) #runSequences removed
            Pair <VList <LNode>, LNode> BubbleUp_GeneralCall2(LNode expr)
            {
                var target           = expr.Target;
                var args             = expr.Args;
                var combinedSequence = LNode.List();

                // Bubbe up target
                target = BubbleUpBlocks(target);
                if (target.CallsMin(__numrunSequence, 1))
                {
                    combinedSequence = target.Args.WithoutLast(1);
                    expr             = expr.WithTarget(target.Args.Last);
                }

                // Bubble up each argument
                var isAssignment = EcsValidators.IsAssignmentOperator(expr.Name);

                if (isAssignment)
                {
                    LNode lhs = BubbleUpBlocks(expr.Args[0]);
                    LNode rhs = BubbleUpBlocks(expr.Args[1]);
                    args = LNode.List(lhs, rhs);
                }
                else                            // most common case
                {
                    args = args.SmartSelect(arg => BubbleUpBlocks(arg));
                }

                int lastRunSeq = args.LastIndexWhere(a => a.CallsMin(__numrunSequence, 1));

                if (lastRunSeq >= 0)
                {
                    // last index of #runSequence that is not marked pure
                    int lastRunSeqImpure = args.First(lastRunSeq + 1).LastIndexWhere(a =>
                                                                                     a.CallsMin(__numrunSequence, 1) && a.AttrNamed(_trivia_pure.Name) == null);

                    if (lastRunSeq > 0 &&
                        (args.Count == 2 && (target.IsIdNamed(S.And) || target.IsIdNamed(S.Or)) || args.Count == 3 && target.IsIdNamed(S.QuestionMark)))
                    {
                        Context.Sink.Error(target,
                                           "#useSequenceExpressions is not designed to support sequences or variable declarations on the right-hand side of the `&&`, `||` or `?` operators. The generated code will be incorrect.");
                    }

                    var argsW = args.ToList();
                    for (int i = 0; i <= lastRunSeq; i++)
                    {
                        LNode arg = argsW[i];
                        if (!arg.IsLiteral)
                        {
                            if (arg.CallsMin(__numrunSequence, 1))
                            {
                                combinedSequence.AddRange(arg.Args.WithoutLast(1));
                                argsW[i] = arg = arg.Args.Last;
                            }
                            if (i < lastRunSeqImpure)
                            {
                                if (i == 0 && (expr.CallsMin(S.IndexBracks, 1) || expr.CallsMin(S.NullIndexBracks, 1)))
                                {
                                    // Consider foo[#runSequence(f(), i)]. In case this appears in
                                    // an lvalue context and `foo` is a struct, we cannot store `foo` in
                                    // a temporary, as this may silently change the code's behavior.
                                    // Better to take the risk of evaluating `foo` after `f()`.
                                }
                                else
                                {
                                    if (isAssignment || arg.Attrs.Any(a => a.IsIdNamed(S.Ref) || a.IsIdNamed(S.Out)))
                                    {
                                        argsW[i] = MaybeCreateTemporaryForLValue(arg, ref combinedSequence);
                                    }
                                    else
                                    {
                                        // Create a temporary variable to hold this argument
                                        LNode tmpVarName, tmpVarDecl = TempVarDecl(Context, arg, out tmpVarName);
                                        combinedSequence.Add(tmpVarDecl);
                                        argsW[i] = tmpVarName.PlusAttr(_trivia_isTmpVar);
                                    }
                                }
                            }
                        }
                    }

                    expr = expr.WithArgs(LNode.List(argsW));
                }

                return(Pair.Create(combinedSequence, expr));
            }
            Pair <VList <LNode>, LNode> BubbleUp_GeneralCall2(LNode expr)
            {
                var target           = expr.Target;
                var args             = expr.Args;
                var combinedSequence = LNode.List();

                target = BubbleUpBlocks(target);
                if (target.CallsMin(__numrunSequence, 1))
                {
                    combinedSequence = target.Args.WithoutLast(1);
                    expr             = expr.WithTarget(target.Args.Last);
                }
                var isAssignment = EcsValidators.IsAssignmentOperator(expr.Name);

                if (isAssignment)
                {
                    LNode lhs = BubbleUpBlocks(expr.Args[0]);
                    LNode rhs = BubbleUpBlocks(expr.Args[1]);
                    args = LNode.List(lhs, rhs);
                }
                else
                {
                    args = args.SmartSelect(arg => BubbleUpBlocks(arg));
                }
                int lastRunSeq = args.LastIndexWhere(a => a.CallsMin(__numrunSequence, 1));

                if (lastRunSeq >= 0)
                {
                    int lastRunSeqImpure = args.First(lastRunSeq + 1).LastIndexWhere(a => a.CallsMin(__numrunSequence, 1) && a.AttrNamed(_trivia_pure.Name) == null);
                    if (lastRunSeq > 0 && (args.Count == 2 && (target.IsIdNamed(S.And) || target.IsIdNamed(S.Or)) || args.Count == 3 && target.IsIdNamed(S.QuestionMark)))
                    {
                        Context.Write(Severity.Error, target, "#useSequenceExpressions is not designed to support sequences or variable declarations on the right-hand side of the `&&`, `||` or `?` operators. The generated code will be incorrect.");
                    }
                    var argsW = args.ToList();
                    for (int i = 0; i <= lastRunSeq; i++)
                    {
                        LNode arg = argsW[i];
                        if (!arg.IsLiteral)
                        {
                            if (arg.CallsMin(__numrunSequence, 1))
                            {
                                combinedSequence.AddRange(arg.Args.WithoutLast(1));
                                argsW[i] = arg = arg.Args.Last;
                            }
                            if (i < lastRunSeqImpure)
                            {
                                if (i == 0 && (expr.CallsMin(S.IndexBracks, 1) || expr.CallsMin(S.NullIndexBracks, 1)))
                                {
                                }
                                else
                                {
                                    if (isAssignment || arg.Attrs.Any(a => a.IsIdNamed(S.Ref) || a.IsIdNamed(S.Out)))
                                    {
                                        argsW[i] = MaybeCreateTemporaryForLValue(arg, ref combinedSequence);
                                    }
                                    else
                                    {
                                        LNode tmpVarName, tmpVarDecl = TempVarDecl(Context, arg, out tmpVarName);
                                        combinedSequence.Add(tmpVarDecl);
                                        argsW[i] = tmpVarName.PlusAttr(_trivia_isTmpVar);
                                    }
                                }
                            }
                        }
                    }
                    expr = expr.WithArgs(LNode.List(argsW));
                }
                return(Pair.Create(combinedSequence, expr));
            }