void EndMulti(ILGenerator il)
        {
            Debug.Assert(il != null);
            Debug.Assert(ArgsCount > 2);

            il_EmitSaveElem(il);

            for (int i = 0, j = ArgsCount - 1; i < ArgsCount; i++, j--)
            {
                var index = Locals.Pop();
                var array = Locals.Pop();
                var var   = ArgsLocs[j];

                // x += xstep;
                il.Emit(OpCodes.Ldloc, var);
                il.Emit(OpCodes.Ldloc, StepLocs.Pop());
                Generic.Operation(il, 1);
                il.Emit(OpCodes.Stloc, var);

                EmitLoopEnd(il, index, array);
            }
        }
        void BeginMulti(ILGenerator il)
        {
            Debug.Assert(il != null);
            Debug.Assert(ArgsCount > 2);

            for (int i = 0; i < ArgsCount; i++)
            {
                LocalBuilder step =
                    il.DeclareLocal(TypeHelper <T> .ValueType);

                il_EmitLoadArg(il, 1);
                il_EmitLoadI4(il, i);
                il_EmitLoadElem(il);
                il.Emit(OpCodes.Stloc, step);

                StepLocs.Push(step);
            }

            LocalBuilder lastIndex = null;
            LocalBuilder lastArray = null;

            for (int i = 0, t = ArgsCount; i < ArgsCount; i++, t--)
            {
                Type arrayType = TypeHelper <T> .GetArrayType(t);

                var array = il.DeclareLocal(arrayType);
                var index = il.DeclareLocal(IndexType);
                var var   = il.DeclareLocal(TypeHelper <T> .ValueType);

                if (i == 0)
                {
                    // a = (T[][][]) ar;
                    il_EmitLoadArg(il, 0);
                    il.Emit(OpCodes.Castclass, arrayType);
                    il.Emit(OpCodes.Stloc, array);
                }
                else
                {
                    Debug.Assert(lastArray != null);
                    Debug.Assert(lastIndex != null);

                    // T[] b = a[i];
                    il.Emit(OpCodes.Ldloc, lastArray);
                    il.Emit(OpCodes.Ldloc, lastIndex);
                    il.Emit(OpCodes.Ldelem_Ref);
                    il.Emit(OpCodes.Stloc, array);
                }

                // T x = begins[0];
                il_EmitLoadArg(il, 1);
                il_EmitLoadI4(il, i + ArgsCount);
                il_EmitLoadElem(il);
                il.Emit(OpCodes.Stloc, var);

                // i++;
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Stloc, index);

                EmitLoopBegin(il);

                ArgsLocs.Add(var);
                Locals.Push(array);
                Locals.Push(index);

                lastArray = array;
                lastIndex = index;
            }

            Debug.Assert(lastIndex != null);
            Debug.Assert(lastArray != null);

            // c[z] =
            il.Emit(OpCodes.Ldloc, lastArray);
            il.Emit(OpCodes.Ldloc, lastIndex);
            il_EmitLoadAdress(il);
        }