TextWriter writer; // all output is sent here

        #endregion Fields

        #region Constructors

        /// <summary>
        /// create template manager using a template
        /// </summary>
        public TemplateManager(Template template)
        {
            this.mainTemplate = template;
            this.currentTemplate = template;
            this.silentErrors = false;

            Init();
        }
        public Template(string name, List<Element> elements, Template parent)
        {
            this.name = name;
            this.elements = elements;
            this.parent = parent;

            InitTemplates();
        }
        protected void ProcessTemplate(string name, Tag tag)
        {
            if (customTags != null && customTags.ContainsKey(name))
            {
                ExecuteCustomTag(tag);
                return;
            }

            Template useTemplate = currentTemplate.FindTemplate(name);
            if (useTemplate == null)
            {
                string msg = string.Format("Template '{0}' not found", name);
                throw new TemplateRuntimeException(msg, tag.Line, tag.Col);
            }

            // process inner elements and save content
            TextWriter saveWriter = writer;
            writer = new StringWriter();
            string content = string.Empty;

            try
            {
                ProcessElements(tag.InnerElements);

                content = writer.ToString();
            }
            finally
            {
                writer = saveWriter;
            }

            Template saveTemplate = currentTemplate;
            variables = new VariableScope(variables);
            variables["innerText"] = content;

            try
            {
                foreach (TagAttribute attrib in tag.Attributes)
                {
                    object val = EvalExpression(attrib.Expression);
                    variables[attrib.Name] = val;
                }

                currentTemplate = useTemplate;
                ProcessElements(currentTemplate.Elements);
            }
            finally
            {
                variables = variables.Parent;
                currentTemplate = saveTemplate;
            }
        }
        /// <summary>
        /// processes current template and sends output to writer
        /// </summary>
        /// <param name="writer"></param>
        public void Process(TextWriter writer)
        {
            this.writer = writer;
            this.currentTemplate = mainTemplate;

            if (handler != null)
            {
                SetValue("this", handler);
                handler.BeforeProcess(this);
            }

            ProcessElements(mainTemplate.Elements);

            if (handler != null)
                handler.AfterProcess(this);
        }
 /// <summary>
 /// adds template that can be used within execution 
 /// </summary>
 /// <param name="template"></param>
 public void AddTemplate(Template template)
 {
     mainTemplate.Templates.Add(template.Name, template);
 }
        /// <summary>
        /// go thru all tags and see if they are template tags and add
        /// them to this.templates collection
        /// </summary>
        private void InitTemplates()
        {
            this.templates = new Dictionary<string, Template>(StringComparer.InvariantCultureIgnoreCase);

            foreach (Element elem in elements)
            {
                if (elem is Tag)
                {
                    Tag tag = (Tag)elem;
                    if (string.Compare(tag.Name, "template", true) == 0)
                    {
                        Expression ename = tag.AttributeValue("name");
                        string tname;
                        if (ename is StringLiteral)
                            tname = ((StringLiteral)ename).Content;
                        else
                            tname = "?";

                        Template template = new Template(tname, tag.InnerElements, this);
                        templates[tname] = template;
                    }
                }
            }
        }