Example #1
0
        /// <summary>
        /// Appends a breadbrumb trail element.
        /// </summary>
        /// <param name="sb">The destination <see cref="T:StringBuilder" />.</param>
        /// <param name="page">The page to append.</param>
        /// <param name="dpPrefix">The drop-down menu ID prefix.</param>
        private void AppendBreadcrumb(StringBuilder sb, PageInfo page, string dpPrefix)
        {
            PageNameComparer comp = new PageNameComparer();
            PageContent      pc   = Content.GetPageContent(page, true);

            string id = AppendBreadcrumbDropDown(sb, page, dpPrefix);

            string nspace = NameTools.GetNamespace(page.FullName);

            sb.Append("&raquo; ");
            if (comp.Compare(page, currentPage) == 0)
            {
                sb.Append("<b>");
            }

            sb.AppendFormat(@"<a href=""{0}"" title=""{1}""{2}{3}{4}>{1}</a>",
                            Tools.UrlEncode(page.FullName) + Settings.PageExtension,
                            FormattingPipeline.PrepareTitle(pc.Title, false, FormattingContext.PageContent, currentPage) + (string.IsNullOrEmpty(nspace) ? "" : (" (" + NameTools.GetNamespace(page.FullName) + ")")),
                            (id != null ? @" onmouseover=""javascript:return __ShowDropDown(event, '" + id + @"', this);""" : ""),
                            (id != null ? @" id=""lnk" + id + @"""" : ""),
                            (id != null ? @" onmouseout=""javascript:return __HideDropDown('" + id + @"');""" : ""));
            if (comp.Compare(page, currentPage) == 0)
            {
                sb.Append("</b>");
            }

            sb.Append(" ");
        }
Example #2
0
        /// <summary>
        /// Searches for pages with name or title similar to a specified value.
        /// </summary>
        /// <param name="wiki">The wiki.</param>
        /// <param name="name">The name to look for (<c>null</c> for the root).</param>
        /// <param name="nspace">The namespace to search into.</param>
        /// <returns>The similar pages, if any.</returns>
        public static PageContent[] SearchSimilarPages(string wiki, string name, string nspace)
        {
            if (string.IsNullOrEmpty(nspace))
            {
                nspace = null;
            }

            var searchFields = new [] { SearchField.PageFullName };
            List <SearchResult> searchResults = Search(wiki, searchFields, name, SearchOptions.AtLeastOneWord);

            var result = new List <PageContent>(20);

            foreach (SearchResult res in searchResults)
            {
                var pageDoc = res.Document as PageDocument;
                if (pageDoc != null)
                {
                    string pageNamespace = NameTools.GetNamespace(pageDoc.PageFullName);
                    if (string.IsNullOrEmpty(pageNamespace))
                    {
                        pageNamespace = null;
                    }

                    if (pageNamespace == nspace)
                    {
                        var page = new PageContent(pageDoc.PageFullName, null, new DateTime(), pageDoc.Title, null, new DateTime(), null, pageDoc.Content, null, null);
                        result.Add(page);
                    }
                }
            }

            // Search page names for matches
            List <PageContent> allPages = Pages.GetPages(wiki, Pages.FindNamespace(wiki, nspace));
            var    comp        = new PageNameComparer();
            string currentName = name.ToLowerInvariant();

            foreach (PageContent page in allPages)
            {
                if (NameTools.GetLocalName(page.FullName).ToLowerInvariant().Contains(currentName))
                {
                    if (result.Find(p => comp.Compare(p, page) == 0) == null)
                    {
                        result.Add(page);
                    }
                }
            }

            return(result.ToArray());
        }
