Ejemplo n.º 1
0
        /// <summary>
        /// Renames a file in the index.
        /// </summary>
        /// <param name="oldName">The old attachment name.</param>
        /// <param name="newName">The new attachment name.</param>
        public static bool RenameFile(string oldName, string newName)
        {
            IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider;

            Analyzer analyzer = new SimpleAnalyzer();
            Term     term     = new Term(SearchField.Key.AsString(), (DocumentTypeToString(DocumentType.File) + "|" + oldName).Replace(" ", ""));

            Query query = new TermQuery(term);

            using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), analyzer, IndexWriter.MaxFieldLength.UNLIMITED))
                using (IndexSearcher searcher = new IndexSearcher(indexDirectoryProvider.GetDirectory(), false))
                {
                    TopDocs topDocs = searcher.Search(query, 100);
                    if (topDocs.ScoreDocs.Length == 0)
                    {
                        return(true);
                    }

                    Document doc = searcher.Doc(topDocs.ScoreDocs[0].Doc);

                    Document newDoc = new Document();
                    newDoc.Add(new Field(SearchField.Key.AsString(), (DocumentTypeToString(DocumentType.File) + "|" + newName).Replace(" ", ""), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS));
                    newDoc.Add(new Field(SearchField.DocumentType.AsString(), DocumentTypeToString(DocumentType.File), Field.Store.YES, Field.Index.ANALYZED));
                    newDoc.Add(new Field(SearchField.FileName.AsString(), newName, Field.Store.YES, Field.Index.ANALYZED));
                    newDoc.Add(new Field(SearchField.FileContent.AsString(), doc.GetField(SearchField.FileContent.AsString()).StringValue, Field.Store.YES, Field.Index.ANALYZED));
                    writer.UpdateDocument(term, newDoc);
                    writer.Commit();
                }
            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Indexes a file.
        /// </summary>
        /// <param name="fileName">The name of the file to be indexed.</param>
        /// <param name="filePath">The path of the file to be indexed.</param>
        /// <returns><c>true</c> if the message has been indexed succesfully, <c>false</c> otherwise.</returns>
        public static bool IndexFile(string fileName, string filePath)
        {
            IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider;

            Analyzer analyzer = new SimpleAnalyzer();

            using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), analyzer, IndexWriter.MaxFieldLength.UNLIMITED))
            {
                try
                {
                    Document doc = new Document();
                    doc.Add(new Field(SearchField.Key.AsString(), (DocumentTypeToString(DocumentType.File) + "|" + fileName).Replace(" ", ""), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS));
                    doc.Add(new Field(SearchField.DocumentType.AsString(), DocumentTypeToString(DocumentType.File), Field.Store.YES, Field.Index.ANALYZED));
                    doc.Add(new Field(SearchField.FileName.AsString(), fileName, Field.Store.YES, Field.Index.ANALYZED));
                    string fileContent = SearchEngine.Parser.Parse(filePath);
                    doc.Add(new Field(SearchField.FileContent.AsString(), fileContent, Field.Store.YES, Field.Index.ANALYZED));
                    writer.AddDocument(doc);
                    writer.Commit();
                }
                catch (System.Runtime.InteropServices.COMException ex)
                {
                    Log.LogEntry(ex.Message, EntryType.Warning, Log.SystemUsername);
                }
            }
            return(true);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Unindexes the file.
        /// </summary>
        /// <param name="fileName">The name of the attachment.</param>
        /// <returns><c>true</c> if the file has been unindexed succesfully, <c>false</c> otherwise.</returns>
        public static bool UnindexFile(string fileName)
        {
            IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider;

            using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), new SimpleAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED))
            {
                writer.DeleteDocuments(new Term(SearchField.Key.AsString(), (DocumentTypeToString(DocumentType.File) + "|" + fileName).Replace(" ", "")));
                writer.Commit();
            }
            return(true);
        }
