/// <summary>
        /// Render messages tag.
        /// </summary>
        /// <returns></returns>
        public StringBuilder RenderMessages()
        {
            StringBuilder output = new StringBuilder();

            var messageStore = FeedbackMessageStore.Current;

            foreach (var messages in messageStore.Messages)
            {
                if (messages.Value.Count == 0)
                {
                    continue;
                }

                FeedbackMessageAttributeCollection outerAttrs;
                if (PerLevelOuterTagAttributes.ContainsKey(messages.Key))
                {
                    outerAttrs = OuterTagAttributes.Merge(PerLevelOuterTagAttributes[messages.Key]);
                }
                else
                {
                    outerAttrs = new FeedbackMessageAttributeCollection(OuterTagAttributes);
                }

                outerAttrs.AppendAttribute("class", $"feedback-{ messages.Key.ToString().ToLower() }");


                FeedbackMessageAttributeCollection innerAttrs;
                if (PerLevelInnerTagAttributes.ContainsKey(messages.Key))
                {
                    innerAttrs = InnerTagAttributes.Merge(PerLevelInnerTagAttributes[messages.Key]);
                }
                else
                {
                    innerAttrs = new FeedbackMessageAttributeCollection(InnerTagAttributes);
                }


                output.Append($"<{OuterTagName} {outerAttrs.Build().ToString()}>");

                foreach (var msg in messages.Value)
                {
                    output.Append($"<{InnerTagName} {innerAttrs.Build().ToString()}>");

                    string message = StringConverter.Convert(msg);
                    output.Append(EscapeMessage ? System.Web.HttpUtility.HtmlEncode(message) : message);
                    output.Append($"</{InnerTagName}>");
                    msg.MarkRendered();
                }

                output.Append($"</{OuterTagName}>");
            }

            return(output);
        }
        /// <summary>
        /// Appends attribute value to outer tag.
        /// </summary>
        /// <param name="level"></param>
        /// <param name="key"></param>
        /// <param name="attrValue"></param>
        /// <returns></returns>
        public FeedbackMessageRenderer AppendOuterAttributeValue(FeedbackMessageLevel level, string key, string attrValue)
        {
            FeedbackMessageAttributeCollection attrCollection;

            if (PerLevelOuterTagAttributes.ContainsKey(level))
            {
                attrCollection = PerLevelOuterTagAttributes[level];
            }
            else
            {
                attrCollection = new FeedbackMessageAttributeCollection();
                PerLevelOuterTagAttributes[level] = attrCollection;
            }

            attrCollection.AppendAttribute(key, attrValue);
            return(this);
        }
        /// <summary>
        /// Merges attributes. Create new one.
        /// </summary>
        /// <param name="attrCollection"></param>
        /// <returns></returns>
        public FeedbackMessageAttributeCollection Merge(FeedbackMessageAttributeCollection attrCollection)
        {
            var newAttrCollection = new FeedbackMessageAttributeCollection(attrCollection);

            foreach (var attrEntry in this)
            {
                if (newAttrCollection.ContainsKey(attrEntry.Key))
                {
                    var set = newAttrCollection[attrEntry.Key];
                    foreach (var attr in attrEntry.Value)
                    {
                        set.Add(attr);
                    }
                }
                else
                {
                    newAttrCollection[attrEntry.Key] = new HashSet <string>(attrEntry.Value);
                }
            }

            return(newAttrCollection);
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="attrCollection"></param>
 public FeedbackMessageAttributeCollection(FeedbackMessageAttributeCollection attrCollection) : base(attrCollection)
 {
 }