Example #3
0
        /// <summary>
        /// Searches for pages with name or title similar to a specified value.
        /// </summary>
        /// <param name="name">The name to look for (<c>null</c> for the root).</param>
        /// <param name="nspace">The namespace to search into.</param>
        /// <returns>The similar pages, if any.</returns>
        public static PageInfo[] SearchSimilarPages(string name, string nspace)
        {
            if (string.IsNullOrEmpty(nspace))
            {
                nspace = null;
            }

            SearchResultCollection searchResults = Search(name, false, false, SearchOptions.AtLeastOneWord);

            var result = new List <PageInfo>(20);

            foreach (SearchResult res in searchResults)
            {
                var pageDoc = res.Document as PageDocument;
                if (pageDoc != null)
                {
                    var pageNamespace = NameTools.GetNamespace(pageDoc.PageInfo.FullName);
                    if (string.IsNullOrEmpty(pageNamespace))
                    {
                        pageNamespace = null;
                    }

                    if (pageNamespace == nspace)
                    {
                        result.Add(pageDoc.PageInfo);
                    }
                }
            }

            // Search page names for matches
            List <PageInfo> allPages    = Pages.GetPages(Pages.FindNamespace(nspace));
            var             comp        = new PageNameComparer();
            var             currentName = name.ToLowerInvariant();

            foreach (PageInfo page in allPages)
            {
                if (NameTools.GetLocalName(page.FullName).ToLowerInvariant().Contains(currentName))
                {
                    if (result.Find(delegate(PageInfo p) { return(comp.Compare(p, page) == 0); }) == null)
                    {
                        result.Add(page);
                    }
                }
            }

            return(result.ToArray());
        }
        /// <summary>
        /// Finds a page by name.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <returns>The index in the collection.</returns>
        private int FindPage(PageInfo page)
        {
            lock (this) {
                if (pages == null || pages.Count == 0)
                {
                    return(-1);
                }

                PageNameComparer comp = new PageNameComparer();
                for (int i = 0; i < pages.Count; i++)
                {
                    if (comp.Compare(pages[i], page) == 0)
                    {
                        return(i);
                    }
                }

                return(-1);
            }
        }
Example #5
0
        /// <summary>
        /// Finds a page by name.
        /// </summary>
        /// <param name="pageFullName">The page full name.</param>
        /// <returns>The index in the collection.</returns>
        private int FindPage(string pageFullName)
        {
            lock (this) {
                if (pages == null || pages.Count == 0)
                {
                    return(-1);
                }

                PageNameComparer comp = new PageNameComparer();
                for (int i = 0; i < pages.Count; i++)
                {
                    if (pages[i] == pageFullName)
                    {
                        return(i);
                    }
                }

                return(-1);
            }
        }
Example #6
0
        /// <summary>
        /// Finds a page by name.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <returns>The index in the collection.</returns>
        private int FindPage(PageInfo page)
        {
            lock (this)
            {
                if (pageFullNames.Count == 0)
                {
                    return(-1);
                }

                var comp = new PageNameComparer();

                for (var i = 0; i < pageFullNames.Count; i++)
                {
                    if (string.Equals(pageFullNames[i], page.FullName, System.StringComparison.OrdinalIgnoreCase))
                    {
                        return(i);
                    }
                }

                return(-1);
            }
        }
