private ReadOnlyArray<BoundExpression> SpillArgumentListInner(
            ReadOnlyArray<BoundExpression> arguments,
            ReadOnlyArray<RefKind> refKindsOpt,
            ArrayBuilder<SpillBuilder> spillBuilders,
            ref bool spilledFirstArg)
        {
            var newArgsBuilder = ArrayBuilder<BoundExpression>.GetInstance();

            var refKindIterator = refKindsOpt != null ? refKindsOpt.AsReverseEnumerable().GetEnumerator() : null;

            foreach (var arg in arguments.AsReverseEnumerable())
            {
                RefKind refKind = (refKindIterator == null) ? RefKind.None :
                    (refKindIterator.MoveNext()) ? refKindIterator.Current :
                    RefKind.None;

                if (arg.Kind == BoundKind.ArrayInitialization)
                {
                    // Descend into a nested array initializer:
                    var nestedInitializer = ((BoundArrayInitialization)arg);
                    var newInitializers = SpillArgumentListInner(nestedInitializer.Initializers, ReadOnlyArray<RefKind>.Empty, spillBuilders, ref spilledFirstArg);
                    newArgsBuilder.Add(nestedInitializer.Update(newInitializers));
                    continue;
                }

                if (arg.Kind == BoundKind.ArgListOperator)
                {
                    // Descend into arglist:
                    var argList = (BoundArgListOperator)arg;
                    var newArgs = SpillArgumentListInner(argList.Arguments, argList.ArgumentRefKindsOpt, spillBuilders, ref spilledFirstArg);
                    newArgsBuilder.Add(argList.Update(newArgs, argList.ArgumentRefKindsOpt, argList.Type));
                    continue;
                }

                var spillBuilder = new SpillBuilder();

                BoundExpression newExpression;
                if (!spilledFirstArg)
                {
                    if (arg.Kind == BoundKind.SpillSequence)
                    {
                        // We have found the right-most expression containing an await expression. Save the await
                        // result to a temp local
                        spilledFirstArg = true;
                        var spill = (BoundSpillSequence)arg;
                        spillBuilder.AddSpill(spill);
                        newExpression = spill.Value;
                    }
                    else
                    {
                        // We are to the right of any await-containing expressions. The args do not yet need to be
                        // spilled.
                        newExpression = arg;    
                    }
                }
                else
                {
                    // We are to the left of an await-containing expression. Spill the arg.

                    if (Unspillable(arg) ||
                        (arg.Kind == BoundKind.FieldAccess && Unspillable(((BoundFieldAccess)arg).ReceiverOpt)))
                    {
                        newExpression = arg;
                    }
                    else if (refKind != RefKind.None)
                    {
                        newExpression = SpillLValue(arg, spillBuilder);
                    }
                    else
                    {
                        var spillTemp = F.SpillTemp(arg.Type, arg);
                        spillBuilder.Temps.Add(spillTemp);
                        spillBuilder.Statements.Add(GenerateSpillInit(spillTemp));
                        newExpression = spillTemp;
                    }
                }

                newArgsBuilder.Add(newExpression);
                spillBuilders.Add(spillBuilder);
            }

            newArgsBuilder.Reverse();
            return newArgsBuilder.ToReadOnlyAndFree();
        }
        private ReadOnlyArray <BoundExpression> SpillArgumentListInner(
            ReadOnlyArray <BoundExpression> arguments,
            ReadOnlyArray <RefKind> refKindsOpt,
            ArrayBuilder <SpillBuilder> spillBuilders,
            ref bool spilledFirstArg)
        {
            var newArgsBuilder = ArrayBuilder <BoundExpression> .GetInstance();

            var refKindIterator = refKindsOpt != null?refKindsOpt.AsReverseEnumerable().GetEnumerator() : null;

            foreach (var arg in arguments.AsReverseEnumerable())
            {
                RefKind refKind = (refKindIterator == null) ? RefKind.None :
                                  (refKindIterator.MoveNext()) ? refKindIterator.Current :
                                  RefKind.None;

                if (arg.Kind == BoundKind.ArrayInitialization)
                {
                    // Descend into a nested array initializer:
                    var nestedInitializer = ((BoundArrayInitialization)arg);
                    var newInitializers   = SpillArgumentListInner(nestedInitializer.Initializers, ReadOnlyArray <RefKind> .Empty, spillBuilders, ref spilledFirstArg);
                    newArgsBuilder.Add(nestedInitializer.Update(newInitializers));
                    continue;
                }

                if (arg.Kind == BoundKind.ArgListOperator)
                {
                    // Descend into arglist:
                    var argList = (BoundArgListOperator)arg;
                    var newArgs = SpillArgumentListInner(argList.Arguments, argList.ArgumentRefKindsOpt, spillBuilders, ref spilledFirstArg);
                    newArgsBuilder.Add(argList.Update(newArgs, argList.ArgumentRefKindsOpt, argList.Type));
                    continue;
                }

                var spillBuilder = new SpillBuilder();

                BoundExpression newExpression;
                if (!spilledFirstArg)
                {
                    if (arg.Kind == BoundKind.SpillSequence)
                    {
                        // We have found the right-most expression containing an await expression. Save the await
                        // result to a temp local
                        spilledFirstArg = true;
                        var spill = (BoundSpillSequence)arg;
                        spillBuilder.AddSpill(spill);
                        newExpression = spill.Value;
                    }
                    else
                    {
                        // We are to the right of any await-containing expressions. The args do not yet need to be
                        // spilled.
                        newExpression = arg;
                    }
                }
                else
                {
                    // We are to the left of an await-containing expression. Spill the arg.

                    if (Unspillable(arg) ||
                        (arg.Kind == BoundKind.FieldAccess && Unspillable(((BoundFieldAccess)arg).ReceiverOpt)))
                    {
                        newExpression = arg;
                    }
                    else if (refKind != RefKind.None)
                    {
                        newExpression = SpillLValue(arg, spillBuilder);
                    }
                    else
                    {
                        var spillTemp = F.SpillTemp(arg.Type, arg);
                        spillBuilder.Temps.Add(spillTemp);
                        spillBuilder.Statements.Add(GenerateSpillInit(spillTemp));
                        newExpression = spillTemp;
                    }
                }

                newArgsBuilder.Add(newExpression);
                spillBuilders.Add(spillBuilder);
            }

            newArgsBuilder.Reverse();
            return(newArgsBuilder.ToReadOnlyAndFree());
        }