/// <summary>
        /// Generates the Jekyll output from the specified <see cref="Feed"/> using XSLT.
        /// </summary>
        /// <param name="feed">The feed.</param>
        /// <param name="outputRootPath">The ouput root path.</param>
        /// <param name="fileType">Type of the file.</param>
        public void GenerateOutput(Feed feed, string outputRootPath = DefaultOutputPath, string fileType = ".html")
        {
            feed.CheckNull("feed");

            if (string.IsNullOrEmpty(outputRootPath))
            {
                outputRootPath = DefaultOutputPath;
            }

            Log.Info("Processing posts from imported feed.");
            Log.InfoFormat("There are {0} posts total.", feed.Posts.Count);
            Log.InfoFormat("Output root path is {0}.", outputRootPath);
            Log.InfoFormat("Expected XSLT output format is {0}.", fileType);

            ProcessPosts(feed.Posts, outputRootPath, fileType);

            Log.Info("Processing posts from imported feed complete.");
        }
        /// <summary>
        /// Matches settings entries, if they exist.
        /// </summary>
        /// <param name="feed">The feed.</param>
        private void ProcessSettings(Feed feed)
        {
            Debug.Assert(null != feed);
            Debug.Assert(null != feed.Posts);

            List<Entry> settings = feed.Posts.Where(entry => entry.Type == EntryType.Settings || entry.Type == EntryType.Layout).ToList();
            foreach (Entry page in settings)
            {
                feed.Settings.Add(page);
                feed.Posts.Remove(page);
            }

            Log.InfoFormat("{0} settings entries were processed", feed.Settings);
        }
        /// <summary>
        /// Matches comments to the specified post, if they exist.
        /// </summary>
        /// <param name="feed">The feed.</param>
        private void ProcessComments(Feed feed)
        {
            Debug.Assert(null != feed);
            Debug.Assert(null != feed.Posts);

            List<Entry> allPosts = feed.Posts.Where(entry => entry.Type == EntryType.Post).ToList();
            foreach (Entry postEntry in allPosts)
            {
                if (feed.Posts.Count == 0)
                {
                    // this shouldn't happen, but if it does, there's nothing to do
                    Log.Warn("No entries were available to match.");
                    return;
                }

                int ct = 0;

                // metadata will contain thr:in-reply-to tag; the ref of this tag is the id of the post
                List<Entry> allComments = feed.Posts.Where(entry => entry.Type == EntryType.Comment).ToList();
                foreach (Entry possibleMatch in allComments)
                {
                    if (null != possibleMatch.Metadata)
                    {
                        XmlElement commentNode = possibleMatch.Metadata.Where(node => node.LocalName == "in-reply-to").FirstOrDefault();
                        if (null != commentNode)
                        {
                            string relatedPostId = commentNode.GetAttribute("ref");
                            if (!string.IsNullOrEmpty(relatedPostId) && relatedPostId == postEntry.Id)
                            {
                                // it's a match!
                                postEntry.Comments.Add(possibleMatch);
                                feed.Posts.Remove(possibleMatch); // prune it
                                ct++;
                            }
                        }
                    }
                }

                Log.InfoFormat("{0} comments were matched to the post having id {1}", ct, postEntry.Id);
            }
        }
        /// <summary>
        /// Matches page entries, if they exist.
        /// </summary>
        /// <param name="feed">The feed.</param>
        private void ProcessPages(Feed feed)
        {
            Debug.Assert(null != feed);
            Debug.Assert(null != feed.Posts);

            List<Entry> pages = feed.Posts.Where(entry => entry.Type == EntryType.Page).ToList();
            foreach (Entry page in pages)
            {
                feed.Pages.Add(page);
                feed.Posts.Remove(page);
            }

            Log.InfoFormat("{0} page entries were processed", feed.Pages);
        }