Ejemplo n.º 4
0
        protected void rptIndex_ItemCommand(object sender, CommandEventArgs e)
        {
            Log.LogEntry("Index rebuild requested for " + e.CommandArgument as string, EntryType.General, SessionFacade.GetCurrentUsername());

            IIndexDirectoryProviderV30 provider = Collectors.IndexDirectoryProvider;

            //TODO provider.RebuildIndex();

            Log.LogEntry("Index rebuild completed for " + e.CommandArgument as string, EntryType.General, Log.SystemUsername);

            rptIndex.DataBind();
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Clears the files index.
        /// </summary>
        public static void ClearFilesIndex()
        {
            IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider;

            Analyzer analyzer = new SimpleAnalyzer();

            using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), analyzer, IndexWriter.MaxFieldLength.UNLIMITED))
            {
                ClearFilesIndex(writer);
                ClearAttachmentsIndex(writer);

                writer.Commit();
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Unindexes the message.
        /// </summary>
        /// <param name="messageId">The id of the message to be unindexed.</param>
        /// <param name="page">The page the message belongs to.</param>
        /// <returns><c>true</c> if the message has been unindexed succesfully, <c>false</c> otherwise.</returns>
        public static bool UnindexMessage(int messageId, PageContent page)
        {
            IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider;

            using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), new KeywordAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED))
            {
                Query query = MultiFieldQueryParser.Parse(Lucene.Net.Util.Version.LUCENE_30
                                                          , new string[] { DocumentTypeToString(DocumentType.Message), page.PageInfo.FullName, messageId.ToString() }
                                                          , new string[] { SearchField.DocumentType.AsString(), SearchField.PageFullName.AsString(), SearchField.MessageId.AsString() }
                                                          , new Occur[] { Occur.MUST, Occur.MUST, Occur.MUST }, new KeywordAnalyzer());
                writer.DeleteDocuments(query);
                writer.Commit();
            }

            return(true);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Indexes the page.
        /// </summary>
        /// <param name="page">The page page to be intexed.</param>
        /// <returns><c>true</c> if the page has been indexed succesfully, <c>false</c> otherwise.</returns>
        public static bool IndexPage(PageContent page)
        {
            IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider;

            Analyzer analyzer = new SimpleAnalyzer();

            using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), analyzer, IndexWriter.MaxFieldLength.UNLIMITED))
            {
                Document doc = new Document();
                doc.Add(new Field(SearchField.Key.AsString(), (DocumentTypeToString(DocumentType.Page) + "|" + page.FullName).Replace(" ", ""), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS));
                doc.Add(new Field(SearchField.DocumentType.AsString(), DocumentTypeToString(DocumentType.Page), Field.Store.YES, Field.Index.NOT_ANALYZED));
                doc.Add(new Field(SearchField.PageFullName.AsString(), page.FullName, Field.Store.YES, Field.Index.ANALYZED));
                doc.Add(new Field(SearchField.Title.AsString(), page.Title, Field.Store.YES, Field.Index.ANALYZED));
                doc.Add(new Field(SearchField.Content.AsString(), page.Content, Field.Store.YES, Field.Index.ANALYZED));
                writer.AddDocument(doc);
                writer.Commit();
            }
            return(true);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Indexes the message.
        /// </summary>
        /// <param name="message">The message to be indexed.</param>
        /// <param name="page">The page the message belongs to.</param>
        /// <returns><c>true</c> if the message has been indexed succesfully, <c>false</c> otherwise.</returns>
        public static bool IndexMessage(Message message, PageContent page)
        {
            IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider;

            Analyzer analyzer = new SimpleAnalyzer();

            using (IndexWriter writer = new IndexWriter(indexDirectoryProvider.GetDirectory(), analyzer, IndexWriter.MaxFieldLength.UNLIMITED))
            {
                Document doc = new Document();
                doc.Add(new Field(SearchField.DocumentType.AsString(), DocumentTypeToString(DocumentType.Message), Field.Store.YES, Field.Index.NOT_ANALYZED));
                doc.Add(new Field(SearchField.PageFullName.AsString(), page.PageInfo.FullName, Field.Store.YES, Field.Index.NOT_ANALYZED));
                doc.Add(new Field(SearchField.MessageId.AsString(), message.ID.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED));
                doc.Add(new Field(SearchField.Title.AsString(), message.Subject, Field.Store.YES, Field.Index.ANALYZED));
                doc.Add(new Field(SearchField.Content.AsString(), message.Body, Field.Store.YES, Field.Index.ANALYZED));
                doc.Add(new Field(SearchField.MessageDateTime.AsString(), message.DateTime.ToString("yyyy/MM/dd HH:mm:ss"), Field.Store.YES, Field.Index.NO));
                writer.AddDocument(doc);
                writer.Commit();
            }

            return(true);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Performs all needed startup operations.
        /// </summary>
        public static void Startup()
        {
            // Load Host
            Host.Instance = new Host();

            // Load config
            ISettingsStorageProviderV30 ssp = ProviderLoader.LoadSettingsStorageProvider(WebConfigurationManager.AppSettings["SettingsStorageProvider"]);

            ssp.Init(Host.Instance, GetSettingsStorageProviderConfiguration());
            Collectors.SettingsProvider = ssp;

            if (!(ssp is SettingsStorageProvider))
            {
                // Update DLLs from public\Plugins
                UpdateDllsIntoSettingsProvider(ssp, ProviderLoader.SettingsStorageProviderAssemblyName);
            }

            if (ssp.IsFirstApplicationStart())
            {
                if (ssp.GetMetaDataItem(MetaDataItem.AccountActivationMessage, null) == "")
                {
                    ssp.SetMetaDataItem(MetaDataItem.AccountActivationMessage, null, Defaults.AccountActivationMessageContent);
                }

                if (ssp.GetMetaDataItem(MetaDataItem.EditNotice, null) == "")
                {
                    ssp.SetMetaDataItem(MetaDataItem.EditNotice, null, Defaults.EditNoticeContent);
                }

                if (ssp.GetMetaDataItem(MetaDataItem.Footer, null) == "")
                {
                    ssp.SetMetaDataItem(MetaDataItem.Footer, null, Defaults.FooterContent);
                }

                if (ssp.GetMetaDataItem(MetaDataItem.Header, null) == "")
                {
                    ssp.SetMetaDataItem(MetaDataItem.Header, null, Defaults.HeaderContent);
                }

                if (ssp.GetMetaDataItem(MetaDataItem.PasswordResetProcedureMessage, null) == "")
                {
                    ssp.SetMetaDataItem(MetaDataItem.PasswordResetProcedureMessage, null, Defaults.PasswordResetProcedureMessageContent);
                }

                if (ssp.GetMetaDataItem(MetaDataItem.Sidebar, null) == "")
                {
                    ssp.SetMetaDataItem(MetaDataItem.Sidebar, null, Defaults.SidebarContent);
                }

                if (ssp.GetMetaDataItem(MetaDataItem.PageChangeMessage, null) == "")
                {
                    ssp.SetMetaDataItem(MetaDataItem.PageChangeMessage, null, Defaults.PageChangeMessage);
                }

                if (ssp.GetMetaDataItem(MetaDataItem.DiscussionChangeMessage, null) == "")
                {
                    ssp.SetMetaDataItem(MetaDataItem.DiscussionChangeMessage, null, Defaults.DiscussionChangeMessage);
                }

                if (ssp.GetMetaDataItem(MetaDataItem.ApproveDraftMessage, null) == "")
                {
                    ssp.SetMetaDataItem(MetaDataItem.ApproveDraftMessage, null, Defaults.ApproveDraftMessage);
                }
            }

            // Load config
            IIndexDirectoryProviderV30 idp = ProviderLoader.LoadIndexDirectoryProvider(WebConfigurationManager.AppSettings["IndexDirectoryProvider"]);

            idp.Init(Host.Instance, GetSettingsStorageProviderConfiguration());
            Collectors.IndexDirectoryProvider = idp;

            MimeTypes.Init();

            // Load Providers
            Collectors.FileNames = new System.Collections.Generic.Dictionary <string, string>(10);
            Collectors.UsersProviderCollector             = new ProviderCollector <IUsersStorageProviderV30>();
            Collectors.PagesProviderCollector             = new ProviderCollector <IPagesStorageProviderV30>();
            Collectors.FilesProviderCollector             = new ProviderCollector <IFilesStorageProviderV30>();
            Collectors.FormatterProviderCollector         = new ProviderCollector <IFormatterProviderV30>();
            Collectors.CacheProviderCollector             = new ProviderCollector <ICacheProviderV30>();
            Collectors.DisabledUsersProviderCollector     = new ProviderCollector <IUsersStorageProviderV30>();
            Collectors.DisabledPagesProviderCollector     = new ProviderCollector <IPagesStorageProviderV30>();
            Collectors.DisabledFilesProviderCollector     = new ProviderCollector <IFilesStorageProviderV30>();
            Collectors.DisabledFormatterProviderCollector = new ProviderCollector <IFormatterProviderV30>();
            Collectors.DisabledCacheProviderCollector     = new ProviderCollector <ICacheProviderV30>();

            // Load built-in providers

            // Files storage providers have to be loaded BEFORE users storage providers in order to properly set permissions
            FilesStorageProvider f = new FilesStorageProvider();

            if (!ProviderLoader.IsDisabled(f.GetType().FullName))
            {
                f.Init(Host.Instance, "");
                Collectors.FilesProviderCollector.AddProvider(f);
                Log.LogEntry("Provider " + f.Information.Name + " loaded (Enabled)", EntryType.General, Log.SystemUsername);
            }
            else
            {
                Collectors.DisabledFilesProviderCollector.AddProvider(f);
                Log.LogEntry("Provider " + f.Information.Name + " loaded (Disabled)", EntryType.General, Log.SystemUsername);
            }

            UsersStorageProvider u = new UsersStorageProvider();

            if (!ProviderLoader.IsDisabled(u.GetType().FullName))
            {
                u.Init(Host.Instance, "");
                Collectors.UsersProviderCollector.AddProvider(u);
                Log.LogEntry("Provider " + u.Information.Name + " loaded (Enabled)", EntryType.General, Log.SystemUsername);
            }
            else
            {
                Collectors.DisabledUsersProviderCollector.AddProvider(u);
                Log.LogEntry("Provider " + u.Information.Name + " loaded (Disabled)", EntryType.General, Log.SystemUsername);
            }

            // Load Users (pages storage providers might need access to users/groups data for upgrading from 2.0 to 3.0)
            ProviderLoader.FullLoad(true, false, false, false, false);
            //Users.Instance = new Users();
            bool groupsCreated = VerifyAndCreateDefaultGroups();

            PagesStorageProvider p = new PagesStorageProvider();

            if (!ProviderLoader.IsDisabled(p.GetType().FullName))
            {
                p.Init(Host.Instance, "");
                Collectors.PagesProviderCollector.AddProvider(p);
                Log.LogEntry("Provider " + p.Information.Name + " loaded (Enabled)", EntryType.General, Log.SystemUsername);
            }
            else
            {
                Collectors.DisabledPagesProviderCollector.AddProvider(p);
                Log.LogEntry("Provider " + p.Information.Name + " loaded (Disabled)", EntryType.General, Log.SystemUsername);
            }

            CacheProvider c = new CacheProvider();

            if (!ProviderLoader.IsDisabled(c.GetType().FullName))
            {
                c.Init(Host.Instance, "");
                Collectors.CacheProviderCollector.AddProvider(c);
                Log.LogEntry("Provider " + c.Information.Name + " loaded (Enabled)", EntryType.General, Log.SystemUsername);
            }
            else
            {
                Collectors.DisabledCacheProviderCollector.AddProvider(c);
                Log.LogEntry("Provider " + c.Information.Name + " loaded (Disabled)", EntryType.General, Log.SystemUsername);
            }

            // Load all other providers
            ProviderLoader.FullLoad(false, true, true, true, true);

            if (groupsCreated)
            {
                // It is necessary to set default permissions for file management
                UserGroup administratorsGroup = Users.FindUserGroup(Settings.AdministratorsGroup);
                UserGroup anonymousGroup      = Users.FindUserGroup(Settings.AnonymousGroup);
                UserGroup usersGroup          = Users.FindUserGroup(Settings.UsersGroup);

                SetAdministratorsGroupDefaultPermissions(administratorsGroup);
                SetUsersGroupDefaultPermissions(usersGroup);
                SetAnonymousGroupDefaultPermissions(anonymousGroup);
            }

            // Init cache
            //Cache.Instance = new Cache(Collectors.CacheProviderCollector.GetProvider(Settings.DefaultCacheProvider));
            if (Collectors.CacheProviderCollector.GetProvider(Settings.DefaultCacheProvider) == null)
            {
                Log.LogEntry("Default Cache Provider was not loaded, backing to integrated provider", EntryType.Error, Log.SystemUsername);
                Settings.DefaultCacheProvider = typeof(CacheProvider).FullName;
                Collectors.TryEnable(Settings.DefaultCacheProvider);
            }

            // Create the Main Page, if needed
            if (Pages.FindPage(Settings.DefaultPage) == null)
            {
                CreateMainPage();
            }

            Log.LogEntry("ScrewTurn Wiki is ready", EntryType.General, Log.SystemUsername);

            System.Threading.ThreadPool.QueueUserWorkItem(ignored =>
            {
                SearchClass.RebuildIndex();
            });
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Searches the specified phrase in the specified search fields.
        /// </summary>
        /// <param name="searchFields">The search fields.</param>
        /// <param name="phrase">The phrase to search.</param>
        /// <param name="searchOption">The search options.</param>
        /// <returns>A list of <see cref="SearchResult"/> items.</returns>
        public static List <SearchResult> Search(SearchField[] searchFields, string phrase, SearchOptions searchOption)
        {
            IIndexDirectoryProviderV30 indexDirectoryProvider = Collectors.IndexDirectoryProvider;
            Analyzer analyzer = new SimpleAnalyzer();

            using (IndexSearcher searcher = new IndexSearcher(indexDirectoryProvider.GetDirectory(), false))
            {
                string[] searchFieldsAsString     = (from f in searchFields select f.AsString()).ToArray();
                MultiFieldQueryParser queryParser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, searchFieldsAsString, analyzer);

                if (searchOption == SearchOptions.AllWords)
                {
                    queryParser.DefaultOperator = QueryParser.Operator.AND;
                }

                if (searchOption == SearchOptions.AtLeastOneWord)
                {
                    queryParser.DefaultOperator = QueryParser.Operator.OR;
                }

                try
                {
                    Query   query   = queryParser.Parse(phrase);
                    TopDocs topDocs = searcher.Search(query, 100);

                    Highlighter highlighter = new Highlighter(new SimpleHTMLFormatter("<b class=\"searchkeyword\">", "</b>"), new QueryScorer(query));

                    List <SearchResult> searchResults = new List <SearchResult>(topDocs.TotalHits);
                    for (int i = 0; i < Math.Min(100, topDocs.TotalHits); i++)
                    {
                        Document doc = searcher.Doc(topDocs.ScoreDocs[i].Doc);

                        SearchResult result = new SearchResult();
                        result.DocumentType = DocumentTypeFromString(doc.GetField(SearchField.DocumentType.AsString()).StringValue);
                        result.Relevance    = topDocs.ScoreDocs[i].Score * 100;
                        switch (result.DocumentType)
                        {
                        case DocumentType.Page:
                            PageDocument page = new PageDocument();
                            page.PageFullName = doc.GetField(SearchField.PageFullName.AsString()).StringValue;
                            page.Title        = doc.GetField(SearchField.Title.AsString()).StringValue;

                            TokenStream tokenStream1 = analyzer.TokenStream(SearchField.Title.AsString(), new StringReader(page.Title));
                            page.HighlightedTitle = highlighter.GetBestFragments(tokenStream1, page.Title, 3, " [...] ");

                            page.Content = doc.GetField(SearchField.Content.AsString()).StringValue;

                            tokenStream1            = analyzer.TokenStream(SearchField.Content.AsString(), new StringReader(page.Content));
                            page.HighlightedContent = highlighter.GetBestFragments(tokenStream1, page.Content, 3, " [...] ");

                            result.Document = page;
                            break;

                        case DocumentType.Message:
                            MessageDocument message = new MessageDocument();
                            message.PageFullName = doc.GetField(SearchField.PageFullName.AsString()).StringValue;
                            message.DateTime     = DateTime.Parse(doc.GetField(SearchField.MessageDateTime.AsString()).StringValue);
                            message.Subject      = doc.GetField(SearchField.Title.AsString()).StringValue;
                            message.Body         = doc.GetField(SearchField.Content.AsString()).StringValue;

                            TokenStream tokenStream2 = analyzer.TokenStream(SearchField.Content.AsString(), new StringReader(message.Body));
                            message.HighlightedBody = highlighter.GetBestFragments(tokenStream2, message.Body, 3, " [...] ");

                            result.Document = message;
                            break;

                        case DocumentType.Attachment:
                            PageAttachmentDocument attachment = new PageAttachmentDocument();
                            attachment.PageFullName = doc.GetField(SearchField.PageFullName.AsString()).StringValue;
                            attachment.FileName     = doc.GetField(SearchField.FileName.AsString()).StringValue;
                            attachment.FileContent  = doc.GetField(SearchField.FileContent.AsString()).StringValue;

                            TokenStream tokenStream3 = analyzer.TokenStream(SearchField.Content.AsString(), new StringReader(attachment.FileContent));
                            attachment.HighlightedFileContent = highlighter.GetBestFragments(tokenStream3, attachment.FileContent, 3, " [...] ");

                            result.Document = attachment;
                            break;

                        case DocumentType.File:
                            FileDocument file = new FileDocument();
                            file.FileName    = doc.GetField(SearchField.FileName.AsString()).StringValue;
                            file.FileContent = doc.GetField(SearchField.FileContent.AsString()).StringValue;

                            TokenStream tokenStream4 = analyzer.TokenStream(SearchField.Content.AsString(), new StringReader(file.FileContent));
                            file.HighlightedFileContent = highlighter.GetBestFragments(tokenStream4, file.FileContent, 3, " [...]");

                            result.Document = file;
                            break;

                        case DocumentType.SourceControlFile:
                            FileDocument scfile = new FileDocument();
                            scfile.FileName    = doc.GetField(SearchField.FileName.AsString()).StringValue;
                            scfile.FileContent = doc.GetField(SearchField.FileContent.AsString()).StringValue;

                            TokenStream tokenStream5 = analyzer.TokenStream(SearchField.Content.AsString(), new StringReader(scfile.FileContent));
                            scfile.HighlightedFileContent = highlighter.GetBestFragments(tokenStream5, scfile.FileContent, 3, " [...]");

                            result.Document = scfile;
                            break;
                        }

                        searchResults.Add(result);
                    }
                    return(searchResults);
                }
                catch (ParseException)
                {
                    return(new List <SearchResult>(0));
                }
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Loads the proper Index Directory Provider, given its name.
        /// </summary>
        /// <param name="name">The fully qualified name (such as "Namespace.ProviderClass, MyAssembly"), or <c>null</c>/<b>String.Empty</b>/"<b>default</b>" for the default provider.</param>
        /// <returns>The Index Directory provider.</returns>
        public static IIndexDirectoryProviderV30 LoadIndexDirectoryProvider(string name)
        {
            if (name == null || name.Length == 0 || string.Compare(name, "default", true, CultureInfo.InvariantCulture) == 0)
            {
                return(new FSIndexDirectoryProvider());
            }

            IIndexDirectoryProviderV30 result = null;

            Exception inner = null;

            if (name.Contains(","))
            {
                string[] fields = name.Split(',');
                if (fields.Length == 2)
                {
                    fields[0] = fields[0].Trim(' ', '"');
                    fields[1] = fields[1].Trim(' ', '"');
                    try
                    {
                        // assemblyName should be an absolute path or a relative path in bin or public\Plugins

                        Assembly asm;
                        Type     t;
                        string   assemblyName = fields[1];
                        if (!assemblyName.ToLowerInvariant().EndsWith(".dll"))
                        {
                            assemblyName += ".dll";
                        }

                        if (File.Exists(assemblyName))
                        {
                            asm = Assembly.Load(LoadAssemblyFromDisk(assemblyName));
                            t   = asm.GetType(fields[0]);
                            SettingsStorageProviderAssemblyName = Path.GetFileName(assemblyName);
                        }
                        else
                        {
                            string tentativePluginsPath = null;
                            try
                            {
                                // Settings.PublicDirectory is only available when running the web app
                                tentativePluginsPath = Path.Combine(Settings.PublicDirectory, "Plugins");
                                tentativePluginsPath = Path.Combine(tentativePluginsPath, assemblyName);
                            }
                            catch { }

                            if (!string.IsNullOrEmpty(tentativePluginsPath) && File.Exists(tentativePluginsPath))
                            {
                                asm = Assembly.Load(LoadAssemblyFromDisk(tentativePluginsPath));
                                t   = asm.GetType(fields[0]);
                                IndexDirectoryProviderAssemblyName = Path.GetFileName(tentativePluginsPath);
                            }
                            else
                            {
                                // Trim .dll
                                t = Type.GetType(fields[0] + "," + assemblyName.Substring(0, assemblyName.Length - 4), true, true);
                                IndexDirectoryProviderAssemblyName = assemblyName;
                            }
                        }

                        result = t.GetConstructor(new Type[0]).Invoke(new object[0]) as IIndexDirectoryProviderV30;
                    }
                    catch (Exception ex)
                    {
                        inner  = ex;
                        result = null;
                    }
                }
            }

            if (result == null)
            {
                throw new ArgumentException("Could not load the specified Settings Storage Provider", inner);
            }
            else
            {
                return(result);
            }
        }