private static bool SpecializeExpression(ILFunction f, ILExpression expr, AbstractEnvironment env, StringBuilder source, List<FunctionCallContainer> calls)
        {
            if (expr.Type == ILExpressionType.Assign) {

                var left = expr.LeftNode;
                var right = expr.RightNode;
                if (left.Type == ILExpressionType.VariableAccess) {
                    var varName = left.Const.ToString();
                    try {
                        var rightRed = right.AbstactReduce(varName, env, f.LocalTypes);
                        if (rightRed is ILExpression) {
                                var fcall = rightRed as ILExpression;

                                SpecializeFunctionCall(f, fcall, varName, source, env, calls);
                                //source.Append("<<FUNCTION_CALL>>");
                        }
                        else if (env.IsDynamic(varName)) {

                            //source.Append(varName); source.Append(" := ");

                            if (rightRed is string) {
                                source.Append("\t"); source.Append(varName); source.Append(" := ");
                                source.Append((string)rightRed);
                                source.Append(";"); source.Append(System.Environment.NewLine);
                            }
                            else {
                                source.Append("\t"); source.Append(varName); source.Append(" := ");
                                source.Append(RenderConst(rightRed));
                                source.Append(";"); source.Append(System.Environment.NewLine);
                            }
                        }
                        else {
                            object val = rightRed;

                            System.Diagnostics.Debug.Assert(val is string == false);
                            System.Diagnostics.Debug.Assert(val is ILExpression == false);

                            env.SetValue(varName, val);
                        }
                    }
                    catch (NullReferenceException) {
                        source.Append("\t__spec_raise_null_ref_exception();"); source.Append(System.Environment.NewLine);
                    }
                    catch (IndexOutOfRangeException) {
                        source.Append("\t__spec_raise_index_out_of_range_exception();"); source.Append(System.Environment.NewLine);
                    }
                }
                else {
                    System.Diagnostics.Debug.Assert(left.Type == ILExpressionType.ArrayAccess);

                    try {
                        var arrayName = left.LeftNode.Const.ToString();
                        object index = null;
                        if (env.IsDynamic(left.RightNode.Const.ToString())) {
                            index = left.RightNode.Const.ToString();
                        } else {
                            index = env.GetValue(left.RightNode.Const.ToString());
                        }

                        object rightVar = null;
                        if (env.IsDynamic(right.Const.ToString())) {
                            rightVar = right.Const.ToString();
                        } else {
                            rightVar = env.GetValue(right.Const.ToString());
                        }

                        if (env.IsDynamic(arrayName)) {
                            source.Append("\t"); source.Append(arrayName); source.Append("["); source.Append(index); source.Append("] := ");
                            source.Append(rightVar); source.Append(";"); source.Append(System.Environment.NewLine);
                        }
                        else {
                            object[] a = (object[])env.GetValue(arrayName);
                            a[Convert.ToInt32(index)] = rightVar;
                        }
                    }
                    catch (NullReferenceException) {
                        source.Append("\t__spec_raise_null_ref_exception();"); source.Append(System.Environment.NewLine);
                    }
                    catch (IndexOutOfRangeException) {
                        source.Append("\t__spec_raise_index_out_of_range_exception();"); source.Append(System.Environment.NewLine);
                    }
                }

            }
            else if (expr.Type == ILExpressionType.FunctionCall) {
                source.Append("\t"); source.Append(expr.Const.ToString()); source.Append("(");
                for (int i = 0; i < expr.VAList.Count; ++i) {
                    string p = null;
                    if (env.IsDynamic(expr.VAList[i].Const.ToString())) {
                        p = expr.VAList[i].Const.ToString();
                    } else {
                        p = RenderConst(env.GetValue(expr.VAList[i].Const.ToString()));
                    }
                    source.Append(p);
                    if (i != expr.VAList.Count - 1)
                        source.Append(", ");
                }
                source.Append(");"); source.Append(System.Environment.NewLine);
            }

            return false;
        }
        private static void SpecializeFunctionCall(ILFunction context, 
		                                           ILExpression fcall, 
		                                           string resultVar, 
		                                           StringBuilder source, 
		                                           AbstractEnvironment env, 
		                                           List<FunctionCallContainer> calls)
        {
            var f = fcall.Function;
            //Stdlib function
            if (f.EmbeddedBody != null) {
                if (f.CanBeCalculatedWithoutRun && !fcall.VAList.Any(pexpr => env.IsDynamic(pexpr.Const.ToString()))) {

                    var args = fcall.VAList.Select(ilexpr => ilexpr.Eval(env))
                        .Select(o => (o is Int32) ? o : ( (o is Boolean) ? o : L1Runtime.L1Runtime.GetArrayFromObjectArray((object[])o))).ToArray();
                    var result = f.EmbeddedBody.Invoke(null, args);

                    if (env.IsDynamic(resultVar)) {
                        source.Append("\t"); source.Append(resultVar); source.Append(" := "); RenderConst(result); source.Append(");"); source.Append(System.Environment.NewLine);
                    } else {
                        if (result is L1Runtime.L1Array<int>) {
                            var l1arr = result as L1Runtime.L1Array<int>;
                            var a = new object[l1arr.GetLength()];
                            for (int i = 0; i < a.Length; ++i) {
                                a[i] = l1arr.GetValue(i);
                            }
                            result = a;
                        }
                        env.SetValue(resultVar, result);
                    }
                } else {
                    source.Append("\t"); source.Append(resultVar); source.Append(" := "); source.Append(f.Name); source.Append("(");
                    for (int i = 0; i < fcall.VAList.Count; ++i) {
                        var p = fcall.VAList[i].Const.ToString();
                        if (env.IsDynamic(p)) {
                            source.Append(p);
                        } else {
                            source.Append(RenderConst(env.GetValue(p)));
                        }
                        if (i != fcall.VAList.Count - 1)
                            source.Append(", ");
                    }
                    source.Append(");"); source.Append(System.Environment.NewLine);
                }
            } else {
                if (f.CanBeCalculatedWithoutRun && !fcall.VAList.Any(pexpr => env.IsDynamic(pexpr.Const.ToString()))) {
                    var args = fcall.VAList.Select(ilexpr => ilexpr.Eval(env)).ToArray();
                    var res = f.Call(args);

                    if (env.IsDynamic(resultVar)) {
                        source.Append("\t").Append(resultVar).Append(" := ").Append(RenderConst(res)).Append(";").AppendLine();
                    } else {
                        env.SetValue(resultVar, res);
                    }
                }
                else {
                    var functionCallRef = new FunctionCallContainer {
                        Function = fcall.Function,
                        SourceFunction = context,
                        ResultVariable = resultVar,
                        Parameters = fcall.VAList.Select(ilexpr => env.IsDynamic(ilexpr.Const.ToString()) ? ilexpr.Const.ToString() : env.GetValue(ilexpr.Const.ToString())).ToList()
                    };
                    calls.Add(functionCallRef);
                    source.Append("\t").Append(functionCallRef.ToString()).AppendLine();
                }
            }
        }
        private static ILExpression _constructVariableAccess(string accessTo)
        {
            var ilExpr = new ILExpression();
            ilExpr.Type = ILExpressionType.VariableAccess;
            ilExpr.Const = accessTo;

            return ilExpr;
        }
 //Simple expr contains dynamic variables?
 private static bool m_simpleExprContainsDynamicVariables(ILExpression expr, AbstractEnvironment env)
 {
     if (expr.Type == ILExpressionType.FunctionCall) {
         if (expr.Function.EmbeddedBody != null && !expr.Function.CanBeCalculatedWithoutRun)
             return true;
         foreach (var arg in expr.VAList) {
             if (env.IsDynamic(arg.Const.ToString()))
                 return true;
         }
         if (expr.Function.CanBeCalculatedWithoutRun == false) {
             return true;
         }
     } else if (expr.Type == ILExpressionType.VariableAccess) {
         if (env.IsDynamic(expr.Const.ToString()))
             return true;
     } else {
         if (expr.LeftNode != null) {
             if (env.IsDynamic(expr.LeftNode.Const.ToString()))
                 return true;
         }
         if (expr.RightNode != null) {
             if (env.IsDynamic(expr.RightNode.Const.ToString()))
                 return true;
         }
     }
     return false;
 }
        private static ILExpression _constructAssignExpressionToConst(string assignTo, object constant)
        {
            var assingExpr = new ILExpression();
            assingExpr.Type = ILExpressionType.Assign;
            assingExpr.LeftNode = new ILExpression();
            assingExpr.LeftNode.Type = ILExpressionType.VariableAccess;
            assingExpr.LeftNode.Const = assignTo;

            assingExpr.RightNode = new ILExpression();
            assingExpr.RightNode.Type = ILExpressionType.Const;
            assingExpr.RightNode.Const = constant;
            return assingExpr;
        }
        private static ILExpression _constructBinaryExpressionFromVars(string leftOp, string rightOp, OperationType opType)
        {
            var ilExpr = new ILExpression();

            //+, -, *, /, mod, pow, xor
            if (opType == OperationType.Plus)
                ilExpr.Type = ILExpressionType.Plus;
            if (opType == OperationType.Minus)
                ilExpr.Type = ILExpressionType.Minus;
            if (opType == OperationType.Mult)
                ilExpr.Type = ILExpressionType.Mul;
            if (opType == OperationType.Div)
                ilExpr.Type = ILExpressionType.Div;
            if (opType == OperationType.Mod)
                ilExpr.Type = ILExpressionType.Mod;
            if (opType == OperationType.Power)
                ilExpr.Type = ILExpressionType.Pow;
            if (opType == OperationType.Xor)
                ilExpr.Type = ILExpressionType.Xor;
            //>,>=,<,<=,=,<>
            if (opType == OperationType.Gr)
                ilExpr.Type = ILExpressionType.Gr;
            if (opType == OperationType.Greq)
                ilExpr.Type = ILExpressionType.Greq;
            if (opType == OperationType.Le)
                ilExpr.Type = ILExpressionType.Le;
            if (opType == OperationType.Leeq)
                ilExpr.Type = ILExpressionType.Leeq;
            if (opType == OperationType.Equals)
                ilExpr.Type = ILExpressionType.Eq;
            if (opType == OperationType.NotEquals)
                ilExpr.Type = ILExpressionType.NotEq;
            //ArrayAccess
            if (opType == OperationType.ArrayAccess)
                ilExpr.Type = ILExpressionType.ArrayAccess;

            var left = new ILExpression();
            left.Type = ILExpressionType.VariableAccess;
            left.Const = leftOp;
            ilExpr.LeftNode = left;

            if (opType == OperationType.UMinus || opType == OperationType.UNot) {
                if (opType == OperationType.UMinus)
                    ilExpr.Type = ILExpressionType.Uminus;
                if (opType == OperationType.UNot)
                    ilExpr.Type = ILExpressionType.Unot;
                ilExpr.RightNode = null;
            }
            else {
                var right = new ILExpression();
                right.Type = ILExpressionType.VariableAccess;
                right.Const = rightOp;
                ilExpr.RightNode = right;
            }

            return ilExpr;
        }
        private static ILExpression _constructAssignExpression(ILExpression left, string assignWhat)
        {
            var assingExpr = new ILExpression();
            assingExpr.Type = ILExpressionType.Assign;

            assingExpr.LeftNode = left;

            assingExpr.RightNode = new ILExpression();
            assingExpr.RightNode.Type = ILExpressionType.VariableAccess;
            assingExpr.RightNode.Const = assignWhat;

            return assingExpr;
        }
 private static List<ILExpression> FindAllFunctionCallsInExpr(ILExpression expression)
 {
     if (expression == null)
         return new List<ILExpression>();
     if (expression.Type == ILExpressionType.FunctionCall)
         return new List<ILExpression>(new ILExpression[]{expression});
     else
     {
         var r = FindAllFunctionCallsInExpr(expression.LeftNode);
         r.AddRange(FindAllFunctionCallsInExpr(expression.RightNode));
         return r;
     }
 }
        private static ILExpression ConstructILExpression(Expression expr)
        {
            if (expr.OpType == OperationType.And || expr.OpType == OperationType.Or)
                throw new InvalidOperationException("And an Or doesn't supported yet");

            if (expr == null)
                return null;

            //Binary ops
            if (expr.IsLeaf == false)
            {
                ILExpression ilExpr = new ILExpression();

                ilExpr.LeftNode = ConstructILExpression(expr.LeftNode);
                ilExpr.RightNode = ConstructILExpression(expr.RightNode);

                //+, -, *, /, mod, pow, xor
                if (expr.OpType == OperationType.Plus)
                    ilExpr.Type = ILExpressionType.Plus;
                if (expr.OpType == OperationType.Minus)
                    ilExpr.Type = ILExpressionType.Minus;
                if (expr.OpType == OperationType.Mult)
                    ilExpr.Type = ILExpressionType.Mul;
                if (expr.OpType == OperationType.Div)
                    ilExpr.Type = ILExpressionType.Div;
                if (expr.OpType == OperationType.Mod)
                    ilExpr.Type = ILExpressionType.Mod;
                if (expr.OpType == OperationType.Power)
                    ilExpr.Type = ILExpressionType.Pow;
                if (expr.OpType == OperationType.Xor)
                    ilExpr.Type = ILExpressionType.Xor;
                //>,>=,<,<=,=,<>
                if (expr.OpType == OperationType.Gr)
                    ilExpr.Type = ILExpressionType.Gr;
                if (expr.OpType == OperationType.Greq)
                    ilExpr.Type = ILExpressionType.Greq;
                if (expr.OpType == OperationType.Le)
                    ilExpr.Type = ILExpressionType.Leeq;
                if (expr.OpType == OperationType.Equals)
                    ilExpr.Type = ILExpressionType.Eq;
                if (expr.OpType == OperationType.NotEquals)
                    ilExpr.Type = ILExpressionType.NotEq;
                //UNot, Uminus
                if (expr.OpType == OperationType.UNot)
                    ilExpr.Type = ILExpressionType.Unot;
                if (expr.OpType == OperationType.UMinus)
                    ilExpr.Type = ILExpressionType.Uminus;
                //ArrayAccess
                if (expr.OpType == OperationType.ArrayAccess)
                    ilExpr.Type = ILExpressionType.ArrayAccess;
                //Assign
                if (expr.OpType == OperationType.Assign)
                    ilExpr.Type = ILExpressionType.Assign;

                return ilExpr;
            }
            else
            {
                ILExpression ilExpr = new ILExpression();

                if (expr.LeafType == ExpressionLeafType.Constant)
                {
                    ilExpr.Type = ILExpressionType.Const;
                    if (expr.ResultType == VariableType.IntType)
                        ilExpr.Const = expr.IntValue;
                    else if (expr.ResultType == VariableType.BoolType)
                        ilExpr.Const = expr.BoolValue;
                    else
                        ilExpr.Const = expr.Value;
                }
                else if (expr.LeafType == ExpressionLeafType.VariableAccess)
                {
                    ilExpr.Type = ILExpressionType.VariableAccess;
                    ilExpr.Const = expr.Value;
                }
                else if (expr.LeafType == ExpressionLeafType.FunctionCall)
                {
                    ilExpr.Type = ILExpressionType.FunctionCall;
                    ilExpr.Const = expr.Value;
                    ilExpr.VAList = new List<ILExpression>();
                    foreach (var expression in expr.VAList)
                        ilExpr.VAList.Add(ConstructILExpression(expression));
                    ilExpr.Function = FindFunction((string)ilExpr.Const, expr.VAList);
                }
                else
                {
                    ilExpr.LeftNode = ConstructILExpression(expr.LeftNode);

                    if (expr.LeafType == ExpressionLeafType.ArrayLength)
                        ilExpr.Type = ILExpressionType.ArrayLength;
                    if (expr.LeafType == ExpressionLeafType.ArrayAlloc)
                        ilExpr.Type = ILExpressionType.Alloc;
                }

                return ilExpr;
            }
        }
        public static string _EmitExpression(Expression expr, List<ILInstuction> il)
        {
            if (expr.IsLeaf) {
                //Variable access
                if (expr.LeafType == ExpressionLeafType.VariableAccess) {

                    CurrentFunction.AddLocal(expr.Value.ToString(), expr.ResultType);

                    return expr.Value.ToString();
                } else if (expr.LeafType == ExpressionLeafType.Constant) {
                    var resultVariable = GetVariableName();
                    object c;
                    if (expr.ResultType == VariableType.IntType)
                        c = expr.IntValue;
                    else if (expr.ResultType == VariableType.BoolType)
                        c = expr.BoolValue;
                    else
                        c = expr.Value;
                    var ilExpr = _constructAssignExpressionToConst(resultVariable, c);
                    il.Add(ilExpr);

                    //ilExpr.OriginalType = expr.ResultType;
                    CurrentFunction.AddLocal(resultVariable, expr.ResultType);

                    return resultVariable;

                } else if (expr.LeafType == ExpressionLeafType.FunctionCall) {
                    var ilExpr = new ILExpression();
                    ilExpr.Type = ILExpressionType.FunctionCall;
                    ilExpr.Const = expr.Value;
                    ilExpr.VAList = new List<ILExpression>();
                    foreach (var expression in expr.VAList) {
                        var parameterVariable = _EmitExpression(expression, il);
                        ilExpr.VAList.Add(_constructVariableAccess(parameterVariable));
                    }
                    ilExpr.Function = FindFunction((string)ilExpr.Const, expr.VAList);
                    //TODO: Add support for void functions;

                    //ilExpr.OriginalType = expr.ResultType;

                    if (ilExpr.Function.IsVoidReturn) {
                        il.Add(ilExpr);
                        return "void";
                    } else {
                        var resultVariable = GetVariableName();
                        var resultExpr = _constructAssignExpression(resultVariable, ilExpr);
                        il.Add(resultExpr);

                        CurrentFunction.AddLocal(resultVariable, expr.ResultType);

                        return resultVariable;
                    }

                } else if (expr.LeafType == ExpressionLeafType.ArrayLength) {
                    var leftOp = _EmitExpression(expr.LeftNode, il);
                    var ilExpr = new ILExpression();
                    ilExpr.Type = ILExpressionType.ArrayLength;
                    ilExpr.LeftNode = _constructVariableAccess(leftOp);
                    var resultVariable = GetVariableName();
                    var resultExpr = _constructAssignExpression(resultVariable, ilExpr);
                    il.Add(resultExpr);

                    //resultExpr.OriginalType = expr.ResultType;
                    CurrentFunction.AddLocal(resultVariable, expr.ResultType);

                    return resultVariable;

                } else if (expr.LeafType == ExpressionLeafType.ArrayAlloc) {
                    var leftOp = _EmitExpression(expr.LeftNode, il);
                    var ilExpr = new ILExpression();
                    ilExpr.Type = ILExpressionType.Alloc;
                    ilExpr.OriginalType = expr.ResultType;

                    ilExpr.LeftNode = _constructVariableAccess(leftOp);
                    var resultVariable = GetVariableName();
                    var resultExpr = _constructAssignExpression(resultVariable, ilExpr);
                    il.Add(resultExpr);

                    CurrentFunction.AddLocal(resultVariable, expr.ResultType);

                    return resultVariable;
                }
            } else {
                if (expr.OpType == OperationType.Assign) {
                    var rightOp = _EmitExpression(expr.RightNode, il);
                    if (expr.LeftNode.LeafType == ExpressionLeafType.VariableAccess) {
                        var leftOp = _EmitExpression(expr.LeftNode, il);
                        il.Add(_constructAssignExpression(leftOp, rightOp));

                        CurrentFunction.AddLocal(leftOp, expr.ResultType);

                        return leftOp;
                    } else if (expr.LeftNode.OpType == OperationType.ArrayAccess) {

                        // Emit ( E1[E2] = E3) =
                        // Emit (E3) --> R
                        // Emit (E1) --> A
                        // Emit (E2) --> I
                        // A[I] = R
                        // return R;

                        var arrLeftOp = _EmitExpression(expr.LeftNode.LeftNode, il);
                        var arrIndexOp = _EmitExpression(expr.LeftNode.RightNode, il);
                        var arrAccess = _constructBinaryExpressionFromVars(arrLeftOp, arrIndexOp, OperationType.ArrayAccess);

                        var assignExpr = _constructAssignExpression(arrAccess, rightOp);
                        il.Add(assignExpr);

            //						assignExprstring resultVar = GetVariableName();
            //						var secondAssignExpr = _constructAssignExpression(resultVar, arrAccess);
            //						il.Add(secondAssignExpr);
                        return rightOp;
                    } else {
                        throw new InvalidOperationException("Bad assign construction!");
                    }
                } else if (expr.OpType == OperationType.And) {
                    var leftOp = _EmitExpression(expr.LeftNode, il);

                    CurrentFunction.AddLocal(leftOp, expr.ResultType);

                    var branch = new ILBranch();
                    branch.Line = GetLabel();
                    branch.Condition = _constructVariableAccess(leftOp);
                    var succ = new ILDummy();
                    succ.Line = GetLabel();
                    var fail = new ILDummy();
                    fail.Line = GetLabel();
                    var end = new ILDummy();
                    end.Line = GetLabel();
                    var gotoEnd = new ILGoto(end.Line);
                    branch.SuccessJump = succ.Line;
                    branch.FailJump = fail.Line;

                    var resultVariable = GetVariableName();
                    il.Add(branch);
                    il.Add(succ);
                    var rightOp = _EmitExpression(expr.RightNode, il);

                    CurrentFunction.AddLocal(rightOp, expr.ResultType);

                    il.Add(_constructAssignExpression(resultVariable, rightOp));
                    il.Add(gotoEnd);
                    il.Add(fail);
                    il.Add(_constructAssignExpressionToConst(resultVariable, false));
                    il.Add(end);

                    CurrentFunction.AddLocal(resultVariable, expr.ResultType);

                    return resultVariable;
                } else if (expr.OpType == OperationType.Or) {
                    var leftOp = _EmitExpression(expr.LeftNode, il);

                    CurrentFunction.AddLocal(leftOp, expr.ResultType);

                    var branch = new ILBranch();
                    branch.Line = GetLabel();
                    branch.Condition = _constructVariableAccess(leftOp);
                    var succ = new ILDummy();
                    succ.Line = GetLabel();
                    var fail = new ILDummy();
                    fail.Line = GetLabel();
                    var end = new ILDummy();
                    end.Line = GetLabel();
                    var gotoEnd = new ILGoto(end.Line);
                    branch.SuccessJump = succ.Line;
                    branch.FailJump = fail.Line;

                    var resultVariable = GetVariableName();
                    il.Add(branch);
                    il.Add(fail);
                    var rightOp = _EmitExpression(expr.RightNode, il);

                    CurrentFunction.AddLocal(rightOp, expr.ResultType);

                    il.Add(_constructAssignExpression(resultVariable, rightOp));
                    il.Add(gotoEnd);
                    il.Add(succ);
                    il.Add(_constructAssignExpressionToConst(resultVariable, true));
                    il.Add(end);

                    CurrentFunction.AddLocal(resultVariable, expr.ResultType);

                    return resultVariable;
                }
                else if (expr.OpType == OperationType.UNot || expr.OpType == OperationType.UMinus) {
                    var op1 = _EmitExpression(expr.LeftNode, il);
                    string varName=  GetVariableName();
                    var ilExpr = _constructBinaryExpressionFromVars(op1, "", expr.OpType);
                    il.Add(_constructAssignExpression(varName, ilExpr));

                    CurrentFunction.AddLocal(varName, expr.ResultType);

                    return varName;
                }
                else {
                    var op1 = _EmitExpression(expr.LeftNode, il);
                    var op2 = _EmitExpression(expr.RightNode, il);
                    string varName = GetVariableName();
                    var ilExpr = _constructBinaryExpressionFromVars(op1, op2, expr.OpType);
                    il.Add(_constructAssignExpression(varName, ilExpr));

                    CurrentFunction.AddLocal(varName, expr.ResultType);

                    return varName;
                }
            }

            throw new InvalidOperationException("Bad expression! " + expr.ToString());
        }
        public static void EmitVariableDefinition(VariableDefinitionList vdl, List<ILInstuction> il)
        {
            foreach (var vd in vdl.Definitions)
            {
                ILExpression initExpr = new ILExpression();
                initExpr.Type = ILExpressionType.Assign;

                ILExpression varAccess = new ILExpression();
                varAccess.Type = ILExpressionType.VariableAccess;
                varAccess.Const = vd.Name;

                initExpr.LeftNode = varAccess;
                if (vd.InitExpression != null)
                    initExpr.RightNode = ConstructILExpression(vd.InitExpression);
                else
                {
                    initExpr.RightNode = new ILExpression();
                    initExpr.RightNode.Type = ILExpressionType.Const;
                    if (vd.VariableType.Equals(VariableType.IntType))
                        initExpr.RightNode.Const = 0;
                    else if (vd.VariableType.Equals(VariableType.BoolType))
                        initExpr.RightNode.Const = false;
                    else
                        initExpr.RightNode.Const = null;
                }
                initExpr.Line = GetLabel();
                il.Add(initExpr);
            }
        }