Example #7
0
        private void bindPageNameData(bool sort)
        {
            CustomGenericList <PageName> pageNames = (CustomGenericList <PageName>)Session["PageNames" + pageIdTextBox.Text];

            // filter out deleted items
            CustomGenericList <PageName> pns = new CustomGenericList <PageName>();

            foreach (PageName pn in pageNames)
            {
                if (pn.IsDeleted == false)
                {
                    pns.Add(pn);
                }
            }
            if (sort)
            {
                PageNameComparer comp = new PageNameComparer((PageNameComparer.CompareEnum)_sortColumn, _sortOrder);
                pns.Sort(comp);
            }
            pageNameList.DataSource = pns;
            pageNameList.DataBind();
        }
        /// <summary>
        /// Gets all the categories of a page.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <returns>The categories, sorted by name.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="page"/> is <c>null</c>.</exception>
        public CategoryInfo[] GetCategoriesForPage(PageInfo page)
        {
            if(page == null) throw new ArgumentNullException("page");

            string pageNamespace = NameTools.GetNamespace(page.FullName);
            CategoryInfo[] categories = GetCategories(FindNamespace(pageNamespace, GetNamespaces())); // Sorted

            List<CategoryInfo> result = new List<CategoryInfo>(10);

            PageNameComparer comp = new PageNameComparer();
            foreach(CategoryInfo cat in categories) {
                foreach(string p in cat.Pages) {
                    if(comp.Compare(page, new PageInfo(p, this, DateTime.Now)) == 0) {
                        result.Add(cat);
                        break;
                    }
                }
            }

            return result.ToArray();
        }
 /// <summary>
 /// Finds a corresponding instance of <see cref="T:LocalPageInfo" /> in the available pages.
 /// </summary>
 /// <param name="page">The instance of <see cref="T:PageInfo" /> to "convert" to <see cref="T:LocalPageInfo" />.</param>
 /// <returns>The instance of <see cref="T:LocalPageInfo" />, or <c>null</c>.</returns>
 private LocalPageInfo LoadLocalPageInfo(PageInfo page)
 {
     if(page == null) return null;
     lock(this) {
         PageInfo[] pages = GetAllPages();
         PageNameComparer comp = new PageNameComparer();
         for(int i = 0; i < pages.Length; i++) {
             if(comp.Compare(pages[i], page) == 0) return pages[i] as LocalPageInfo;
         }
     }
     return null;
 }
 /// <summary>
 /// Determines whether a page exists.
 /// </summary>
 /// <param name="page">The instance of <see cref="T:PageInfo" /> to look for.</param>
 /// <returns><c>true</c> if the page exists, <c>false</c> otherwise.</returns>
 private bool PageExists(PageInfo page)
 {
     lock(this) {
         PageInfo[] pages = GetAllPages();
         PageNameComparer comp = new PageNameComparer();
         for(int i = 0; i < pages.Length; i++) {
             if(comp.Compare(pages[i], page) == 0) return true;
         }
     }
     return false;
 }
        /// <summary>
        /// Renames a Page.
        /// </summary>
        /// <param name="page">The Page to rename.</param>
        /// <param name="newName">The new Name.</param>
        /// <returns>True if the Page has been renamed successfully.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="page"/> or <paramref name="newName"/> are <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <paramref name="newName"/> is empty.</exception>
        public PageInfo RenamePage(PageInfo page, string newName)
        {
            if(page == null) throw new ArgumentNullException("page");
            if(newName == null) throw new ArgumentNullException("newName");
            if(newName.Length == 0) throw new ArgumentException("New Name cannot be empty", "newName");

            lock(this) {
                if(PageExists(new PageInfo(NameTools.GetFullName(NameTools.GetNamespace(page.FullName), newName), this, DateTime.Now))) return null;

                NamespaceInfo currentNs = FindNamespace(NameTools.GetNamespace(page.FullName), GetNamespaces());
                if(currentNs != null && currentNs.DefaultPage != null) {
                    // Cannot rename the default page
                    if(new PageNameComparer().Compare(currentNs.DefaultPage, page) == 0) return null;
                }

                PageInfo[] pgs = GetAllPages();
                PageNameComparer comp = new PageNameComparer();

                // Store page's categories for rebinding with new page
                CategoryInfo[] tmp = GetCategoriesForPage(page);
                string[] cats = new string[tmp.Length];
                for(int i = 0; i < tmp.Length; i++) {
                    cats[i] = tmp[i].FullName;
                }
                // Remove all bindings for old page
                RebindPage(page, new string[0]);

                // Find page and rename files
                for(int i = 0; i < pgs.Length; i++) {
                    if(comp.Compare(pgs[i], page) == 0) {

                        LocalPageInfo local = pgs[i] as LocalPageInfo;

                        PageContent oldContent = GetContent(page);

                        Message[] messages = GetMessages(local);

                        // Update search engine index
                        UnindexPage(oldContent);
                        foreach(Message msg in messages) {
                            UnindexMessageTree(local, msg);
                        }

                        string oldFullName = local.FullName;
                        local.FullName = NameTools.GetFullName(NameTools.GetNamespace(local.FullName), newName);

                        string newFile = GetNamespacePartialPathForPageContent(NameTools.GetNamespace(local.FullName)) + newName +
                            Path.GetExtension(local.File);

                        // Rename content file
                        string oldLocalName = local.File;
                        string oldFullPath = GetFullPathForPageContent(local.File);
                        string newFullPath = GetFullPathForPageContent(newFile);
                        File.Move(oldFullPath, newFullPath);

                        // Rename messages file
                        if(File.Exists(GetFullPathForMessages(oldLocalName))) {
                            File.Move(GetFullPathForMessages(oldLocalName), GetFullPathForMessages(newFile));
                        }

                        // Rename draft file, if any
                        string oldDraftFullPath = GetDraftFullPath(local);
                        if(File.Exists(oldDraftFullPath)) {
                            string newDraftFullPath = GetDraftFullPath(new LocalPageInfo(local.FullName, this, local.CreationDateTime, newFile));

                            File.Move(oldDraftFullPath, newDraftFullPath);
                        }

                        // Rename all backups, store new page list on disk
                        // and rebind new page with old categories
                        RenameBackups(new LocalPageInfo(oldFullName, this, local.CreationDateTime, oldLocalName), newName);

                        // Set new filename (local references an element in the pgs array)
                        local.File = newFile;

                        DumpPages(pgs);
                        // Clear internal cache
                        categoriesCache = null;
                        pagesCache = null;
                        // Re-bind page with previously saved categories
                        RebindPage(local, cats);

                        // Update search engine index
                        IndexPage(new PageContent(local, oldContent.Title, oldContent.User, oldContent.LastModified, oldContent.Comment,
                            oldContent.Content, oldContent.Keywords, oldContent.Description));
                        foreach(Message msg in messages) {
                            IndexMessageTree(local, msg);
                        }

                        return local;
                    }
                }

                // Page not found, return null
                return null;
            }
        }
        /// <summary>
        /// Finds a page.
        /// </summary>
        /// <param name="nspace">The namespace that contains the page.</param>
        /// <param name="name">The name of the page to find.</param>
        /// <param name="pages">The pages array.</param>
        /// <returns>The found page, or <c>null</c>.</returns>
        private PageInfo FindPage(string nspace, string name, PageInfo[] pages)
        {
            if(name == null) return null;

            PageNameComparer comp = new PageNameComparer();
            PageInfo target = new PageInfo(NameTools.GetFullName(nspace, name), this, DateTime.Now);

            PageInfo result = Array.Find(pages, delegate(PageInfo p) { return comp.Compare(p, target) == 0; });

            return result;
        }
        /// <summary>
        /// Removes a Page.
        /// </summary>
        /// <param name="page">The Page to remove.</param>
        /// <returns><c>true</c> if the Page has been removed successfully, <c>false</c> otherwise.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="page"/> is <c>null</c>.</exception>
        public bool RemovePage(PageInfo page)
        {
            if(page == null) throw new ArgumentNullException("page");

            lock(this) {
                NamespaceInfo currentNs = FindNamespace(NameTools.GetNamespace(page.FullName), GetNamespaces());
                if(currentNs != null && currentNs.DefaultPage != null) {
                    // Cannot remove the default page
                    if(new PageNameComparer().Compare(currentNs.DefaultPage, page) == 0) return false;
                }

                List<PageInfo> allPages = new List<PageInfo>(GetAllPages());
                PageNameComparer comp = new PageNameComparer();
                for(int i = 0; i < allPages.Count; i++) {
                    if(comp.Compare(allPages[i], page) == 0) {
                        PageContent content = GetContent(page);

                        LocalPageInfo local = page as LocalPageInfo;

                        // Update search engine index
                        UnindexPage(content);
                        Message[] messages = GetMessages(local);
                        foreach(Message msg in messages) {
                            UnindexMessageTree(local, msg);
                        }

                        allPages.Remove(allPages[i]);
                        DeleteBackups(page, -1);
                        DumpPages(allPages.ToArray());
                        try {
                            File.Delete(GetFullPathForPageContent(GetNamespacePartialPathForPageContent(NameTools.GetNamespace(page.FullName)) + ((LocalPageInfo)page).File));
                        }
                        catch { }
                        try {
                            File.Delete(GetDraftFullPath(local));
                        }
                        catch { }
                        try {
                            File.Delete(GetFullPathForMessages(local.File));
                        }
                        catch { }
                        pagesCache = null;
                        categoriesCache = null;

                        return true;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// Moves a page from its namespace into another.
        /// </summary>
        /// <param name="page">The page to move.</param>
        /// <param name="destination">The destination namespace (null for the root).</param>
        /// <param name="copyCategories">A value indicating whether to copy the page categories in the destination 
        /// namespace, if not already available.</param>
        /// <returns>The correct instance of <see cref="T:PageInfo" />.</returns>
        /// <exception cref="ArgumentNullException">If <b>page</b> is <c>null</c>.</exception>
        public PageInfo MovePage(PageInfo page, NamespaceInfo destination, bool copyCategories)
        {
            if(page == null) throw new ArgumentNullException("page");

            string destinationName = destination != null ? destination.Name : null;

            NamespaceInfo currentNs = FindNamespace(NameTools.GetNamespace(page.FullName), GetNamespaces());
            NamespaceComparer nsComp = new NamespaceComparer();
            if((currentNs == null && destination == null) || nsComp.Compare(currentNs, destination) == 0) return null;

            if(PageExists(new PageInfo(NameTools.GetFullName(destinationName, NameTools.GetLocalName(page.FullName)), this, page.CreationDateTime))) return null;
            if(!NamespaceExists(destinationName)) return null;

            if(currentNs != null && currentNs.DefaultPage != null) {
                // Cannot move the default page
                if(new PageNameComparer().Compare(currentNs.DefaultPage, page) == 0) return null;
            }

            // Store categories for copying them, if needed
            CategoryInfo[] pageCategories = GetCategoriesForPage(page);
            // Update categories names with new namespace (don't modify the same instance because it's actually the cache!)
            for(int i = 0; i < pageCategories.Length; i++) {
                string[] pages = pageCategories[i].Pages;
                pageCategories[i] = new CategoryInfo(NameTools.GetFullName(destinationName, NameTools.GetLocalName(pageCategories[i].FullName)), this);
                pageCategories[i].Pages = new string[pages.Length];
                for(int k = 0; k < pages.Length; k++) {
                    pageCategories[i].Pages[k] = NameTools.GetFullName(destinationName, NameTools.GetLocalName(pages[k]));
                }
            }

            // Delete category bindings
            RebindPage(page, new string[0]);

            // Change namespace and file
            PageInfo[] allPages = GetAllPages();
            PageNameComparer comp = new PageNameComparer();
            PageInfo newPage = null;
            foreach(PageInfo current in allPages) {
                if(comp.Compare(current, page) == 0) {
                    // Page found, update data

                    // Change namespace and file
                    LocalPageInfo local = (LocalPageInfo)current;

                    // Update search engine index
                    PageContent oldPageContent = GetContent(local);
                    UnindexPage(oldPageContent);
                    foreach(Message msg in GetMessages(local)) {
                        UnindexMessageTree(local, msg);
                    }

                    // Move backups in new folder
                    MoveBackups(page, destination);

                    string newFile = GetNamespacePartialPathForPageContent(destinationName) + Path.GetFileName(local.File);

                    // Move data file
                    File.Move(GetFullPathForPageContent(local.File), GetFullPathForPageContent(newFile));

                    // Move messages file
                    string messagesFullPath = GetFullPathForMessages(local.File);
                    if(File.Exists(messagesFullPath)) {
                        File.Move(messagesFullPath, GetFullPathForMessages(newFile));
                    }

                    // Move draft file
                    string draftFullPath = GetFullPathForPageDrafts(local.File);
                    if(File.Exists(draftFullPath)) {
                        string newDraftFullPath = GetFullPathForPageDrafts(newFile);
                        if(!Directory.Exists(Path.GetDirectoryName(newDraftFullPath))) {
                            Directory.CreateDirectory(Path.GetDirectoryName(newDraftFullPath));
                        }
                        File.Move(draftFullPath, newDraftFullPath);
                    }

                    //local.Namespace = destinationName;
                    local.FullName = NameTools.GetFullName(destinationName, NameTools.GetLocalName(local.FullName));
                    local.File = newFile;
                    newPage = local;

                    DumpPages(allPages);

                    // Update search engine index
                    IndexPage(new PageContent(newPage, oldPageContent.Title, oldPageContent.User, oldPageContent.LastModified,
                        oldPageContent.Comment, oldPageContent.Content, oldPageContent.Keywords, oldPageContent.Description));
                    foreach(Message msg in GetMessages(local)) {
                        IndexMessageTree(newPage, msg);
                    }

                    break;
                }
            }

            // Rebind page, if needed
            if(copyCategories) {
                // Foreach previously bound category, verify that is present in the destination namespace, if not then create it
                List<string> newCategories = new List<string>(pageCategories.Length);
                foreach(CategoryInfo oldCategory in pageCategories) {
                    if(!CategoryExists(new CategoryInfo(oldCategory.FullName, this))) {
                        AddCategory(destination != null ? destination.Name : null, NameTools.GetLocalName(oldCategory.FullName));
                    }
                    newCategories.Add(oldCategory.FullName);
                }
                RebindPage(newPage, newCategories.ToArray());
            }

            namespacesCache = null;
            pagesCache = null;
            categoriesCache = null;
            return newPage;
        }
Example #15
0
        /// <summary>
        /// Appends a breadbrumb trail element.
        /// </summary>
        /// <param name="sb">The destination <see cref="T:StringBuilder" />.</param>
        /// <param name="page">The page to append.</param>
        /// <param name="dpPrefix">The drop-down menu ID prefix.</param>
        private void AppendBreadcrumb(StringBuilder sb, PageInfo page, string dpPrefix)
        {
            PageNameComparer comp = new PageNameComparer();
            PageContent pc = Content.GetPageContent(page, true);

            string id = AppendBreadcrumbDropDown(sb, page, dpPrefix);

            string nspace = NameTools.GetNamespace(page.FullName);

            sb.Append("&raquo; ");
            if(comp.Compare(page, currentPage) == 0) sb.Append("<b>");
            sb.AppendFormat(@"<a href=""{0}"" title=""{1}""{2}{3}{4}>{1}</a>",
                Tools.UrlEncode(page.FullName) + Settings.PageExtension,
                FormattingPipeline.PrepareTitle(pc.Title, false, FormattingContext.PageContent, currentPage) + (string.IsNullOrEmpty(nspace) ? "" : (" (" + NameTools.GetNamespace(page.FullName) + ")")),
                (id != null ? @" onmouseover=""javascript:return __ShowDropDown(event, '" + id + @"', this);""" : ""),
                (id != null ? @" id=""lnk" + id + @"""" : ""),
                (id != null ? @" onmouseout=""javascript:return __HideDropDown('" + id + @"');""" : ""));
            if(comp.Compare(page, currentPage) == 0) sb.Append("</b>");
            sb.Append(" ");
        }
Example #16
0
        /// <summary>
        /// Finds a page by name.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <returns>The index in the collection.</returns>
        private int FindPage(PageInfo page)
        {
            lock(this) {
                if(pages == null || pages.Count == 0) return -1;

                PageNameComparer comp = new PageNameComparer();
                for(int i = 0; i < pages.Count; i++) {
                    if(comp.Compare(pages[i], page) == 0) return i;
                }

                return -1;
            }
        }
Example #17
0
        /// <summary>
        /// Searches for pages with name or title similar to a specified value.
        /// </summary>
        /// <param name="name">The name to look for (<c>null</c> for the root).</param>
        /// <param name="nspace">The namespace to search into.</param>
        /// <returns>The similar pages, if any.</returns>
        public static PageInfo[] SearchSimilarPages(string name, string nspace)
        {
            if(string.IsNullOrEmpty(nspace)) nspace = null;

            SearchResultCollection searchResults = Search(name, false, false, SearchOptions.AtLeastOneWord);

            List<PageInfo> result = new List<PageInfo>(20);

            foreach(SearchResult res in searchResults) {
                PageDocument pageDoc = res.Document as PageDocument;
                if(pageDoc != null) {
                    string pageNamespace = NameTools.GetNamespace(pageDoc.PageInfo.FullName);
                    if(string.IsNullOrEmpty(pageNamespace)) pageNamespace = null;

                    if(pageNamespace == nspace) {
                        result.Add(pageDoc.PageInfo);
                    }
                }
            }

            // Search page names for matches
            List<PageInfo> allPages = Pages.GetPages(Pages.FindNamespace(nspace));
            PageNameComparer comp = new PageNameComparer();
            string currentName = name.ToLowerInvariant();
            foreach(PageInfo page in allPages) {
                if(NameTools.GetLocalName(page.FullName).ToLowerInvariant().Contains(currentName)) {
                    if(result.Find(delegate(PageInfo p) { return comp.Compare(p, page) == 0; }) == null) {
                        result.Add(page);
                    }
                }
            }

            return result.ToArray();
        }