private void EmitMethod(DeclarationEmitContext dgc, string id, IEnumerable<ParameterSyntax> parameters, SyntaxNode body)
        {
            var ltype = dgc.LType;
            var qname = ltype.ID + "." + id;

            TraceEmit("  method '{0}' ...", id);

            var rtype = ltype.RType;
            var ps = TranslateMethodParameters(parameters);

            var jsw = new JScriptWriter();
            jsw.Write(GetPrototypeClause(ltype, id) + " = function(" + ps + ")");

            // method context
            var context = ModuleFactory.CreateMethodContext((IDeclarationContext)ltype);

            // CS to JS rewriter using the method context.
            var rewriter = CreateRewriter(dgc, context);

            // parameter variables 
            rewriter.AddMethodParameters(parameters);

            if (null == body)
            {
                Trace("WARNING: method " + id + " has no body.");
                return;
            }

            // convert the method body
            var node = rewriter.Visit(body);

            // prefix with the 'this' replacement
            node = AddLambdaThis(node);

            // and emit the JS method declaration
            jsw.WriteLine(node.ToString());
            dgc.Writer.Write(jsw);
        }
        private void EmitConstructorFields(DeclarationEmitContext dgc, CSharpToJScriptRewriter rewriter, JScriptWriter jsw)
        {
            var info = dgc.LType;
            var rtype = info.RType;

            var cls = dgc.Source.ClassDeclaration;

            // emit class member fields (LN4NL4H5PI)
            foreach (var fielddecl in cls.ChildNodes().OfType<FieldDeclarationSyntax>())
            {
                foreach (var declarator in fielddecl.DescendantNodes().OfType<VariableDeclaratorSyntax>())
                {
                    var id = declarator.Identifier.ToString();
                    if (null != rtype)
                    {
                        var field = rtype.GetField(id, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                        if (null != field && field.IsStatic)
                        {
                            continue;
                        }
                    }

                    // identifier, prepend 'this'.
                    //var idsyntax = SyntaxFactory.IdentifierName(declarator.Identifier);
                    var idsyntax = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                        SyntaxFactory.IdentifierName(Settings.OuterThis),
                        SyntaxFactory.IdentifierName(declarator.Identifier)
                        );
                    var idnode = rewriter.Visit(idsyntax);
                    jsw.Write(idnode.ToString());

                    var equals = declarator.ChildNodes().FirstOrDefault();
                    if (null != equals)
                    {
                        var node = rewriter.Visit(equals);
                        jsw.Write(node.ToString());
                    }
                    else
                    {
                        jsw.Write(" = null");
                    }

                    jsw.WriteLine(";");
                }
            }

            // event objects (LMGMELDMQ7)
            foreach (var ev in cls.Members.OfType<EventFieldDeclarationSyntax>())
            {
                foreach (var v in ev.Declaration.Variables)
                {
                    // initialize event object to null, as in C#
                    var id = Settings.OuterThis + "." + v.Identifier;
                    jsw.WriteLine(id + " = null;");

                    jsw.WriteLine("this.add_" + v.Identifier + " = function(h) {");
                    jsw.WriteLine(id + " = Delegate.Combine(" + id + ", h); };");
                    jsw.WriteLine("this.remove_" + v.Identifier + " = function(h) {");
                    jsw.WriteLine(id + " = Delegate.Remove(" + id + ", h); };");
                    jsw.WriteLine("this.fire_" + v.Identifier + " = function(sender, e) {");
                    jsw.WriteLine("Delegate.Fire(" + id + ", sender, e); };");
                }
            }

            // constructor
            var constructor = cls.Members.OfType<ConstructorDeclarationSyntax>().FirstOrDefault();
            if (null != constructor)
            {
                foreach (var stmt in constructor.Body.Statements)
                {
                    var ctor = rewriter.Visit(stmt);
                    // ctor = AddLambdaThis(ctor);
                    jsw.Write(ctor.ToString());
                }
            }
        }
        private void EmitConstructor(DeclarationEmitContext dgc, IEnumerable<string> autoprops)
        {
            var ltype = dgc.LType;
            var rtype = ltype.RType;
            var typename = ltype.CodeName;

            var declctx = (IDeclarationContext)ltype;

            // method context for constructor
            var context = ModuleFactory.CreateMethodContext(declctx);

            // rewriter
            var rewriter = CreateRewriter(dgc, context);

            // writer receiving constructor and related code.
            JScriptWriter jsw = new JScriptWriter();

            // initialize the prototype
            string basename = null;
            if (null != ltype.BaseType)
            {
                if (null != ltype.BaseType.RType)
                {
                    basename = ltype.BaseType.CodeName;
                    jsw.WriteLine(typename + ".prototype = new " + basename + "();");
                    jsw.WriteLine(typename + ".prototype.constructor = " + typename + ";");
                }
            }

            // static
            EmitStaticInitializer(dgc, jsw);

            // analyze constructors ...
            var cls = dgc.Source.ClassDeclaration;
            var constructors = cls.Members.OfType<ConstructorDeclarationSyntax>();
            if (constructors.Count() > 1)
            {
                throw new Exception("multiple constructors are not supported [" + typename + "].");
            }

            var constructor = constructors.FirstOrDefault();
            var ps = string.Empty;
            if (null != constructor)
            {
                var parameters = constructor.ParameterList.ChildNodes().OfType<ParameterSyntax>();
                rewriter.AddMethodParameters(parameters);
                ps = TranslateMethodParameters(parameters);
            }


            // constructor method
            jsw.WriteLine("function " + typename + "(" + ps + ")");
            jsw.EnterBlock();

            // call base constructor
            if (null != basename)
            {
                jsw.WriteLine(basename + ".prototype.constructor.call(this);");
            }

            // type identifier
            jsw.WriteLine("this.$type = '" + typename + "';");

            // initialize our 'this' replacement.
            var cthis = CreateLambdaThis();
            jsw.Write(cthis.ToString());

            foreach (var ap in autoprops)
            {
                jsw.Write(Settings.OuterThis + "." + DeriveAutomaticName(ap) + " = null;");
            }

            foreach (var dp in dgc.DependencyPropertyInitializations)
            {
                // TODO: constant management required.
                //var dvalue = dp.DefaultMetadata.DefaultValue;
                object dvalue = null;
                if (null == dvalue)
                {
                    jsw.Write(Settings.OuterThis + ".InitValue(\"" + dp.Name + "\");");
                }
                else
                {
                    jsw.Write(Settings.OuterThis + ".InitValue(\"" + dp.Name + "\", " + dvalue + ");");
                }
            }

            // field initializers and constructor body ...
            EmitConstructorFields(dgc, rewriter, jsw);

            jsw.LeaveBlock();

            // commit to class output
            dgc.Writer.Write(jsw);
        }
        private void EmitStaticInitializer(DeclarationEmitContext dgc, JScriptWriter staticinit)
        {
            var cls = dgc.Source.ClassDeclaration;
            var ltype = dgc.LType;
            var typename = ltype.CodeName;
            var rtype = ltype.RType;

            staticinit.WriteLine(typename + ".prototype.$static = ");
            staticinit.EnterBlock();

            if (null != ltype.BaseType)
            {
                staticinit.WriteLine("BaseClass: \"" + ltype.BaseType.CodeName + "\",");
            }

            var dplist = new List<DependencyProperty>();

            // emit static variables
            foreach (var fielddecl in cls.ChildNodes().OfType<FieldDeclarationSyntax>())
            {
                foreach (var declarator in fielddecl.DescendantNodes().OfType<VariableDeclaratorSyntax>())
                {
                    var id = declarator.Identifier.ToString();
                    var field = rtype.GetField(id, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

                    if (null != field && field.IsStatic)
                    {
                        if (field.FieldType == typeof(DependencyProperty))
                        {
                            var dp = field.GetValue(null) as DependencyProperty;
                            if (null == dp) continue;
                            dplist.Add(dp);
                        }
                    }
                }
            }

            EmitDependencyPropertyDefinitions(staticinit, dplist);

            staticinit.LeaveBlock();
            staticinit.WriteLine(";");

        }
        private void EmitDependencyPropertyDefinitions(JScriptWriter jsw, List<DependencyProperty> dplist)
        {
            foreach (var dp in dplist)
            {
                var dptype = dp.PropertyType;
                var ldptype = _context.TranslateRType(dptype, TranslateOptions.MustExist);
                var convert = ldptype.GetConvertMethod();

                jsw.Write(dp.Name + "Property:");
                jsw.EnterBlock();

                jsw.WriteLine("Type: \"" + ldptype.ID + "\",");

                if (null != convert)
                {
                    jsw.WriteLine("Convert: function(p) { return " + convert.ID + "(p); },");
                }

                jsw.LeaveBlock();
                jsw.WriteLine(",");
            }
        }
        private void EmitNativeScript(IScriptReference script)
        {
            using (var s = script.Assembly.GetManifestResourceStream(script.Key))
            {
                if (null == s)
                {
                    Log.Warning("native script '{0}' was not found.", script.Key);
                }
                else
                {
                    if (Log.ShowScripts || Log.ShowCodeGeneration)
                    {
                        Log.Trace("  inline script '{0}' ...", script.Path);
                    }

                    var jsw = new JScriptWriter();
                    using (var reader = new StreamReader(s))
                    {
                        jsw.WriteLine(reader.ReadToEnd());
                    }

                    RewriteDeclaration(jsw);
                }
            }
        }
        private void EmitScript(XmlWriter writer)
        {
            EmitScriptIncludesBefore(writer);

            var code = new JScriptWriter();
            code.WriteLine();
            code.WriteLine("// generated");
            code.Write(_scriptincludes);
            code.Write(Declarations);

            // consumed, more to come ...

            // resize handler function (unused currently)
            code.WriteLine("function docResized() ");
            code.EnterBlock();
            code.WriteLine("ResizeManager_Initialize();");
            code.Write(_resizebuilder);
            code.LeaveBlock();

            // bindings initialization
            code.WriteLine();
            code.WriteLine("function Bindings_Initialize() ");
            code.EnterBlock();
            code.WriteLine("if(window['BindingObject'] !== undefined)");
            code.EnterBlock();
            code.Write(CodeBuilder);
            code.LeaveBlock();
            code.LeaveBlock();

            // primary document ready handler
            code.WriteLine();
            code.WriteLine("docReady(function() ");
            code.EnterBlock();
            code.WriteLine("DataContext_Initialize(function() { Bindings_Initialize(); });");
            code.WriteLine("docResized();");
            code.WriteLine("DragDrop_Initialize();");
            code.LeaveBlock();
            code.WriteLine(");");


            // TraceTarget.Trace("jscript code in HTML:\n{0}\n\n", code.Text);

            writer.WriteStartElement("script");

            if (!IsOptimized)
            {

                writer.WriteRaw(code.Text);
            }
            else
            {
                Information("generating optimized code ...");
                var builder = new JScriptBuilder();
                builder.SuppressedGlobalFunctions.Add("trace");
                builder.RewriteProgram(code);
                writer.WriteRaw(builder.Text);
            }

            writer.WriteEndElement();

            // application specific initializer scripts ...
            _scriptincludes = new JScriptBuilder();
            EmitScriptIncludesAfter(writer);

            if (_scriptincludes.Text.Length > 0)
            {
                writer.WriteStartElement("script");
                writer.WriteRaw(_scriptincludes.Text);
                writer.WriteEndElement();
            }
        }
        private void EmitScriptItems(XmlWriter writer, IEnumerable<string> scriptincludes)
        {
            if (!InlineAllScript)
            {
                foreach (var include in scriptincludes)
                {
                    writer.WriteStartElement("script");
                    writer.WriteAttributeString("src", include);
                    writer.WriteString("\u00A0");
                    writer.WriteEndElement();
                }
            }
            else
            {
                var common = new JScriptWriter();

                if(null == ScriptSource)
                {
                    throw new Exception("script source required to inline scripts.");
                }

                foreach (var include in scriptincludes)
                {
                    using(var reader = new StreamReader(ScriptSource(include)))
                    {
                        Log.Trace("including script '{0}' ...", include);

                        var jscode = reader.ReadToEnd();
                        common.WriteLine(jscode);
                    }
                }

                // compactify code ...
                var compacter = new JScriptBuilder();
                compacter.IsCompact = IsCompact;
                compacter.RewriteProgram(common);

                _scriptincludes.Write(compacter);
            }
        }