/// <summary>
        /// Processes HTML input and returns it with inline content items replaced with resolvers output.
        /// </summary>
        /// <param name="value">HTML code</param>
        /// <param name="inlineContentItemMap">Content items referenced as inline content items</param>
        /// <returns>HTML with inline content items replaced with resolvers output</returns>
        public string Process(string value, Dictionary <string, object> inlineContentItemMap)
        {
            var document = _htmlParser.Parse(value);
            var inlineContentItemElements = GetInlineContentItemElements(document);

            foreach (var inlineContentItemElement in inlineContentItemElements)
            {
                object inlineContentItem;
                var    contentItemCodename = inlineContentItemElement.GetAttribute("data-codename");
                if (inlineContentItemMap.TryGetValue(contentItemCodename, out inlineContentItem))
                {
                    string fragmentText;
                    Type   inlineContentItemType;
                    var    unretrieved = inlineContentItem as UnretrievedContentItem;
                    if (unretrieved != null)
                    {
                        inlineContentItemType = typeof(UnretrievedContentItem);
                        var data = new ResolvedContentItemData <UnretrievedContentItem> {
                            Item = unretrieved
                        };
                        fragmentText = _unretrievedInlineContentItemsResolver.Resolve(data);
                    }
                    else
                    {
                        inlineContentItemType = inlineContentItem.GetType();
                        Func <object, string> inlineContentItemResolver;
                        if (_typeResolver.TryGetValue(inlineContentItemType, out inlineContentItemResolver))
                        {
                            fragmentText = inlineContentItemResolver(inlineContentItem);
                        }
                        else
                        {
                            var data = new ResolvedContentItemData <object> {
                                Item = inlineContentItem
                            };
                            fragmentText = DefaultResolver.Resolve(data);
                        }
                    }

                    try
                    {
                        var fragmentNodes = _strictHtmlParser.ParseFragment(fragmentText, inlineContentItemElement.ParentElement);
                        inlineContentItemElement.Replace(fragmentNodes.ToArray());
                    }
                    catch (HtmlParseException exception)
                    {
                        var errorNode = document.CreateTextNode($"[Inline content item resolver provided an invalid HTML 5 fragment ({exception.Position.Line}:{exception.Position.Column}). Please check the output for a content item {contentItemCodename} of type {inlineContentItemType}.]");
                        inlineContentItemElement.Replace(errorNode);
                    }
                }
            }

            return(document.Body.InnerHtml);
        }
        /// <summary>
        /// Processes HTML input and returns it with inline content items replaced with resolvers output.
        /// </summary>
        /// <param name="value">HTML code</param>
        /// <param name="usedContentItems">Content items referenced as inline content items</param>
        /// <returns>HTML with inline content items replaced with resolvers output</returns>
        public string Process(string value, Dictionary <string, object> usedContentItems)
        {
            object processedContentItem;
            var    htmlInput = new HtmlParser().Parse(value);

            var inlineContentItems = GetContentItemsFromHtml(htmlInput);

            foreach (var contentItems in inlineContentItems)
            {
                var codename    = contentItems.GetAttribute("data-codename");
                var wasResolved = usedContentItems.TryGetValue(codename, out processedContentItem);
                if (wasResolved)
                {
                    string replacement;
                    Type   contentType;
                    var    unretrieved = processedContentItem as UnretrievedContentItem;
                    if (unretrieved != null)
                    {
                        contentType = typeof(UnretrievedContentItem);
                        var data = new ResolvedContentItemData <UnretrievedContentItem> {
                            Item = unretrieved
                        };
                        replacement = _unretrievedInlineContentItemsResolver.Resolve(data);
                    }
                    else
                    {
                        contentType = processedContentItem.GetType();
                        Func <object, string> resolver;
                        if (_typeResolver.TryGetValue(contentType, out resolver))
                        {
                            replacement = resolver(processedContentItem);
                        }
                        else
                        {
                            var data = new ResolvedContentItemData <object> {
                                Item = processedContentItem
                            };
                            replacement = DefaultResolver.Resolve(data);
                        }
                    }

                    try
                    {
                        var options = new HtmlParserOptions()
                        {
                            IsStrictMode = true
                        };
                        var docs = new HtmlParser(options).ParseFragment(replacement, contentItems);
                        contentItems.Replace(docs.ToArray());
                    }
                    catch (HtmlParseException exception)
                    {
                        var textNodeWithError =
                            htmlInput.CreateTextNode($"Error while parsing resolvers output for content type {contentType}, codename {codename} at line {exception.Position.Line}, column {exception.Position.Column}.");
                        contentItems.Replace(textNodeWithError);
                    }
                }
            }

            return(htmlInput.Body.InnerHtml);
        }