/// <summary>
        /// Spill a list of expressions (e.g. the arguments of a method call).
        ///
        /// The expressions are processed right-to-left. Once an expression has been found that contains an await
        /// expression, all subsequent expressions are spilled.
        ///
        /// Example:
        ///
        ///     (1 + 2, await t1, Foo(), await t2, 3 + 4)
        ///
        ///     becomes:
        ///
        ///     Spill(
        ///         spill1 = 1 + 2,
        ///         spill2 = await t1,
        ///         spill3 = Foo(),
        ///         (spill1, spill2, spill3, await t2, 3 + 4))
        ///
        /// NOTE: Consider nested array initializers:
        ///
        ///     new int[] {
        ///         { 1, await t1 },
        ///         { 3, await t2 }
        ///     }
        ///
        /// If the arguments of the top-level initializer had already been spilled, we would end up trying to spill
        /// something like this:
        ///
        ///     new int[] {
        ///         Spill(
        ///             spill1 = 1,
        ///             { spill1, await t1 }),
        ///         Spill(
        ///             spill2 = 3,
        ///             { spill2, await t2 })
        ///     }
        ///
        /// The normal rewriting would produce:
        ///
        ///     Spill(
        ///         spill1 = 1,
        ///         spill3 = { spill1, await t1 },
        ///         spill2 = 3,
        ///         int[] a = new int[] {
        ///             spill3,
        ///             { spill2, await t2 }))
        ///
        /// Which is invalid, because spill3 does not have a type.
        ///
        /// To solve this problem the expression list spilled descends into nested array initializers.
        ///
        /// </summary>
        private ReadOnlyArray <BoundExpression> SpillExpressionList(
            SpillBuilder outerSpillBuilder,
            ReadOnlyArray <BoundExpression> expressions,
            ReadOnlyArray <RefKind> refKindsOpt = default(ReadOnlyArray <RefKind>))
        {
            var spillBuilders = ArrayBuilder <SpillBuilder> .GetInstance();

            bool spilledFirstArg = false;

            ReadOnlyArray <BoundExpression> newArgs = SpillArgumentListInner(expressions, refKindsOpt, spillBuilders, ref spilledFirstArg);

            var spillBuilder = new SpillBuilder();

            spillBuilders.Reverse();
            foreach (var spill in spillBuilders)
            {
                spillBuilder.AddSpill(spill);
                spill.Free();
            }
            spillBuilders.Free();

            outerSpillBuilder.AddSpill(spillBuilder);
            spillBuilder.Free();

            return(newArgs);
        }
        /// <summary>
        /// Spill a list of expressions (e.g. the arguments of a method call).
        /// 
        /// The expressions are processed right-to-left. Once an expression has been found that contains an await
        /// expression, all subsequent expressions are spilled.
        /// 
        /// Example:
        /// 
        ///     (1 + 2, await t1, Foo(), await t2, 3 + 4)
        /// 
        ///     becomes:
        /// 
        ///     Spill(
        ///         spill1 = 1 + 2,
        ///         spill2 = await t1,
        ///         spill3 = Foo(),
        ///         (spill1, spill2, spill3, await t2, 3 + 4))
        /// 
        /// NOTE: Consider nested array initializers:
        /// 
        ///     new int[] {
        ///         { 1, await t1 },
        ///         { 3, await t2 }
        ///     }
        /// 
        /// If the arguments of the top-level initializer had already been spilled, we would end up trying to spill
        /// something like this:
        /// 
        ///     new int[] {
        ///         Spill(
        ///             spill1 = 1,
        ///             { spill1, await t1 }),
        ///         Spill(
        ///             spill2 = 3,
        ///             { spill2, await t2 })
        ///     }
        /// 
        /// The normal rewriting would produce:
        /// 
        ///     Spill(
        ///         spill1 = 1,
        ///         spill3 = { spill1, await t1 },
        ///         spill2 = 3,
        ///         int[] a = new int[] {
        ///             spill3,
        ///             { spill2, await t2 }))
        /// 
        /// Which is invalid, because spill3 does not have a type.
        /// 
        /// To solve this problem the expression list spilled descends into nested array initializers.
        /// 
        /// </summary>
        private ReadOnlyArray<BoundExpression> SpillExpressionList(
            SpillBuilder outerSpillBuilder,
            ReadOnlyArray<BoundExpression> expressions,
            ReadOnlyArray<RefKind> refKindsOpt = default(ReadOnlyArray<RefKind>))
        {
            var spillBuilders = ArrayBuilder<SpillBuilder>.GetInstance();
            bool spilledFirstArg = false;

            ReadOnlyArray<BoundExpression> newArgs = SpillArgumentListInner(expressions, refKindsOpt, spillBuilders, ref spilledFirstArg);

            var spillBuilder = new SpillBuilder();

            spillBuilders.Reverse();
            foreach (var spill in spillBuilders)
            {
                spillBuilder.AddSpill(spill);
                spill.Free();
            }
            spillBuilders.Free();

            outerSpillBuilder.AddSpill(spillBuilder);
            spillBuilder.Free();

            return newArgs;
        }