/// <summary>
        /// executes the template given a set of instance parameters
        /// and writes its output to the target file
        /// </summary>
        /// <param name="targetFile"></param>
        public void Execute(string targetFile, TemplateParameters parameters)
        {
            if (System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(targetFile)) == false)
            {
                System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(targetFile));
            }
            MyStreamWriter response = new MyStreamWriter(targetFile);

            Execute(response, parameters);
            response.Close(); // done writing
        }
        /// <summary>
        /// compiles a template into an assembly
        /// </summary>
        /// <param name="assemblies">the assemblies to refernce</param>
        /// <param name="namespaces">the namespaces to add to the compiled template</param>
        /// <param name="parameternames">the names of the parameters to be declared in the assembly (these can be used inside the template)</param>
        /// <returns>the comiled assembly</returns>
        public void Compile(string[] assemblies, string[] namespaces, TemplateParameters parameters)
        {
            Assemblies = assemblies;
            Namespaces = namespaces;
            Parameters = parameters;

            Sections = Parser.ParsePage(Page);

            CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider();

            System.CodeDom.Compiler.CompilerParameters compilerparams = new System.CodeDom.Compiler.CompilerParameters();
            compilerparams.GenerateInMemory   = true;
            compilerparams.GenerateExecutable = false;

            // setup references assemblies
            if (assemblies != null)
            {
                foreach (string assembly in assemblies)
                {
                    compilerparams.ReferencedAssemblies.Add(assembly);
                }
            }


            foreach (Section s in Sections)
            {
                if (s.Type == SectionType.Directive)
                {
                    if (s.Values.Directive.ToLower() == "assembly")
                    {
                        string assembly;
                        if (s.Values.TryGetValue("name", out assembly))
                        {
                            compilerparams.ReferencedAssemblies.Add(assembly + ".dll");
                        }
                    }
                }
            }


            string source = Sections.ExtractSource(namespaces, parameters);

            if (source.Length > 0)
            {
                Result = provider.CompileAssemblyFromSource(compilerparams, new string[] { source });
                Console.WriteLine(source);
            }
        }
        public static string GenerateCodeForModule(CodeGeneratorProject Project, CodeGeneratorModule module, string templateCode, bool isProjectTemplate = false)
        {
            templateCode = templateCode.Replace("{CURRENTDIRECTORY}", System.IO.Directory.GetCurrentDirectory());
            string tmpCodeFile = System.IO.Directory.GetCurrentDirectory() + "/tmp.source.aspx";

            File.WriteAllText(tmpCodeFile, templateCode);

            AspCompiler.Template           template   = new AspCompiler.Template(tmpCodeFile);
            AspCompiler.TemplateParameters parameters = new AspCompiler.TemplateParameters();
            AspCompiler.TemplateParameter  param      = new AspCompiler.TemplateParameter(typeof(CodeGeneratorProject), "Project", Project);
            parameters.Add(param);
            param = new AspCompiler.TemplateParameter(typeof(CodeGeneratorModule), "Module", module);
            parameters.Add(param);

            string currentPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

            string[] assemblies = new string[4];
            assemblies[0] = currentPath + "\\Com.Wiseape.Utility.dll";
            assemblies[1] = currentPath + "\\Com.Wiseape.UtilityApp.CodeGenerator.dll";
            assemblies[2] = currentPath + "\\AspCompiler.dll";
            assemblies[3] = currentPath + "\\Com.Wiseape.UtilityApp.CodeGenerator.Helper.dll";


            string[] namespaces = new string[7];
            namespaces[0] = "System.Collections.Generic";
            namespaces[1] = "System.Collections";
            namespaces[2] = "Com.Wiseape.UtilityApp.CodeGenerator.Model";
            namespaces[3] = "Com.Wiseape.UtilityApp.CodeGenerator.Business";
            namespaces[4] = "Com.Wiseape.Utility";
            namespaces[5] = "AspCompiler";
            namespaces[6] = "Com.Wiseape.UtilityApp.CodeGenerator.Helper";

            //namespaces[4] = "System.Data";

            template.Compile(assemblies, namespaces, parameters);
            string tmpFile = System.IO.Directory.GetCurrentDirectory() + "/tmp.result";

            template.Execute(tmpFile);
            string content = System.IO.File.ReadAllText(tmpFile);

            return(content);
        }
        /// <summary>
        /// executes the template and writes output to the response
        /// caller is required to open and close the output stream
        /// </summary>
        /// <param name="response">the output stream to write to</param>
        public void Execute(MyStreamWriter response, TemplateParameters parameters)
        {
            if (Result == null)
            {
                return;
            }

            if (Result.Errors.HasErrors)
            {
                foreach (System.CodeDom.Compiler.CompilerError error in Result.Errors)
                {
                    response.Write(GenerateSource());
                    response.Write(String.Format("Error on line {0}: {1}", error.Line, error.ErrorText));
                }
                return;
            }

            if (Sections == null)
            {
                return;                   // nothing to execute
            }
            Sections.Process(Result.CompiledAssembly, parameters, response);
        }
            public string ExtractSource(string[] namespaces, TemplateParameters parameters)
            {
                StringBuilder lines = new StringBuilder();

                lines.Append("using System;\r\n");
                lines.Append("using System.Text;\r\n");
                lines.Append("using System.Collections.Generic;\r\n");

                // setup public parameters
                if (namespaces != null)
                {
                    foreach (string ns in namespaces)
                    {
                        lines.Append("using " + ns + ";\r\n");
                    }
                }

                foreach (Section line in this)
                {
                    if (line.Type == SectionType.Directive)
                    {
                        if (line.Values.Directive.ToLower() == "import")
                        {
                            string ns;
                            if (line.Values.TryGetValue("namespace", out ns))
                            {
                                lines.Append("using " + ns + ";\r\n");
                            }
                        }
                    }
                }
                lines.Append("public class Page {\r\n");
                lines.Append("  public MyStreamWriter me;\r\n");
                lines.Append("  public MyStreamWriter Response;\r\n");

                // setup public variable declarations
                foreach (Section line in this)
                {
                    if (line.Type == SectionType.Text)
                    {
                        lines.Append("  public string SectionText" + line.Index + ";\r\n");
                    }
                }

                // setup public parameters
                if (parameters != null)
                {
                    foreach (TemplateParameter parameter in parameters)
                    {
                        lines.Append("  public " + parameter.Type.FullName + " " + parameter.Name + ";\r\n");
                    }
                }

                // setup public declarations extracted from the template script-tags
                foreach (Section line in this)
                {
                    if (line.Type == SectionType.Declaration)
                    {
                        lines.Append(line.Text + "\r\n");
                    }
                }

                lines.Append("  public Page() {}\r\n");           // add a constructor
                lines.Append("  public void RenderPage() {\r\n"); // setup the page execution entrypoint

                foreach (Section line in this)
                {
                    if (line.Type == SectionType.Text)
                    {
                        lines.Append("    me.say(SectionText" + line.Index + ");\r\n");
                    }
                    else if (line.Type == SectionType.Code)
                    {
                        if (line.Text.Trim().StartsWith("@"))
                        {
                            continue;
                        }
                        lines.Append(line.Text);
                    }
                }
                lines.Append("  }\r\n");
                lines.Append("}\r\n");
                return(lines.ToString());
            }
            public void Process(Assembly assembly, TemplateParameters parameters, MyStreamWriter Response)
            {
                try
                {
                    if (assembly == null)
                    {
                        return;
                    }

                    object instance = assembly.CreateInstance("Page");
                    Type   typepage = instance.GetType();

                    // assign Response object to Page
                    typepage.InvokeMember("me", BindingFlags.SetField, null, instance, new object[] { Response });
                    typepage.InvokeMember("Response", BindingFlags.SetField, null, instance, new object[] { Response });

                    // assign section texts to Page members for execution
                    foreach (Section section in this)
                    {
                        if (section.Type == SectionType.Text)
                        {
                            // assign section text to Page members
                            typepage.InvokeMember("SectionText" + section.Index, BindingFlags.SetField, null, instance, new object[] { section.Text });
                        }
                    }

                    // assign parameters to page
                    if (parameters != null)
                    {
                        foreach (TemplateParameter tp in parameters)
                        {
                            // try to assign the parameter. if the parameter/variable is not defined in the
                            // template then skip it, there is no need to break the execution here
                            try
                            {
                                typepage.InvokeMember(tp.Name, BindingFlags.SetField, null, instance, new object[] { tp.Value });
                            }
                            catch (MissingFieldException)
                            {
                                //variable was not declared in template but continue anyway
                            }
                        }
                    }


                    typepage.InvokeMember("RenderPage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, null, instance, null);
                }
                catch (Exception ex)
                {
                    Exception inner;
                    Response.WriteLine();
                    inner = ex;

                    while (inner != null)
                    {
                        Response.WriteLine(inner.Message);
                        inner = inner.InnerException;
                    }
                    Response.WriteLine(ex.StackTrace);
                }
            }
 /// <summary>
 /// just compiles without any parameters
 /// </summary>
 public void Compile(TemplateParameters parameters)
 {
     //Compile(null, null, null);
     Compile(this.Assemblies, this.Namespaces, parameters);
 }