///--------------------------------------------------------------------------------
        /// <summary>This method assigns a value to a property, and updates corresponding
        /// forward and reverse engineering data.</summary>
        ///
        /// <param name="propertyName">The property name.</param>
        /// <param name="propertyValue">The property value.</param>
        ///--------------------------------------------------------------------------------
        public override bool AssignProperty(string propertyName, object propertyValue)
        {
            if (this.SetPropertyValue(propertyName, propertyValue) == true)
            {
                if (ReverseInstance == null)
                {
                    ReverseInstance = new CodeTemplate();
                    ReverseInstance.TransformDataFromObject(this, null, false);
                }
                else
                {
                    ReverseInstance.SetPropertyValue(propertyName, propertyValue);
                }
                if (ForwardInstance != null)
                {
                    this.TransformDataFromObject(ForwardInstance, null, false, true);
                }
            }
            else
            {
                return(false);
            }

            #region protected
            #endregion protected

            return(true);
        }
        ///--------------------------------------------------------------------------------
        /// <summary>This property returns a copy of the forward engineering data for the solution.</summary>
        ///--------------------------------------------------------------------------------
        public new CodeTemplate GetForwardInstance(Solution forwardSolution)
        {
            bool         isCustomized = false;
            CodeTemplate forwardItem  = new CodeTemplate();

            if (ForwardInstance != null)
            {
                forwardItem.TransformDataFromObject(ForwardInstance, null, false);
                isCustomized = true;
            }
            else if (IsAutoUpdated == false)
            {
                forwardItem.TransformDataFromObject(this, null, false);
                isCustomized = true;
            }
            else
            {
                forwardItem.TemplateID = TemplateID;
            }
            if (isCustomized == false)
            {
                return(null);
            }
            forwardItem.SpecSourceName = DefaultSourceName;
            if (forwardSolution.ReferencedModelIDs.Find("ItemName", forwardItem.SpecSourceName) == null)
            {
                forwardSolution.ReferencedModelIDs.Add(CreateIDReference());
            }

            #region protected
            #endregion protected

            return(forwardItem);
        }
        ///--------------------------------------------------------------------------------
        /// <summary>This method copies changed metadata between the input
        /// instance and the current instance.</summary>
        ///
        /// <param name="inputCodeTemplate">The codetemplate to get metadata.</param>
        ///--------------------------------------------------------------------------------
        public void CopyChangedMetadata(CodeTemplate inputCodeTemplate)
        {
            SpecificationDirectory = inputCodeTemplate.SpecificationDirectory;

            #region protected
            #endregion protected
        }
        ///--------------------------------------------------------------------------------
        /// <summary>This method determines whether or not any metadata is
        /// different between the input instance and the current instance.</summary>
        ///
        /// <param name="inputCodeTemplate">The codetemplate to compare metadata.</param>
        ///--------------------------------------------------------------------------------
        public bool IsIdenticalMetadata(CodeTemplate inputCodeTemplate)
        {
            if (SpecificationDirectory.GetString() != inputCodeTemplate.SpecificationDirectory.GetString())
            {
                return(false);
            }

            #region protected
            #endregion protected

            return(true);
        }
 ///--------------------------------------------------------------------------------
 /// <summary>This method adds a tag to TagList.</summary>
 ///--------------------------------------------------------------------------------
 public override void AddTag(string tagName)
 {
     if (ReverseInstance == null && IsAutoUpdated == true)
     {
         ReverseInstance = new CodeTemplate();
         ReverseInstance.TransformDataFromObject(this, null, false);
         IsAutoUpdated = false;
     }
     base.AddTag(tagName);
     if (ForwardInstance == null)
     {
         ForwardInstance            = new CodeTemplate();
         ForwardInstance.TemplateID = TemplateID;
     }
     if (ForwardInstance.TagList.Find(t => t.TagName == tagName) == null)
     {
         ForwardInstance.TagList.Add(new Tag(Guid.NewGuid(), tagName));
     }
 }
        ///--------------------------------------------------------------------------------
        /// <summary>This method determines whether the input instance metadata is
        /// effectively empty.</summary>
        ///
        /// <param name="inputCodeTemplate">The codetemplate to compare metadata.</param>
        ///--------------------------------------------------------------------------------
        public bool IsEmptyMetadata(CodeTemplate inputCodeTemplate)
        {
            if (inputCodeTemplate == null)
            {
                return(true);
            }
            if (inputCodeTemplate.TagList.Count > 0)
            {
                return(false);
            }
            if (!String.IsNullOrEmpty(inputCodeTemplate.SpecificationDirectory))
            {
                return(false);
            }

            #region protected
            #endregion protected

            return(true);
        }
        ///--------------------------------------------------------------------------------
        /// <summary>Interpret this node to produce code, output, or model data..</summary>
        ///
        /// <param name="interpreterType">The type of interpretation to perform.</param>
        /// <param name="solutionContext">The associated solution.</param>
        /// <param name="templateContext">The associated template.</param>
        /// <param name="parentTemplateContext">The associated parent template.</param>
        /// <param name="modelContext">The associated model context.</param>
        /// <param name="parameterModelContext">The associated model context for parameters.</param>
        ///--------------------------------------------------------------------------------
        public void InterpretNode(InterpreterTypeCode interpreterType, Solution solutionContext, ITemplate templateContext, ITemplate parentTemplateContext, IDomainEnterpriseObject modelContext, IDomainEnterpriseObject parameterModelContext, bool appendToTemplateContext)
        {
            try
            {
                ITemplate template = null;
                if (TemplateName == LanguageTerms.TemplateProperty && modelContext is Project)
                {
                    if (templateContext is SpecTemplate)
                    {
                        template = new SpecTemplate();
                    }
                    else
                    {
                        template = new CodeTemplate();
                    }
                    template.FilePath = (modelContext as Project).TemplateAbsolutePath;
                    template.LoadTemplateFileData(false);
                    string templateName = template.TemplateName;
                    string code         = String.Empty;
                    if (templateContext is SpecTemplate)
                    {
                        template = solutionContext.SpecTemplates[templateContext.GetTemplateKey(modelContext, templateName)] as SpecTemplate;
                    }
                    else
                    {
                        template = solutionContext.CodeTemplates[templateContext.GetTemplateKey(modelContext, templateName)] as CodeTemplate;
                    }
                }
                else
                {
                    if (templateContext is SpecTemplate)
                    {
                        template = solutionContext.SpecTemplates[templateContext.GetTemplateKey(modelContext, TemplateName)] as SpecTemplate;
                    }
                    else
                    {
                        template = solutionContext.CodeTemplates[templateContext.GetTemplateKey(modelContext, TemplateName)] as CodeTemplate;
                    }
                }

                // add parameters
                foreach (TemplateParameterNode parameter in Parameters)
                {
                    ParameterValues[parameter.VariableName] = parameter.Parameter.GetObjectValue(solutionContext, parentTemplateContext, parameterModelContext, interpreterType);
                }

                if (interpreterType == InterpreterTypeCode.Output)
                {
                    if (template != null)
                    {
                        template.GenerateOutput(solutionContext, templateContext, modelContext, appendToTemplateContext, ParameterValues);
                    }
                }
                else
                {
                    if (template != null)
                    {
                        template.GenerateContent(solutionContext, templateContext, modelContext, appendToTemplateContext, ParameterValues);
                    }
                    else
                    {
                        templateContext.ContentCodeBuilder.Append("<" + TemplateName + ">");
                        LogException(solutionContext, templateContext, modelContext, String.Format(DisplayValues.Message_TemplateNotFoundError, TemplateName, interpreterType));
                    }
                }
            }
            catch (ApplicationAbortException)
            {
                throw;
            }
            catch (System.Exception ex)
            {
                LogException(solutionContext, templateContext, modelContext, ex, interpreterType);
            }
        }
        ///--------------------------------------------------------------------------------
        /// <summary>Interpret this node to get the associated template and interpret the content and output.</summary>
        ///
        /// <param name="solutionContext">The associated solution.</param>
        /// <param name="templateContext">The associated template.</param>
        /// <param name="modelContext">The associated model context.</param>
        /// <param name="parameterModelContext">The associated model context for parameters.</param>
        ///--------------------------------------------------------------------------------
        public void InterpretContentAndOutput(Solution solutionContext, ITemplate templateContext, IDomainEnterpriseObject modelContext, IDomainEnterpriseObject parameterModelContext)
        {
            InterpreterTypeCode interpreterType = InterpreterTypeCode.Content;

            try
            {
                ITemplate template = null;
                if (TemplateName == LanguageTerms.TemplateProperty && modelContext is Project)
                {
                    if (templateContext is SpecTemplate)
                    {
                        template = new SpecTemplate();
                    }
                    else
                    {
                        template = new CodeTemplate();
                    }
                    template.FilePath = (modelContext as Project).TemplateAbsolutePath;
                    template.LoadTemplateFileData(false);
                    string templateName = template.TemplateName;
                    string code         = String.Empty;
                    if (templateContext is SpecTemplate)
                    {
                        template = solutionContext.SpecTemplates[templateContext.GetTemplateKey(modelContext, templateName)] as SpecTemplate;
                    }
                    else
                    {
                        template = solutionContext.CodeTemplates[templateContext.GetTemplateKey(modelContext, templateName)] as CodeTemplate;
                    }
                }
                else
                {
                    if (templateContext is SpecTemplate)
                    {
                        template = solutionContext.SpecTemplates[templateContext.GetTemplateKey(modelContext, TemplateName)] as SpecTemplate;
                    }
                    else
                    {
                        template = solutionContext.CodeTemplates[templateContext.GetTemplateKey(modelContext, TemplateName)] as CodeTemplate;
                    }
                }
                if (template != null)
                {
                    template.MessageBuilder.Clear();
                    template.PopCount = 0;
                    template.PushModelContext(modelContext);
                    template.ContentCodeBuilder.Clear();
                    template.CurrentTabIndent = templateContext.CurrentTabIndent;
                    InterpretNode(interpreterType, solutionContext, template, templateContext, modelContext, parameterModelContext, false);
                    template.PopCount = 0;
                    template.PushModelContext(modelContext);
                    template.OutputCodeBuilder.Clear();
                    template.CurrentTabIndent = templateContext.CurrentTabIndent;
                    interpreterType           = InterpreterTypeCode.Output;
                    InterpretNode(interpreterType, solutionContext, template, templateContext, modelContext, parameterModelContext, false);
                    templateContext.AddToTemplateCalls(template);
                    template.AddToTemplateCalledBy(templateContext);
                    if (ParameterValues.Count > 0)
                    {
                        int    parameterCount = 0;
                        string parameters     = String.Empty;
                        foreach (string parameter in ParameterValues.AllKeys)
                        {
                            if (parameterCount > 0)
                            {
                                parameters += ", ";
                            }
                            parameters += parameter;
                            parameterCount++;
                        }
                        if (parameterCount > 1)
                        {
                            LogException(solutionContext, templateContext, modelContext, String.Format(DisplayValues.Message_TemplateParametersNotFoundError, parameters, TemplateName), interpreterType);
                        }
                        else
                        {
                            LogException(solutionContext, templateContext, modelContext, String.Format(DisplayValues.Message_TemplateParameterNotFoundError, parameters, TemplateName), interpreterType);
                        }
                    }
                    if (solutionContext.IsSampleMode == true)
                    {
                        templateContext.MessageBuilder.Append(template.MessageBuilder.ToString());
                    }
                }
                else
                {
                    LogException(solutionContext, templateContext, modelContext, String.Format(DisplayValues.Message_TemplateNotFoundError, TemplateName), interpreterType);
                }
            }
            catch (ApplicationAbortException)
            {
                throw;
            }
            catch (System.Exception ex)
            {
                LogException(solutionContext, templateContext, modelContext, ex, interpreterType);
            }
        }
        ///--------------------------------------------------------------------------------
        /// <summary>This method gets the content for a watch expression.</summary>
        ///
        /// <param name="watchExpression">Expression to evaluate.</param>
        /// <param name="parentModelContext">The parent model context from which to generate code.</param>
        ///
        /// <returns>A string representing the generated code for the watch expression.</returns>
        ///--------------------------------------------------------------------------------
        public string GetWatchContent(string watchExpression, IDomainEnterpriseObject parentModelContext)
        {
            try
            {
                CodeTemplate template = Solution.CodeTemplates[TemplateKey] as CodeTemplate;
                if (template == null)
                {
                    return(String.Empty);
                }

                // handle special cases
                if (String.IsNullOrEmpty(watchExpression))
                {
                    return(String.Empty);
                }
                if (watchExpression == LanguageTerms.TextProperty)
                {
                    return(template.ContentCodeBuilder.ToString());
                }
                if (watchExpression == LanguageTerms.PathProperty)
                {
                    return(template.OutputCodeBuilder.ToString());
                }

                // create temporary template
                CodeTemplate watchTemplate = new CodeTemplate();
                watchTemplate.Solution        = Solution;
                watchTemplate.NodeName        = parentModelContext.GetType().Name;
                watchTemplate.IsWatchTemplate = true;

                // wrap input expression into a template with a single property
                watchTemplate.TemplateContent = LanguageTerms.PropOpenTag + watchExpression + LanguageTerms.CloseTag;

                // push parameters and variables onto watch template
                if (template != null)
                {
                    foreach (string key in template.Parameters.AllKeys)
                    {
                        watchTemplate.Parameters[key] = template.Parameters[key];
                    }
                    foreach (string key in template.Variables.AllKeys)
                    {
                        watchTemplate.Variables[key] = template.Variables[key];
                    }
                }

                // push template context stack onto watch template as needed
                if (template != null && template.ModelContextStack.Count > 1)
                {
                    for (int i = template.ModelContextStack.Count - 1; i > 0; i--)
                    {
                        watchTemplate.PushModelContext(template.ModelContextStack[i]);
                    }
                }

                // get expression value
                string watchValue = watchTemplate.GetContent(parentModelContext, watchExpression);
                if (watchTemplate.HasErrors == true)
                {
                    watchValue = DisplayValues.Exception_WatchExpression;
                }
                return(watchValue);
            }
            catch (ApplicationAbortException ex)
            {
                return(ex.Message);
            }
            catch (System.Exception ex)
            {
                return(ex.Message);
            }
        }