/// <summary>
        /// Creates a lambda compiler that will compile to a dynamic method
        /// </summary>
        private LambdaCompiler(AnalyzedTree tree, LambdaExpression lambda)
        {
            var parameterTypes = GetParameterTypes(lambda).AddFirst(typeof(Closure));

            var method = new DynamicMethod(lambda.Name ?? "lambda_method", lambda.ReturnType, parameterTypes, true);

            _tree   = tree;
            _lambda = lambda;
            _method = method;

            // In a Win8 immersive process user code is not allowed to access non-W8P framework APIs through
            // reflection or RefEmit. Framework code, however, is given an exemption.
            // This is to make sure that user code cannot access non-W8P framework APIs via ExpressionTree.

            // TODO: This API is not available, is there an alternative way to achieve the same.
            // method.ProfileAPICheck = true;

            _ilg = method.GetILGenerator();

            _hasClosureArgument = true;

            // These are populated by AnalyzeTree/VariableBinder
            _scope          = tree.Scopes[lambda];
            _boundConstants = tree.Constants[lambda];

            InitializeMethod();
        }
        /// <summary>
        /// Creates a lambda compiler that will compile into the provided Methodbuilder
        /// </summary>
        private LambdaCompiler(AnalyzedTree tree, LambdaExpression lambda, MethodBuilder method)
        {
            _hasClosureArgument = tree.Scopes[lambda].NeedsClosure;
            var paramTypes = GetParameterTypes(lambda);

            if (_hasClosureArgument)
            {
                paramTypes = paramTypes.AddFirst(typeof(Closure));
            }

            method.SetReturnType(lambda.ReturnType);
            method.SetParameters(paramTypes);
            var paramNames = lambda.Parameters.Map(p => p.Name);
            // parameters are index from 1, with closure argument we need to skip the first arg
            var startIndex = _hasClosureArgument ? 2 : 1;

            for (int i = 0; i < paramNames.Length; i++)
            {
                method.DefineParameter(i + startIndex, ParameterAttributes.None, paramNames[i]);
            }

            _tree        = tree;
            _lambda      = lambda;
            _typeBuilder = (TypeBuilder)method.DeclaringType;
            _method      = method;

            _ilg = method.GetILGenerator();

            // These are populated by AnalyzeTree/VariableBinder
            _scope          = tree.Scopes[lambda];
            _boundConstants = tree.Constants[lambda];

            InitializeMethod();
        }
 /// <summary>
 /// Creates a lambda compiler for an inlined lambda
 /// </summary>
 private LambdaCompiler(LambdaCompiler parent, LambdaExpression lambda)
 {
     _tree               = parent._tree;
     _lambda             = lambda;
     _method             = parent._method;
     _ilg                = parent._ilg;
     _hasClosureArgument = parent._hasClosureArgument;
     _typeBuilder        = parent._typeBuilder;
     _scope              = _tree.Scopes[lambda];
     _boundConstants     = parent._boundConstants;
 }