internal void OnPageSave(string key, IPage currentPage, RavenJObject metadata)
        {
            using (IDocumentSession session = DocumentStore.OpenSession())
            {
                var trie = session.Load <Trie>(TrieId);

                if (trie.RootNode == null)
                {
                    trie.RootNode = new TrieNode
                    {
                        PageId = key
                    };
                }
                else
                {
                    TrieNode[] nodes = trie.RootNode.Flatten(n => n.Children).ToArray();

                    TrieNode parent = currentPage.Parent != null
                        ? nodes.SingleOrDefault(
                        n =>
                        String.Equals(n.PageId, currentPage.Parent.Id, StringComparison.CurrentCultureIgnoreCase))
                        : null;

                    if (parent != null)
                    {
                        currentPage.Metadata.Slug = Slug.CreateSlug(currentPage);
                        currentPage.Metadata.Url  = currentPage.Metadata.Slug.Insert(0,
                                                                                     VirtualPathUtility.AppendTrailingSlash(parent.Url ?? ""));

                        if (parent.Children.All(n => n.PageId != key.Replace("/draft", "")))
                        {
                            parent.Children.Add(new TrieNode
                            {
                                PageId   = key.Replace("/draft", ""),
                                ParentId = parent.PageId,
                                Url      = currentPage.Metadata.Url
                            });
                        }
                    }
                }

                session.SaveChanges();
            }
        }
        /// <summary>
        ///     Called when [page publish].
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="currentPage">The current page.</param>
        /// <param name="metadata">The metadata.</param>
        internal void OnPagePublish(string key, IPage currentPage, RavenJObject metadata)
        {
            using (IDocumentSession session = DocumentStore.OpenSession())
            {
                var trie = session.Load <Trie>(TrieId);

                if (trie.RootNode == null)
                {
                    trie.RootNode = new TrieNode
                    {
                        PageId = key.Replace("/draft", "")
                    };
                }
                else
                {
                    TrieNode[] nodes = trie.RootNode.Flatten(n => n.Children).ToArray();

                    TrieNode parentNode = currentPage.Parent != null
                        ? nodes.SingleOrDefault(n => n.PageId.CompareToIgnoreDraftId(currentPage.Parent.Id))
                        : null;

                    TrieNode currentNode = nodes.SingleOrDefault(n => n.PageId.CompareToIgnoreDraftId(key));

                    if (currentNode != null)
                    {
                        if (parentNode != null)
                        {
                            currentPage.Metadata.Slug = Slug.CreateSlug(currentPage);

                            currentPage.Metadata.Url = currentPage.Metadata.Slug.Insert(0,
                                                                                        VirtualPathUtility.AppendTrailingSlash(parentNode.Url ?? ""));

                            // the currentPage has been moved so we are moving the node and rewrites the url for all child pages and the current node
                            if (parentNode.ParentId != currentPage.Parent.Id)
                            {
                                trie.MoveTo(parentNode, currentNode);

                                IEnumerable <string> ids = currentNode.Flatten(x => x.Children).Select(x => x.PageId);
                                IPage[] pages            = session.Load <IPage>(ids);
                                pages.ForEach(p => { p.Metadata.Url = trie.Get(p.Id).Url; });
                            }

                            currentNode.Url = currentPage.Metadata.Url;
                        }
                    }
                    else if (parentNode != null)
                    {
                        if (parentNode.Children.All(n => n.PageId != key.Replace("/draft", "")))
                        {
                            currentPage.Metadata.Slug = Slug.CreateSlug(currentPage);

                            currentPage.Metadata.Url = currentPage.Metadata.Slug.Insert(0,
                                                                                        VirtualPathUtility.AppendTrailingSlash(parentNode.Url ?? ""));

                            parentNode.Children.Add(new TrieNode
                            {
                                PageId   = key.Replace("/draft", ""),
                                ParentId = parentNode.PageId,
                                Url      = currentPage.Metadata.Url
                            });
                        }
                    }
                }

                // Clean up any existing draft for this page
                if (session.Advanced.DocumentStore.Exists(key + "/draft"))
                {
                    var draft = session.Load <IPage>(key + "/draft");
                    session.Delete(draft);
                }

                session.SaveChanges();
            }
        }