public IEnumerable Match(string pattern)
#endif
        {
            if (caseInsensitive)
            {
                pattern = pattern.ToLower();
            }
            int firstWildcard = findWildcard(pattern);

            if (firstWildcard < 0)
            { // exact match
                return(Range(pattern, pattern, IterationOrder.AscentOrder));
            }
            else if (firstWildcard == pattern.Length - 1 && pattern[firstWildcard] == '%')
            { // pattern like 'XYZ%': use prefix search
                return(StartsWith(pattern.Substring(0, firstWildcard)));
            }
            else if (firstWildcard >= nGrams * 2 || firstWildcard > pattern.Length - nGrams)
            { // better to use prefix  search
                return(new RegexEnumerable(this, StartsWith(pattern.Substring(0, firstWildcard)), pattern));
            }
            else
            {
                string[] ngrams = splitPattern(pattern);
                if (ngrams.Length == 0)
                { // no n-grams: have to use sequential scan
                    return(new RegexEnumerable(this, this, pattern));
                }
#if USE_GENERICS
                Perst.ISet <T>[] sets = new Perst.ISet <T> [ngrams.Length];
                for (int i = 0; i < sets.Length; i++)
                {
                    Perst.ISet <T> s = inverseIndex[ngrams[i]];
                    if (s == null)
                    {
                        return(new List <T>());
                    }
                    sets[i] = s;
                }
#else
                ISet[] sets = new ISet[ngrams.Length];
                for (int i = 0; i < sets.Length; i++)
                {
                    ISet s = (ISet)inverseIndex[ngrams[i]];
                    if (s == null)
                    {
                        return(new ArrayList());
                    }
                    sets[i] = s;
                }
#endif
                return(new JoinRegexEnumerable(this, sets, pattern));
            }
        }
 private void insertInInverseIndex(String text, T obj)
 {
     foreach (String s in splitText(text))
     {
         Perst.ISet <T> set = inverseIndex[s];
         if (set == null)
         {
             set             = Storage.CreateSet <T>();
             inverseIndex[s] = set;
         }
         set.Add(obj);
     }
 }
        private void removeFromInverseIndex(string text, object obj)
        {
            foreach (string s in splitText(text))
            {
#if USE_GENERICS
                Perst.ISet <T> set = inverseIndex[s];
                Debug.Assert(set != null);
                set.Remove((T)obj);
#else
                ISet set = (ISet)inverseIndex[s];
                Debug.Assert(set != null);
                set.Remove(obj);
#endif
            }
        }
        public override bool Equals(object o)
        {
            if (o == this)
            {
                return(true);
            }
#if USE_GENERICS
            Perst.ISet <T> s = o as Perst.ISet <T>;
#else
            ISet s = o as ISet;
#endif
            if (s == null)
            {
                return(false);
            }
            if (Count != s.Count)
            {
                return(false);
            }
            return(ContainsAll(s));
        }