public virtual void GenerateTemplate(EnvDTE.ProjectItem templateItem)
        {
            var    masterProjectItem = this.Dte.Solution.FindProjectItem(this.TemplateFile);
            string fullOutputPath;

            if (templateItem.IsLinkedItem())
            {
                fullOutputPath = Path.Combine(templateItem.ContainingProject.GetProjectDir(), templateItem.GetVirtualPath());
            }
            else
            {
                fullOutputPath = templateItem.GetFullPath();
            }

            fullOutputPath = fullOutputPath.Replace(templateItem.GetFileNameExtension(), ".{ext}");
            this.GenerateTemplateInternal(templateItem.GetFullPath(), fullOutputPath, masterProjectItem, templateItem);
        }
        protected internal virtual void GenerateTemplateInternal(string fullTemplatePath, string fullOutputPath, EnvDTE.ProjectItem templateOwner, EnvDTE.ProjectItem outputOwner)
        {
            Debug.WriteLine(String.Format("Generating template \"{0}\"\r\nto \"{1}\".", fullTemplatePath, fullOutputPath));

            #region Auto-hide sub templates

            if ((this.HideSubtemplates) && (templateOwner != null) && (outputOwner != null))
            {
                if (outputOwner.IsLinkedItem())
                {
                    // Ignore linked items.
                }
                else if ((outputOwner.Collection.Parent is EnvDTE.ProjectItem) && ((EnvDTE.ProjectItem)outputOwner.Collection.Parent).GetFullPath().Equals(templateOwner.GetFullPath()))
                {
                    // Item already hidden.
                }
                else
                {
                    // Try to hide item:
                    try
                    {
                        Debug.WriteLine(String.Format("Hiding subtemplate \"{0}\" under \"{1}\".", fullTemplatePath, templateOwner.GetVirtualPath()));
                        templateOwner.ProjectItems.AddFromFile(fullTemplatePath);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(String.Format("Failed to hide subtemplate {0}: {1}", outputOwner.GetFullPath(), ex.Message));
                    }
                }
            }

            #endregion

            #region Generate template

            string output;

            Engine engine = new Engine();
            GenerationHost <Mapping> host = new GenerationHost <Mapping>(fullTemplatePath, this.Mapping);
            host.LocalNamespace = this.LocalNamespace;

            using (new CurrentDirectoryScope(fullTemplatePath))
                using (new CallContextScope("GenerationHost", host))
                {
                    output = engine.ProcessTemplate(host.TemplateFileContent, host);
                }

            #endregion

            #region Write output

            if (host.Errors.HasErrors)
            {
                string logfilename = Environment.ExpandEnvironmentVariables(@"%TEMP%\Max.Tools.DomainGenerator.log");

                if (File.Exists(logfilename))
                {
                    var sb = new StringBuilder();
                    sb.AppendLine();
                    sb.AppendFormat("Generation at {0} had {1} error(s):", DateTime.Now, host.Errors.Count);
                    sb.AppendLine();
                    foreach (var err in host.Errors)
                    {
                        sb.AppendLine(String.Format("- {0}", err));
                    }

                    Debug.Write(sb.ToString());
                    File.AppendAllText(logfilename, sb.ToString());
                }

                throw new ApplicationException(String.Format("Generation of template {0} caused {1} error(s), create a {3} file to have all errors logged; first error: {2}", fullTemplatePath, host.Errors.Count, host.Errors[0], logfilename));
            }
            else
            {
                fullOutputPath = fullOutputPath.Replace(".{ext}", host.FileExtension);

                WriteFile(fullTemplatePath, fullOutputPath, output, host.FileEncoding, templateOwner, outputOwner);
            }

            #endregion
        }