/// <summary>
        /// This method will get the parsers(types implementing IEDSParser) present in the current assembly in to a List
        /// </summary>
        /// <returns>List containing the Types that implemented IEDSParser</returns>
        private static List <IEDSParser> GetBuiltInParsers()
        {
            List <IEDSParser> parsers     = new List <IEDSParser>(16);
            Assembly          curAssembly = Assembly.GetEntryAssembly();

            foreach (Type type in curAssembly.GetTypes())                      //Enumerate all the types in the current assembly
            {
                if (type.IsClass && typeof(IEDSParser).IsAssignableFrom(type)) //if type is a class and IEDSParser can be instantiated from type "type"
                {
                    IEDSParser fileparser = (IEDSParser)Activator.CreateInstance(type);
                    GlobalData.DefaultExtensions += fileparser.ParserFileTypes + " ";
                    switch (fileparser.ParserCategory)
                    {
                    case "docs":
                        GlobalData.DocFileTypes += fileparser.ParserFileTypes + " ";
                        break;

                    case "audio":
                        GlobalData.AudioFileTypes += fileparser.ParserFileTypes + " ";
                        break;

                    case "video":
                        GlobalData.VideoFileTypes += fileparser.ParserFileTypes + " ";
                        break;

                    case "pics":
                        GlobalData.ImageFileTypes += fileparser.ParserFileTypes + " ";
                        break;
                    }
                    parsers.Add(fileparser);
                }
            }
            return(parsers);
        }
        /// <summary>
        /// This method will get the parsers(types implementing IEDSParser) present in the external parsers in to a List
        /// </summary>
        /// <returns>List containing the Types that implemented IEDSParser</returns>
        private static List <IEDSParser> GetInstalledParsers()
        {
            List <IEDSParser> parsers = new List <IEDSParser>(16);

            foreach (string dll in Directory.GetFiles(GlobalData.ParserFolder, "*.dll"))
            {
                Assembly parser = Assembly.LoadFile(dll);
                foreach (Type type in parser.GetExportedTypes())                   //Enumerate all the types in the current assembly
                {
                    if (type.IsClass && typeof(IEDSParser).IsAssignableFrom(type)) //if type is a class and IEDSParser can be instantiated from type "type"
                    {
                        IEDSParser fileparser = (IEDSParser)Activator.CreateInstance(type);
                        GlobalData.DefaultExtensions += fileparser.ParserFileTypes + " ";
                        switch (fileparser.ParserCategory)
                        {
                        case "docs":
                            GlobalData.DocFileTypes += fileparser.ParserFileTypes + " ";
                            break;

                        case "audio":
                            GlobalData.AudioFileTypes += fileparser.ParserFileTypes + " ";
                            break;

                        case "video":
                            GlobalData.VideoFileTypes += fileparser.ParserFileTypes + " ";
                            break;

                        case "pics":
                            GlobalData.ImageFileTypes += fileparser.ParserFileTypes + " ";
                            break;
                        }
                        parsers.Add(fileparser);
                    }
                }
            }
            return(parsers);
        }
        /// <summary>
        /// This Method is responsible for Crawling a given Volume or Path recursively.
        /// This method periodically checks the shared state variable 'crawlerState' and
        /// crawls the given path only when it is set to CrawlerState.Run
        ///
        /// Note: The shared variable is modified by the scheduler periodically depending on the
        ///       availability of system resources
        /// </summary>
        /// <param name="path">Path to a root volume or a directory whose contents are to be crawled recursively</param>
        private void Crawler(string path)
        {
            if (GlobalData.RunCrawler)  //assume the app is running and user has not exited the application
            {
                try
                {
                    //Process files
                    foreach (string file in Directory.GetFiles(path))
                    {
                        GlobalData.lIndexingStatus.Text = "Indexing: " + file;
                        if (crawlerState == CrawlerState.Run)  //Is the system in idle state
                        {
                            //Get the respective content handler. If no content handler is present return the default handler
                            IEDSParser parser = GlobalData.Parsers.ContainsKey(Path.GetExtension(file).ToLower()) ?
                                                GlobalData.Parsers[Path.GetExtension(file).ToLower()] : GlobalData.Parsers["*.*"];
                            if (parser != null)  //For some nasty reason the file got deleted or doesnot exist
                            {
                                StringDictionary properties = parser.GetProperties(file);
                                if (properties != null)
                                {
#if Log
                                    Console.WriteLine("Indexing File:" + file);
#endif
                                    GlobalData.Indexer.Index(properties);
                                }
                            }
                        }
                        else if (crawlerState == CrawlerState.Stop)                                                       //If the system is not ready
                        {
                            while (crawlerState == CrawlerState.Stop && GlobalData.RunScheduler && GlobalData.RunCrawler) //Check the status for every 1 sec
                            {
                                Thread.Sleep(1000);
                            }
                        }
                        else if (!GlobalData.RunCrawler)
                        {
                            break;                                 //if app is already close then we should also stop the crawler
                        }
                    }

                    //Process Directories
                    foreach (string dir in Directory.GetDirectories(path))
                    {
                        if (Path.GetFileName(dir).ToLower() != "recycler" ||
                            !string.IsNullOrEmpty(Path.GetDirectoryName(Path.GetDirectoryName(dir))))
                        {
                            GenericDirectoryParser parser = GenericDirectoryParser.GetInstance();
                            if (parser != null)
                            {
                                StringDictionary properties = parser.GetProperties(dir);
                                if (properties != null)
                                {
#if Log
                                    Console.WriteLine("Indexing Directory:" + dir);
#endif
                                    GlobalData.Indexer.Index(properties);
                                }
                            }
                            Crawler(dir);
                        }
                    }
                }
                catch (UnauthorizedAccessException uae) { }
            }
        }
        void IndexGatheredFiles(object state)
        {
            try
            {
                #region Deleting files from the indexes
                //Iterate over all the directories present in the %appdata%\EDS\indexes folder
                if (GlobalData.DeletedFiles.Count > 0)
                {
                    foreach (string dir in Directory.GetDirectories(GlobalData.IndexRootPath))
                    {
                        //Deletion of files from indexes
                        IndexReader reader = IndexReader.Open(dir);
                        lock (GlobalData.DeletedFiles)
                        {
                            //foreach (string path in GlobalData.DeletedFiles)
                            while (GlobalData.DeletedFiles.Count != 0)
                            {
                                reader.DeleteDocuments(new Term("path", GlobalData.DeletedFiles[0]));
                                GlobalData.lIndexingStatus.Text = GlobalData.DeletedFiles[0] + " is deleted from indexes";
                                GlobalData.DeletedFiles.RemoveAt(0);
                            }
                        }
                        reader.Close();
                    }
                }
                #endregion

                #region indexing newly created files
                //Indexing of new Files
                if (GlobalData.CreatedFiles.Count > 0)
                {
                    lock (GlobalData.CreatedFiles)
                    {
                        //   foreach (string path in GlobalData.CreatedFiles)
                        while (GlobalData.CreatedFiles.Count != 0)
                        {
                            string path = GlobalData.CreatedFiles[0];
                            //Get the respective content handler. If no content handler is present return the default handler
                            IEDSParser parser = GlobalData.Parsers.ContainsKey(Path.GetExtension(path).ToLower()) ?
                                                GlobalData.Parsers[Path.GetExtension(path).ToLower()] : GlobalData.Parsers["*.*"];
                            if (parser != null)  //For some nasty reason the file got deleted or doesnot exist
                            {
                                StringDictionary properties = parser.GetProperties(path);
                                if (properties != null)
                                {
                                    //Initialize the indexer
                                    EDSIndexer indexer = new EDSIndexer(GlobalData.IndexRootPath + path[0]);
                                    indexer.Index(properties);
                                    indexer.Close();
                                }
                            }
                            GlobalData.lIndexingStatus.Text = GlobalData.CreatedFiles[0] + " is newly indexed";
                            GlobalData.CreatedFiles.RemoveAt(0);
                        }
                    }
                }
                #endregion

                #region Updating already indexed files

                lock (GlobalData.ChangedFiles)
                {
                    //foreach (string path in GlobalData.ChangedFiles)
                    while (GlobalData.ChangedFiles.Count != 0)
                    {
                        string path = GlobalData.ChangedFiles[0];
                        //first delete that document
                        foreach (string dir in Directory.GetDirectories(GlobalData.IndexRootPath))
                        {
                            //Deletion of files from indexes
                            IndexReader reader = IndexReader.Open(dir);
                            reader.DeleteDocuments(new Term("path", path));
                            bool deleted = reader.HasDeletions();
                            reader.Close();
                            if (deleted)
                            {
                                break;
                            }
                        }
                        //reindex the document
                        //Get the respective content handler. If no content handler is present return the default handler
                        IEDSParser parser = GlobalData.Parsers.ContainsKey(Path.GetExtension(path).ToLower()) ?
                                            GlobalData.Parsers[Path.GetExtension(path).ToLower()] : GlobalData.Parsers["*.*"];
                        if (parser != null)  //For some nasty reason the file got deleted or doesnot exist
                        {
                            StringDictionary properties = parser.GetProperties(path);
                            if (properties != null)
                            {
                                //Initialize the indexer
                                EDSIndexer indexer = new EDSIndexer(GlobalData.IndexRootPath + path[0]);
                                indexer.Index(properties);
                                indexer.Close();
                            }
                        }
                        GlobalData.lIndexingStatus.Text = path + " is updated in the indexes";
                        GlobalData.ChangedFiles.RemoveAt(0);
                    }
                }

                #endregion

                #region Updating renamed files
                lock (GlobalData.RenamedFiles)
                {
                    //foreach (string path in GlobalData.ChangedFiles)
                    while (GlobalData.RenamedFiles.Count != 0)
                    {
                        string path = GlobalData.RenamedFiles[0].OldFullPath;
                        //first delete the old document
                        foreach (string dir in Directory.GetDirectories(GlobalData.IndexRootPath))
                        {
                            //Deletion of files from indexes
                            IndexReader reader = IndexReader.Open(dir);
                            reader.DeleteDocuments(new Term("path", path));
                            bool deleted = reader.HasDeletions();
                            reader.Close();
                            if (deleted)
                            {
                                break;
                            }
                        }
                        //reindex the new document
                        //Get the respective content handler. If no content handler is present return the default handler
                        path = GlobalData.RenamedFiles[0].FullPath;
                        IEDSParser parser = GlobalData.Parsers.ContainsKey(Path.GetExtension(path).ToLower()) ?
                                            GlobalData.Parsers[Path.GetExtension(path).ToLower()] : GlobalData.Parsers["*.*"];
                        if (parser != null)  //For some nasty reason the file got deleted or doesnot exist
                        {
                            StringDictionary properties = parser.GetProperties(path);
                            if (properties != null)
                            {
                                //Initialize the indexer
                                EDSIndexer indexer = new EDSIndexer(GlobalData.IndexRootPath + path[0]);
                                indexer.Index(properties);
                                indexer.Close();
                            }
                        }
                        GlobalData.lIndexingStatus.Text = "Renamed file " + path + " is updated in the indexes";
                        GlobalData.RenamedFiles.RemoveAt(0);
                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
#if Log
                Console.WriteLine(ex);
#endif
            }
        }