public static List<QueryResult> SearchFreeTextQuery(string catalog, CultureInfo culture, string query, uint topNbyRank)
        {
            readerLock.AcquireReaderLock(1000 * 60); // 60 second timeout
            TextIndex index = GetTextIndex(catalog, culture);

            // Get all of the words (front match)
            List<Word> queryWordsList = index.WordBreaker.BreakWords(query);

            Dictionary<Synonym, List<WordRef>> results = new Dictionary<Synonym, List<WordRef>>();
            List<Synonym> words = index.Thesaurus.Suggest(queryWordsList);
            WordRefEqualityComparer comp = new WordRefEqualityComparer();

            foreach (Synonym word in words) {
                List<WordRef> res = index.FrontMatch(word.OriginalWord);

                // Synonyms
                foreach (string syn in word.SuggestedWords) {
                    if (syn == word.OriginalWord)
                        continue;

                    List<Word> synBreaker = index.WordBreaker.BreakWords(syn);
                    List<WordRef> SubResults = new List<WordRef>();
                    bool FirstLoop = true;

                    foreach (Word w in synBreaker) {
                        // maybe intersect the results here?
                        List<WordRef> lookup = index.FindWord(w.WordText);
                        if (lookup != null) {
                            if (FirstLoop) {
                                SubResults.AddRange(lookup);
                                FirstLoop = false;
                            } else
                                SubResults = SubResults.Intersect(lookup, comp).ToList();
                        }
                    }

                    // Add the matchie words
                    if ( SubResults != null )
                        res.AddRange(SubResults);
                }
                results.Add(word, res);
            }
            readerLock.ReleaseReaderLock();
            // Intersect results

            // intersect the results
            List<int> resultList = new List<int>();
            bool firstTime = true;
            foreach (List<WordRef> wrfs in results.Values) {
                if (firstTime) {
                    resultList = wrfs.Select(n => n.Key).ToList();
                    firstTime = false;
                    continue;
                }
                //resultList = resultList.Intersect(wrfs, comp).ToList();
                resultList = resultList.Intersect(wrfs.Select( n => n.Key )).ToList();
            }

            SortedList<int, QueryResult> queryResults = PivitQuery(results, resultList);

            // Rank the results!
            return RankResults(query, words, queryResults);
        }
        public static List<QueryResult> SearchTextQuery(string catalog, CultureInfo culture, string query)
        {
            readerLock.AcquireReaderLock(1000 * 60); // 60 second timeout
            TextIndex index = GetTextIndex(catalog, culture);

            // Get all of the words (front match)
            List<Word> queryWordsList = index.WordBreaker.BreakWords(query);
            List<Synonym> wordList = queryWordsList.Select(n => new Synonym() { OriginalWord = n.WordText }).ToList();

            Dictionary<Synonym, List<WordRef>> results = new Dictionary<Synonym, List<WordRef>>();
            foreach (Synonym word in wordList) {
                List<WordRef> res = index.FindWord(word.OriginalWord);
                results.Add(word, res);
            }
            readerLock.ReleaseReaderLock();

            // intersect the results -- what word ref's contain all phrases searched for
            List<int> resultList = new List<int>();
            WordRefEqualityComparer comp = new WordRefEqualityComparer();
            bool firstTime = true;
            foreach (List<WordRef> wrfs in results.Values) {
                if (firstTime) {
                    resultList = wrfs.Select(n => n.Key).ToList();
                    firstTime = false;
                    continue;
                }
                resultList = resultList.Intersect(wrfs.Select(n => n.Key)).ToList();
            }

            SortedList<int, QueryResult> queryResult = PivitQuery(results, resultList);
            return RankResults(query, wordList, queryResult);
        }