public bool MoveNext()
            {
                while (true)
                {
                    while (pos < iterators.Length && !iterators[pos].MoveNext())
                    {
                        pos += 1;
                    }
                    if (pos == iterators.Length)
                    {
                        currThing = null;
                        return(false);
                    }
                    Thing thing = (Thing)iterators[pos].Current;
                    switch (kind)
                    {
                    case SearchKind.LatestVersion:
                        if (!thing.IsLatest())
                        {
                            continue;
                        }
                        break;

                    case SearchKind.LatestBefore:
                        if (thing.timestamp > timestamp)
                        {
                            continue;
                        }
                        break;

                    case SearchKind.OldestAfter:
                        if (thing.timestamp < timestamp)
                        {
                            continue;
                        }
                        break;
                    }
                    if (pos == 0)
                    {
                        if (visited.ContainsKey(thing.Oid))
                        {
                            continue;
                        }
                        else
                        {
                            visited[thing.Oid] = true;
                        }
                        currThing = thing;
                        return(true);
                    }
                    pos -= 1;
                    Key key = new Key(new object[] { defs[pos], thing.vh });
                    iterators[pos] = root.refPropIndex.GetEnumerator(key, key);
                }
            }
            private bool Match(Thing thing)
            {
                if (type != null && !thing.IsInstanceOf(type, kind, timestamp))
                {
                    return(false);
                }
                switch (kind)
                {
                case SearchKind.LatestVersion:
                    if (!thing.IsLatest())
                    {
                        return(false);
                    }
                    break;

                case SearchKind.LatestBefore:
                    if (thing.timestamp > timestamp || thing.vh.GetLatestBefore(timestamp) != thing)
                    {
                        return(false);
                    }
                    break;

                case SearchKind.OldestAfter:
                    if (thing.timestamp < timestamp || thing.vh.GetOldestAfter(timestamp) != thing)
                    {
                        return(false);
                    }
                    break;

                default:
                    break;
                }

                if (uri != null)
                {
                    if (!MatchString(thing.vh.uri, uri))
                    {
                        return(false);
                    }
                }
                for (int i = 0; i < patterns.Length; i++)
                {
                    if (!MatchProperty(patterns[i], thing))
                    {
                        return(false);
                    }
                }
                currThing = thing;
                return(true);
            }
            private bool Match(Thing thing) 
            { 
        
                if (type != null && !thing.IsInstanceOf(type, kind, timestamp)) 
                {
                    return false;
                }
                switch (kind) 
                { 
                    case SearchKind.LatestVersion:
                        if (!thing.IsLatest()) 
                        { 
                            return false;
                        }
                        break;
                    case SearchKind.LatestBefore:
                        if (thing.timestamp > timestamp || thing.vh.GetLatestBefore(timestamp) != thing) 
                        {
                            return false;
                        }
                        break;
                    case SearchKind.OldestAfter:
                        if (thing.timestamp < timestamp || thing.vh.GetOldestAfter(timestamp) != thing)
                        {
                            return false;
                        }
                        break;
                    default:
                        break;
                }

                if (uri != null) 
                { 
                    if (!MatchString(thing.vh.uri, uri)) 
                    { 
                        return false;
                    }
                }
                for (int i = 0; i < patterns.Length; i++) 
                { 
                    if (!MatchProperty(patterns[i], thing)) 
                    { 
                        return false;
                    }
                }
                currThing = thing;
                return true;
            }