public PatternFormatter()
        {
            Pattern = "{Event.Message}";

            TextTemplateProcessingServce = new TemplateProcessingService();
            TextTemplateProcessingServce.InternalContext.Functions.AddFunction(
                new Function(
                    "dump", 
                    (originalValue, input, parameters) => 
                    {
                        return input.DumpToString();
                    }));
            TextTemplateProcessingServce.InternalContext.Functions.AddFunction(
                new Function(
                    "dumpHtml",
                    (originalValue, input, parameters) =>
                    {
                        return input.DumpToHtml();
                    }));

            TextTemplateProcessingServce.InternalContext.Functions.AddFunction(
                new Function(
                    "dumpWithHeader",
                    (originalValue, input, parameters) =>
                    {
                        //# first describe the input
                        var inputKvpc = TypeDescriptors.Describe(input);

                        //# add KVP with header as key and input as value
                        var kvp = new KeyValuePair(parameters.First().ToString().Trim(new char[] { '\'' }),  inputKvpc);
                        
                        var result = new StringObjectWriter().Write(kvp);

                        return result;
                    }));
        }
        public void Write__KeyValuePair_ValueMultiLineString()
        {
            var ow = new StringObjectWriter();

            var kvp = new KeyValuePair("_key_", "_line1_" + Environment.NewLine + "_line2_");

            var r = ow.Write(kvp);

            var expected =
                  "_key_\t:"
                + Environment.NewLine
                + "---------"
                + Environment.NewLine
                + "\t_line1_"
                + Environment.NewLine
                + "\t_line2_";

            Assert.AreEqual(expected, r);
        }
        string Process(
            KeyValuePair kvp,
            string nullValue,
            string emptyValue)
        {
            var valString = Write(kvp.Value, nullValue, emptyValue);

            if (kvp.Value is KeyValuePairCollection || valString.IsMultiLine())
            {
                // start on a new line
                // separator '--' from start of a key to end of a key
                // indent all lines by one '\t';

                // e.g.
                //  Stack Trace  :
                //  --------------
                //      line_one_goes_here
                //      line_two_goes_here

                var sb = new StringBuilder();

                var keyStr = "{0}\t:".FormatWith(kvp.Key);

                var keyStrLen = keyStr.GetLengthWithExpandedTabs(TabSize);

                //# do not write key if it's empty
                if (kvp.Key != "")
                {
                    sb.Append(keyStr);
                    sb.AppendLine();
                    sb.Append(new string('-', keyStrLen));
                    sb.AppendLine();
                }

                var lines = valString.GetLines();

                for (int i = 0; i < lines.Length; i++)
                {
                    sb.Append("\t" + lines[i]);

                    if (i < lines.Length - 1)
                        sb.AppendLine();
                }

                return sb.ToString();

            }
            else
            {
                return "{0}\t:\t{1}".FormatWith(kvp.Key, valString);
            }
        }
        public void Write__KeyValuePair_ValueIsSingleLineString()
        {
            var ow = new StringObjectWriter();

            var kvp = new KeyValuePair("_key_", "_value_");

            var r = ow.Write(kvp);

            Assert.AreEqual("_key_\t:\t_value_", r);
        }