2004-12-01 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml.XPath / Iterator.cs
index 1a49d8afa5cd87851aaf25515b12e8c43e7b39da..307fc6f2aaadc20c5fbb51ce5613e54a6cb0ce53 100644 (file)
@@ -157,8 +157,6 @@ namespace System.Xml.XPath
                                _iter = (BaseIterator) other._iter.Clone ();
                        else
                                _nav = other._nav.Clone ();
-                       if (other._current != null)
-                               _current = other._current.Clone ();
                }
                public SimpleIterator (XPathNavigator nav, NSResolver nsm) : base (nsm)
                {
@@ -178,7 +176,12 @@ namespace System.Xml.XPath
        {
                public SelfIterator (BaseIterator iter) : base (iter) {}
                public SelfIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
-               protected SelfIterator (SelfIterator other, bool clone) : base (other, true) {}
+               protected SelfIterator (SelfIterator other, bool clone) : base (other, true) 
+               {
+                       if (other._current != null)
+                               _current = _nav;
+               }
+
                public override XPathNodeIterator Clone () { return new SelfIterator (this, true); }
                public override bool MoveNextCore ()
                {
@@ -233,7 +236,11 @@ namespace System.Xml.XPath
        internal class ParentIterator : SimpleIterator
        {
                public ParentIterator (BaseIterator iter) : base (iter) {}
-               private ParentIterator (ParentIterator other) : base (other, true) {}
+               private ParentIterator (ParentIterator other) : base (other, true)
+               {
+                       if (other._current != null)
+                               _current = _nav;
+               }
                public ParentIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
                public override XPathNodeIterator Clone () { return new ParentIterator (this); }
                public override bool MoveNextCore ()
@@ -248,7 +255,7 @@ namespace System.Xml.XPath
 
                public override bool ReverseAxis { get { return true; } }
 
-               public override bool RequireSorting { get { return true; } }
+               public override bool RequireSorting { get { return false; } }
        }
 
        internal class ChildIterator : SimpleIterator
@@ -260,8 +267,7 @@ namespace System.Xml.XPath
                {
                        bool fSuccess = (CurrentPosition == 0) ? _nav.MoveToFirstChild () : _nav.MoveToNext ();
                        if (fSuccess) {
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                        }
                        return fSuccess;
                }
@@ -284,8 +290,7 @@ namespace System.Xml.XPath
                        }
                        if (_nav.MoveToNext ())
                        {
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                        return false;
@@ -303,15 +308,12 @@ namespace System.Xml.XPath
                public PrecedingSiblingIterator (BaseIterator iter) : base (iter)
                {
                        startPosition = iter.Current.Clone ();
-                       _current = startPosition.Clone ();
                }
                private PrecedingSiblingIterator (PrecedingSiblingIterator other) : base (other, true) 
                {
                        startPosition = other.startPosition;
                        started = other.started;
                        finished = other.finished;
-                       if (other._current != null)
-                               _current = other._current.Clone ();
                }
 
                public override XPathNodeIterator Clone () { return new PrecedingSiblingIterator (this); }
@@ -330,9 +332,8 @@ namespace System.Xml.XPath
                                }
 
                                _nav.MoveToFirst ();
-                               if (_nav.ComparePosition (startPosition) != XmlNodeOrder.Same) {
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                               if (!_nav.IsSamePosition (startPosition)) {
+                                       _current = null;
                                        return true;
                                }
                        } else {
@@ -346,8 +347,7 @@ namespace System.Xml.XPath
                                finished = true;
                                return false;
                        } else {
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                }
@@ -360,74 +360,59 @@ namespace System.Xml.XPath
 
        internal class AncestorIterator : SimpleIterator
        {
-               bool finished;
-               bool started;
-               ArrayList positions = new ArrayList ();
+               int currentPosition;
+               ArrayList navigators;
                XPathNavigator startPosition;
-               int nextDepth;
+
                public AncestorIterator (BaseIterator iter) : base (iter)
                {
                        startPosition = iter.Current.Clone ();
-                       _current = startPosition.Clone ();
                }
-               private AncestorIterator (AncestorIterator other) : base (other, true)
+
+               private AncestorIterator (AncestorIterator other)
+                       : base (other, true)
                {
                        startPosition = other.startPosition;
-                       started = other.started;
-                       finished = other.finished;
-                       positions = (ArrayList) other.positions.Clone ();
-                       nextDepth = other.nextDepth;
-                       if (other._current != null)
-                               _current = other._current.Clone ();
+                       if (other.navigators != null)
+                               navigators = (ArrayList) other.navigators.Clone ();
+                       currentPosition = other.currentPosition;
                }
-               public override XPathNodeIterator Clone () { return new AncestorIterator (this); }
-               public override bool MoveNextCore ()
+
+               public override XPathNodeIterator Clone ()
                {
-                       if (finished)
-                               return false;
-                       if (!started) {
-                               started = true;
-                               // This clone cannot be omitted
-                               XPathNavigator ancestors = startPosition.Clone ();
-                               ancestors.MoveToParent ();
-                               _nav.MoveToParent ();
-                               while (ancestors.NodeType != XPathNodeType.Root) {
-                                       int i = 0;
-                                       _nav.MoveToFirst ();
-                                       while (_nav.ComparePosition (ancestors) == XmlNodeOrder.Before) {
-                                               _nav.MoveToNext ();
-                                               i++;
-                                       }
-                                       positions.Add (i);
-                                       if (!ancestors.MoveToParent ())
-                                               break; // It is for detached nodes under XmlDocumentNavigator
-                                       _nav.MoveToParent ();
-                               }
+                       return new AncestorIterator (this);
+               }
 
+               private void CollectResults ()
+               {
+                       navigators = new ArrayList ();
 
-                               positions.Reverse ();
+                       XPathNavigator ancestors = startPosition.Clone ();
+                       if (!ancestors.MoveToParent ())
+                               return;
+                       while (ancestors.NodeType != XPathNodeType.Root) {
+                               navigators.Add (ancestors.Clone ());
+                               ancestors.MoveToParent ();
+                       }
+                       currentPosition = navigators.Count;
+               }
 
+               public override bool MoveNextCore ()
+               {
+                       if (navigators == null) {
+                               CollectResults ();
                                if (startPosition.NodeType != XPathNodeType.Root) {
                                        // First time it returns Root
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _nav.MoveToRoot ();
+                                       _current = null;
                                        return true;
                                }
                        }
-                       // Don't worry about node type of start position, like AncestorOrSelf.
-                       // It should be Element or Root.
-                       if (nextDepth < positions.Count) {
-                               int thisTimePos = (int) positions [nextDepth];
-                               _nav.MoveToFirstChild ();
-                               for (int i = 0; i < thisTimePos; i++)
-                                       _nav.MoveToNext ();
-                               nextDepth++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
-                               return true;
-                       }
-                       finished = true;
-                       return false;
+                       if (currentPosition == 0)
+                               return false;
+                       _nav.MoveTo ((XPathNavigator) navigators [--currentPosition]);
+                       _current = null;
+                       return true;
                }
 
                public override bool ReverseAxis {
@@ -436,80 +421,75 @@ namespace System.Xml.XPath
 
                public override bool RequireSorting { get { return true; } }
 
-               public override int Count { get { return positions.Count; } }
+               public override int Count {
+                       get {
+                               if (navigators == null)
+                                       CollectResults ();
+                               return navigators.Count;
+                       }
+               }
        }
 
        internal class AncestorOrSelfIterator : SimpleIterator
        {
-               bool finished;
-               bool started;
-               ArrayList positions = new ArrayList ();
+               int currentPosition;
+               ArrayList navigators;
                XPathNavigator startPosition;
-               int nextDepth;
 
                public AncestorOrSelfIterator (BaseIterator iter) : base (iter)
                {
                        startPosition = iter.Current.Clone ();
-                       _current = startPosition.Clone ();
                }
-               private AncestorOrSelfIterator (AncestorOrSelfIterator other) : base (other, true) 
+
+               private AncestorOrSelfIterator (AncestorOrSelfIterator other)
+                       : base (other, true)
                {
                        startPosition = other.startPosition;
-                       started = other.started;
-                       finished = other.finished;
-                       positions = (ArrayList) other.positions.Clone ();
-                       nextDepth = other.nextDepth;
-                       if (other._current != null)
-                               _current = other._current.Clone ();
+                       if (other.navigators != null)
+                               navigators = (ArrayList) other.navigators.Clone ();
+                       currentPosition = other.currentPosition;
+               }
+
+               public override XPathNodeIterator Clone ()
+               {
+                       return new AncestorOrSelfIterator (this);
+               }
+
+               private void CollectResults ()
+               {
+                       navigators = new ArrayList ();
+
+                       XPathNavigator ancestors = startPosition.Clone ();
+                       if (!ancestors.MoveToParent ())
+                               return;
+                       while (ancestors.NodeType != XPathNodeType.Root) {
+                               navigators.Add (ancestors.Clone ());
+                               ancestors.MoveToParent ();
+                       }
+                       currentPosition = navigators.Count;
                }
-               public override XPathNodeIterator Clone () { return new AncestorOrSelfIterator (this); }
+
                public override bool MoveNextCore ()
                {
-                       bool initialIteration = false;
-                       if (finished)
-                               return false;
-                       if (!started) {
-                               initialIteration = true;
-                               started = true;
-                               // This clone cannot be omitted
-                               XPathNavigator ancestors = startPosition.Clone ();
-                               do {
-                                       int i = 0;
-                                       _nav.MoveToFirst ();
-                                       while (_nav.ComparePosition (ancestors) == XmlNodeOrder.Before) {
-                                               _nav.MoveToNext ();
-                                               i++;
-                                       }
-                                       positions.Add (i);
-                                       if (!ancestors.MoveToParent ())
-                                               break; // for detached nodes under XmlDocumentNavigator.
-                                       _nav.MoveToParent ();
-                               } while (ancestors.NodeType != XPathNodeType.Root);
-                               positions.Reverse ();
+                       if (navigators == null) {
+                               CollectResults ();
+                               if (startPosition.NodeType != XPathNodeType.Root) {
+                                       // First time it returns Root
+                                       _nav.MoveToRoot ();
+                                       _current = null;
+                                       return true;
+                               }
                        }
-                       if (initialIteration && startPosition.NodeType != XPathNodeType.Root) {
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
-                               return true;
-                       } else if (nextDepth + 1 == positions.Count) {
-                               nextDepth++;
+                       if (currentPosition == -1)
+                               return false;
+                       if (currentPosition-- == 0) {
                                _nav.MoveTo (startPosition);
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
-                               return true;
+                               _current = null;
+                               return true; // returns self.
                        }
-                       else if (nextDepth < positions.Count) {
-                               int thisTimePos = (int) positions [nextDepth];
-                               _nav.MoveToFirstChild ();
-                               for (int i = 0; i < thisTimePos; i++)
-                                       _nav.MoveToNext ();
-                               nextDepth++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
-                               return true;
-                       }
-                       finished = true;
-                       return false;
+                       _nav.MoveTo ((XPathNavigator) navigators [currentPosition]);
+                       _current = null;
+                       return true;
                }
 
                public override bool ReverseAxis {
@@ -518,7 +498,13 @@ namespace System.Xml.XPath
 
                public override bool RequireSorting { get { return true; } }
 
-               public override int Count { get { return positions.Count; } }
+               public override int Count {
+                       get {
+                               if (navigators == null)
+                                       CollectResults ();
+                               return navigators.Count + 1;
+                       }
+               }
        }
 
        internal class DescendantIterator : SimpleIterator
@@ -532,8 +518,6 @@ namespace System.Xml.XPath
                {
                        _depth = other._depth;
                        _finished = other._finished;
-                       if (other._current != null)
-                               _current = other._current.Clone ();
                }
 
                public override XPathNodeIterator Clone () { return new DescendantIterator (this); }
@@ -546,16 +530,14 @@ namespace System.Xml.XPath
                        if (_nav.MoveToFirstChild ())
                        {
                                _depth ++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                        while (_depth != 0)
                        {
                                if (_nav.MoveToNext ())
                                {
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _current = null;
                                        return true;
                                }
                                if (!_nav.MoveToParent ())      // should NEVER fail!
@@ -579,8 +561,6 @@ namespace System.Xml.XPath
                private DescendantOrSelfIterator (DescendantOrSelfIterator other) : base (other, true)
                {
                        _depth = other._depth;
-                       if (other._current != null)
-                               _current = other._current.Clone ();
                }
 
                public override XPathNodeIterator Clone () { return new DescendantOrSelfIterator (this); }
@@ -593,23 +573,20 @@ namespace System.Xml.XPath
                        if (CurrentPosition == 0)
                        {
                                // self
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                        if (_nav.MoveToFirstChild ())
                        {
                                _depth ++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                        while (_depth != 0)
                        {
                                if (_nav.MoveToNext ())
                                {
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _current = null;
                                        return true;
                                }
                                if (!_nav.MoveToParent ())      // should NEVER fail!
@@ -637,14 +614,12 @@ namespace System.Xml.XPath
                        {
                                if (_nav.MoveToNext ())
                                {
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _current = null;
                                        return true;
                                } else {
                                        while (_nav.MoveToParent ()) {
                                                if (_nav.MoveToNext ()) {
-                                                       // This clone cannot be omitted
-                                                       _current = _nav.Clone ();
+                                                       _current = null;
                                                        return true;
                                                }
                                        }
@@ -654,16 +629,14 @@ namespace System.Xml.XPath
                        {
                                if (_nav.MoveToFirstChild ())
                                {
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _current = null;
                                        return true;
                                }
                                do
                                {
                                        if (_nav.MoveToNext ())
                                        {
-                                               // This clone cannot be omitted
-                                               _current = _nav.Clone ();
+                                               _current = null;
                                                return true;
                                        }
                                }
@@ -685,15 +658,12 @@ namespace System.Xml.XPath
                public PrecedingIterator (BaseIterator iter) : base (iter) 
                {
                        startPosition = iter.Current.Clone ();
-                       _current = startPosition.Clone ();
                }
                private PrecedingIterator (PrecedingIterator other) : base (other, true) 
                {
                        startPosition = other.startPosition;
                        started = other.started;
                        finished = other.finished;
-                       if (other._current != null)
-                               _current = other._current.Clone ();
                }
                public override XPathNodeIterator Clone () { return new PrecedingIterator (this); }
                public override bool MoveNextCore ()
@@ -725,8 +695,7 @@ namespace System.Xml.XPath
                                finished = true;
                                return false;
                        } else {
-                               // This cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                }
@@ -748,15 +717,13 @@ namespace System.Xml.XPath
                        {
                                if (_nav.MoveToFirstNamespace ())
                                {
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _current = null;
                                        return true;
                                }
                        }
                        else if (_nav.MoveToNextNamespace ())
                        {
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                        return false;
@@ -777,15 +744,13 @@ namespace System.Xml.XPath
                        {
                                if (_nav.MoveToFirstAttribute ())
                                {
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _current = null;
                                        return true;
                                }
                        }
                        else if (_nav.MoveToNextAttribute ())
                        {
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                        return false;                   
@@ -869,6 +834,8 @@ namespace System.Xml.XPath
                {
                        _iterLeft = iter;
                        _expr = expr;
+                       if (_iterLeft.RequireSorting || _expr.RequireSorting)
+                               CollectResults ();
                }
 
                private SlashIterator (SlashIterator other) : base (other)
@@ -891,112 +858,106 @@ namespace System.Xml.XPath
                {
                        if (_finished)
                                return false;
-                       if (RequireSorting) {
-                               if (_navStore == null) {
-                                       CollectResults ();
-                                       if (_navStore.Count == 0) {
-                                               _finished = true;
-                                               return false;
-                                       }
-                               }
+                       if (_navStore != null) {
+                               // Which requires sorting::
                                if (_navStore.Count < CurrentPosition + 1) {
                                        _finished = true;
                                        return false;
                                }
                                while (_navStore.Count > CurrentPosition + 1) {
-                                       if (((XPathNavigator) _navStore [CurrentPosition + 1]).ComparePosition (
-                                               (XPathNavigator) _navStore [CurrentPosition]) == XmlNodeOrder.Same)
+                                       if (((XPathNavigator) _navStore [CurrentPosition + 1]).IsSamePosition (
+                                               (XPathNavigator) _navStore [CurrentPosition]))
                                                _navStore.RemoveAt (CurrentPosition + 1);
                                        else
                                                break;
                                }
 
                                return true;
-                       } else {
-                               if (_iterRight == null) { // First time
-                                       if (!_iterLeft.MoveNext ())
+                       }
+                       // Which does not require sorting::
+                       
+                       if (_iterRight == null) { // First time
+                               if (!_iterLeft.MoveNext ())
+                                       return false;
+                               _iterRight = _expr.EvaluateNodeSet (_iterLeft);
+                               _iterList = new SortedList (XPathIteratorComparer.Instance);
+                       }
+
+                       while (true) {
+                               while (!_iterRight.MoveNext ()) {
+                                       if (_iterList.Count > 0) {
+                                               int last = _iterList.Count - 1;
+                                               BaseIterator tmpIter = (BaseIterator) _iterList.GetByIndex (last);
+                                               _iterList.RemoveAt (last);
+                                               switch (tmpIter.Current.ComparePosition (_iterRight.Current)) {
+                                               case XmlNodeOrder.Same:
+                                               case XmlNodeOrder.Before:
+                                                       _iterRight = tmpIter;
+                                                       continue;
+                                               default:
+                                                       _iterRight = tmpIter;
+                                                       break;
+                                               }
+                                               break;
+                                       } else if (_nextIterRight != null) {
+                                               _iterRight = _nextIterRight;
+                                               _nextIterRight = null;
+                                               break;
+                                       } else if (!_iterLeft.MoveNext ()) {
+                                               _finished = true;
                                                return false;
-                                       _iterRight = _expr.EvaluateNodeSet (_iterLeft);
-                                       _iterList = new SortedList (XPathIteratorComparer.Instance);
+                                       }
+                                       else
+                                               _iterRight = _expr.EvaluateNodeSet (_iterLeft);
                                }
-
-                               while (true) {
-                                       while (!_iterRight.MoveNext ()) {
-                                               if (_iterList.Count > 0) {
-                                                       int last = _iterList.Count - 1;
-                                                       BaseIterator tmpIter = (BaseIterator) _iterList.GetByIndex (last);
-                                                       _iterList.RemoveAt (last);
-                                                       switch (tmpIter.Current.ComparePosition (_iterRight.Current)) {
-                                                       case XmlNodeOrder.Same:
-                                                       case XmlNodeOrder.Before:
-                                                               _iterRight = tmpIter;
-                                                               continue;
-                                                       default:
-                                                               _iterRight = tmpIter;
+                               bool loop = true;
+                               while (loop) {
+                                       loop = false;
+                                       if (_nextIterRight == null) {
+                                               bool noMoreNext = false;
+                                               while (_nextIterRight == null || !_nextIterRight.MoveNext ()) {
+                                                       if(_iterLeft.MoveNext ())
+                                                               _nextIterRight = _expr.EvaluateNodeSet (_iterLeft);
+                                                       else {
+                                                               noMoreNext = true;
                                                                break;
                                                        }
-                                                       break;
-                                               } else if (_nextIterRight != null) {
+                                               }
+                                               if (noMoreNext)
+                                                       _nextIterRight = null; // FIXME: More efficient code. Maybe making noMoreNext class scope would be better.
+                                       }
+                                       if (_nextIterRight != null) {
+                                               switch (_iterRight.Current.ComparePosition (_nextIterRight.Current)) {
+                                               case XmlNodeOrder.After:
+                                                       _iterList.Add (_iterList.Count, _iterRight);
                                                        _iterRight = _nextIterRight;
                                                        _nextIterRight = null;
+                                                       loop = true;
                                                        break;
-                                               } else if (!_iterLeft.MoveNext ()) {
-                                                       _finished = true;
-                                                       return false;
-                                               }
-                                               else
-                                                       _iterRight = _expr.EvaluateNodeSet (_iterLeft);
-                                       }
-                                       bool loop = true;
-                                       while (loop) {
-                                               loop = false;
-                                               if (_nextIterRight == null) {
-                                                       bool noMoreNext = false;
-                                                       while (_nextIterRight == null || !_nextIterRight.MoveNext ()) {
-                                                               if(_iterLeft.MoveNext ())
-                                                                       _nextIterRight = _expr.EvaluateNodeSet (_iterLeft);
-                                                               else {
-                                                                       noMoreNext = true;
-                                                                       break;
-                                                               }
-                                                       }
-                                                       if (noMoreNext)
-                                                               _nextIterRight = null; // FIXME: More efficient code. Maybe making noMoreNext class scope would be better.
-                                               }
-                                               if (_nextIterRight != null) {
-                                                       switch (_iterRight.Current.ComparePosition (_nextIterRight.Current)) {
-                                                       case XmlNodeOrder.After:
-                                                               _iterList.Add (_iterList.Count, _iterRight);
-                                                               _iterRight = _nextIterRight;
+                                               case XmlNodeOrder.Same:
+                                                       if (!_nextIterRight.MoveNext ())
                                                                _nextIterRight = null;
-                                                               loop = true;
-                                                               break;
-                                                       case XmlNodeOrder.Same:
-                                                               if (!_nextIterRight.MoveNext ())
-                                                                       _nextIterRight = null;
-
-                                                               else {
-                                                                       int last = _iterList.Count;
-                                                                       if (last > 0) {
-                                                                               _iterList.Add (last, _nextIterRight);
-                                                                               _nextIterRight = (BaseIterator) _iterList.GetByIndex (last);
-                                                                               _iterList.RemoveAt (last);
-                                                                       }
-                                                               }
 
-                                                               loop = true;
-                                                               break;
+                                                       else {
+                                                               int last = _iterList.Count;
+                                                               if (last > 0) {
+                                                                       _iterList.Add (last, _nextIterRight);
+                                                                       _nextIterRight = (BaseIterator) _iterList.GetByIndex (last);
+                                                                       _iterList.RemoveAt (last);
+                                                               }
                                                        }
+
+                                                       loop = true;
+                                                       break;
                                                }
                                        }
-                                       return true;
                                }
+                               return true;
                        }
                }
+
                private void CollectResults ()
                {
-                       if (_navStore != null)
-                               return;
                        _navStore = new ArrayList ();
                        while (true) {
                                while (_iterRight == null || !_iterRight.MoveNext ()) {
@@ -1014,7 +975,7 @@ namespace System.Xml.XPath
                public override XPathNavigator Current { 
                        get {
                                if (CurrentPosition <= 0) return null;
-                               if (RequireSorting) {
+                               if (_navStore != null) {
                                        return (XPathNavigator) _navStore [CurrentPosition - 1];
                                } else {
                                        return _iterRight.Current;
@@ -1023,9 +984,8 @@ namespace System.Xml.XPath
                }
 
                public override bool RequireSorting {
-                       get {
-                               return _iterLeft.RequireSorting || _expr.RequireSorting;
-                       }
+                       // It always does not need to be sorted.
+                       get { return false; }
                }
 
                public override int Count { get { return _navStore == null ? base.Count : _navStore.Count; } }
@@ -1087,7 +1047,7 @@ namespace System.Xml.XPath
                        get { return _iter.ReverseAxis; }
                }
 
-               public override bool RequireSorting { get { return true; } }
+               public override bool RequireSorting { get { return _iter.RequireSorting || _pred.RequireSorting; } }
        }
 
        internal class ListIterator : BaseIterator