public TemplateProcessingService()
        {
            InternalContext = new TextTemplateProcessingContext();

            InitializeDefaultFunctions();
            InitializeDefaultSubstitutions();
        }
        public string ProcessTemplate(Template template, TextTemplateProcessingContext context = null)
        {
            if (context != null)
            {
                // make sure provided context has access to all default substitutions
                foreach (var sub in InternalContext.Substitutions)
                {
                    context.Substitutions.AddOrUpdateSubstitution(sub);
                }

                // make sure provided context has access to all default functions
                foreach (var function in InternalContext.Functions)
                {
                    if (!context.Functions.Contains(function))
                        context.Functions.AddFunction(function);
                }
            }

            var sb = new StringBuilder(template.RawPattern);

            var placeholders = template.GetPlaceholders();

            for (int i = placeholders.Count - 1; i >= 0; i--)
            {
                var ph = placeholders[i];

                object value = null;

                if (context != null && ph.TryEvaluate(context, out value))
                {
                    sb.Replace(ph.RawValue, value.ToString(valueWhenNull: "[NULL]", valueWhenEmpty: ""), ph.StartIndex, ph.Length);
                }
                else if (ph.TryEvaluate(InternalContext, out value))
                {
                    sb.Replace(ph.RawValue, value.ToString(valueWhenNull: "[NULL]", valueWhenEmpty: ""), ph.StartIndex, ph.Length);
                }
                else
                {
                    Diagnostics.Log.Warning(() => "Unable to process placeholder '{0}'".FormatWith(ph.RawValue));
                    sb.Replace(ph.RawValue, "");
                }
            }

            return sb.ToString();
        }
        public string Format(Entities.DiagnosticEvent de, TypeDescriptorCollection typeDescriptorCollection)
        {
            var context = new TextTemplateProcessingContext();

            foreach (var property in de.Properties)
            {
                var prop = property;

                context.Substitutions.AddOrUpdateSubstitution(
                    property.UniqueName,
                    (cx) =>
                    {
                        return prop.Value;
                    });
            }

            var txt = TextTemplateProcessingServce.ProcessTemplate(Template, context);

            return txt.ExpandTabs();
        }
        public string ProcessTemplate(string templateText, TextTemplateProcessingContext context = null)
        {
            var template = Template.FromText(templateText);

            return ProcessTemplate(template, context);
        }