2004-12-01 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml.XPath / Iterator.cs
index 5884c5156a47eab26ec86d423ac5815afa2f455b..307fc6f2aaadc20c5fbb51ce5613e54a6cb0ce53 100644 (file)
@@ -36,23 +36,30 @@ using System.Xml;
 using System.Xml.XPath;
 using System.Xml.Xsl;
 
+#if NET_2_0
+using NSResolver = System.Xml.IXmlNamespaceResolver;
+#else
+using NSResolver = System.Xml.XmlNamespaceManager;
+#endif
+
 namespace System.Xml.XPath
 {
        internal abstract class BaseIterator : XPathNodeIterator
        {
-               private XmlNamespaceManager _nsm;
-               protected bool _needClone = true; // TODO: use this field in practice.
+               NSResolver _nsm;
+               int position;
 
                internal BaseIterator (BaseIterator other)
                {
                        _nsm = other._nsm;
+                       position = other.position;
                }
-               internal BaseIterator (XmlNamespaceManager nsm)
+               internal BaseIterator (NSResolver nsm)
                {
                        _nsm = nsm;
                }
 
-               public XmlNamespaceManager NamespaceManager
+               public NSResolver NamespaceManager
                {
                        get { return _nsm; }
                        set { _nsm = value; }
@@ -75,6 +82,20 @@ namespace System.Xml.XPath
                        }
                }
 
+               public override int CurrentPosition {
+                       get { return position; }
+               }
+
+               public override bool MoveNext ()
+               {
+                       if (!MoveNextCore ())
+                               return false;
+                       position++;
+                       return true;
+               }
+
+               public abstract bool MoveNextCore ();
+
                public override string ToString ()
                {
                        if (Current != null)
@@ -88,18 +109,24 @@ namespace System.Xml.XPath
        {
                XPathNodeIterator iter;
 
-               public WrapperIterator (XPathNodeIterator iter, XmlNamespaceManager nsm)
+               public WrapperIterator (XPathNodeIterator iter, NSResolver nsm)
                        : base (nsm)
                {
                        this.iter = iter;
                }
 
+               private WrapperIterator (WrapperIterator other)
+                       : base (other)
+               {
+                       iter = other.iter.Clone ();
+               }
+
                public override XPathNodeIterator Clone ()
                {
-                       return new WrapperIterator (iter.Clone (), NamespaceManager);
+                       return new WrapperIterator (this);
                }
 
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        return iter.MoveNext ();
                }
@@ -108,10 +135,6 @@ namespace System.Xml.XPath
                        get { return iter.Current; }
                }
 
-               public override int CurrentPosition {
-                       get { return iter.CurrentPosition; }
-               }
-
                public override bool RequireSorting {
                        get { return true; }
                }
@@ -122,45 +145,49 @@ namespace System.Xml.XPath
                protected readonly BaseIterator _iter;
                protected readonly XPathNavigator _nav;
                protected XPathNavigator _current;
-               protected int _pos;
 
-               public SimpleIterator (BaseIterator iter) : base (iter)
+               public SimpleIterator (BaseIterator iter) : base (iter.NamespaceManager)
                {
                        _iter = iter;
                        _nav = iter.Current.Clone ();
-                       _current = _nav.Clone ();
                }
-               protected SimpleIterator (SimpleIterator other) : base (other)
+               protected SimpleIterator (SimpleIterator other, bool clone) : base (other)
                {
                        if (other._nav == null)
                                _iter = (BaseIterator) other._iter.Clone ();
                        else
                                _nav = other._nav.Clone ();
-                       _pos = other._pos;
-                       _current = other._current.Clone ();
                }
-               public SimpleIterator (XPathNavigator nav, XmlNamespaceManager nsm) : base (nsm)
+               public SimpleIterator (XPathNavigator nav, NSResolver nsm) : base (nsm)
                {
                        _nav = nav.Clone ();
-                       _current = nav.Clone ();
                }
 
-               public override XPathNavigator Current { get { return _current; }}
-               public override int CurrentPosition { get { return _pos; }}
+               public override XPathNavigator Current {
+                       get {
+                               if (_current == null) // position == 0
+                                       _current = _nav.Clone ();
+                               return _current;
+                       }
+               }
        }
 
        internal class SelfIterator : SimpleIterator
        {
                public SelfIterator (BaseIterator iter) : base (iter) {}
-               public SelfIterator (XPathNavigator nav, XmlNamespaceManager nsm) : base (nav, nsm) {}
-               protected SelfIterator (SelfIterator other) : base (other) {}
-               public override XPathNodeIterator Clone () { return new SelfIterator (this); }
-               public override bool MoveNext ()
+               public SelfIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
+               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 ()
                {
-                       if (_pos == 0)
+                       if (CurrentPosition == 0)
                        {
-                               _pos = 1;
-                               _current = _needClone ? _nav.Clone () : _nav;
+                               _current = _nav;
                                return true;
                        }
                        return false;
@@ -173,10 +200,10 @@ namespace System.Xml.XPath
        {
                public NullIterator (BaseIterator iter) : base (iter) {}
                public NullIterator (XPathNavigator nav) : this (nav, null) {}
-               public NullIterator (XPathNavigator nav, XmlNamespaceManager nsm) : base (nav, nsm) {}
-               protected NullIterator (NullIterator other) : base (other) {}
+               public NullIterator (XPathNavigator nav, NSResolver nsm) : base (nav, nsm) {}
+               private NullIterator (NullIterator other) : base (other, true) {}
                public override XPathNodeIterator Clone () { return new NullIterator (this); }
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        return false;
                }
@@ -185,22 +212,21 @@ namespace System.Xml.XPath
        internal class ParensIterator : BaseIterator
        {
                BaseIterator _iter;
-               public ParensIterator (BaseIterator iter) : base (iter) 
+               public ParensIterator (BaseIterator iter) : base (iter.NamespaceManager
                {
                        _iter = iter;
                }
-               protected ParensIterator (ParensIterator other) : base (other) 
+               private ParensIterator (ParensIterator other) : base (other) 
                {
                        _iter = (BaseIterator) other._iter.Clone ();
                }
                public override XPathNodeIterator Clone () { return new ParensIterator (this); }
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        return _iter.MoveNext ();
                }
 
                public override XPathNavigator Current { get { return _iter.Current; }}
-               public override int CurrentPosition { get { return _iter.CurrentPosition; } }
 
                public override bool RequireSorting { get { return _iter.RequireSorting; } }
 
@@ -210,15 +236,18 @@ namespace System.Xml.XPath
        internal class ParentIterator : SimpleIterator
        {
                public ParentIterator (BaseIterator iter) : base (iter) {}
-               protected ParentIterator (ParentIterator other) : base (other) {}
-               public ParentIterator (XPathNavigator nav, XmlNamespaceManager nsm) : base (nav, nsm) {}
+               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 MoveNext ()
+               public override bool MoveNextCore ()
                {
-                       if (_pos == 0 && _nav.MoveToParent ())
+                       if (CurrentPosition == 0 && _nav.MoveToParent ())
                        {
-                               _pos = 1;
-                               _current = _needClone ? _nav.Clone () : _nav;
+                               _current = _nav;
                                return true;
                        }
                        return false;
@@ -226,21 +255,19 @@ 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
        {
                public ChildIterator (BaseIterator iter) : base (iter) {}
-               protected ChildIterator (ChildIterator other) : base (other) {}
+               private ChildIterator (ChildIterator other) : base (other, true) {}
                public override XPathNodeIterator Clone () { return new ChildIterator (this); }
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
-                       bool fSuccess = (_pos == 0) ? _nav.MoveToFirstChild () : _nav.MoveToNext ();
+                       bool fSuccess = (CurrentPosition == 0) ? _nav.MoveToFirstChild () : _nav.MoveToNext ();
                        if (fSuccess) {
-                               _pos ++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                        }
                        return fSuccess;
                }
@@ -251,9 +278,9 @@ namespace System.Xml.XPath
        internal class FollowingSiblingIterator : SimpleIterator
        {
                public FollowingSiblingIterator (BaseIterator iter) : base (iter) {}
-               protected FollowingSiblingIterator (FollowingSiblingIterator other) : base (other) {}
+               private FollowingSiblingIterator (FollowingSiblingIterator other) : base (other, true) {}
                public override XPathNodeIterator Clone () { return new FollowingSiblingIterator (this); }
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        switch (_nav.NodeType) {
                        case XPathNodeType.Attribute:
@@ -263,9 +290,7 @@ namespace System.Xml.XPath
                        }
                        if (_nav.MoveToNext ())
                        {
-                               _pos ++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                        return false;
@@ -283,18 +308,16 @@ namespace System.Xml.XPath
                public PrecedingSiblingIterator (BaseIterator iter) : base (iter)
                {
                        startPosition = iter.Current.Clone ();
-                       _current = startPosition.Clone ();
                }
-               protected PrecedingSiblingIterator (PrecedingSiblingIterator other) : base (other
+               private PrecedingSiblingIterator (PrecedingSiblingIterator other) : base (other, true
                {
                        startPosition = other.startPosition;
                        started = other.started;
                        finished = other.finished;
-                       _current = other._current.Clone ();
                }
 
                public override XPathNodeIterator Clone () { return new PrecedingSiblingIterator (this); }
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        if (finished)
                                return false;
@@ -309,10 +332,8 @@ namespace System.Xml.XPath
                                }
 
                                _nav.MoveToFirst ();
-                               if (_nav.ComparePosition (startPosition) != XmlNodeOrder.Same) {
-                                       _pos++;
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                               if (!_nav.IsSamePosition (startPosition)) {
+                                       _current = null;
                                        return true;
                                }
                        } else {
@@ -326,9 +347,7 @@ namespace System.Xml.XPath
                                finished = true;
                                return false;
                        } else {
-                               _pos ++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                }
@@ -341,75 +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 ();
                }
-               protected AncestorIterator (AncestorIterator other) : base (other)
+
+               private AncestorIterator (AncestorIterator other)
+                       : base (other, true)
                {
                        startPosition = other.startPosition;
-                       started = other.started;
-                       finished = other.finished;
-                       positions = (ArrayList) other.positions.Clone ();
-                       nextDepth = other.nextDepth;
-                       _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 MoveNext ()
+
+               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
-                                       _pos++;
-                                       // 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++;
-                               _pos++;
-                               // 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 {
@@ -418,81 +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 ();
                }
-               protected AncestorOrSelfIterator (AncestorOrSelfIterator other) : base (other) 
+
+               private AncestorOrSelfIterator (AncestorOrSelfIterator other)
+                       : base (other, true)
                {
                        startPosition = other.startPosition;
-                       started = other.started;
-                       finished = other.finished;
-                       positions = (ArrayList) other.positions.Clone ();
-                       nextDepth = other.nextDepth;
-                       _current = other._current.Clone ();
+                       if (other.navigators != null)
+                               navigators = (ArrayList) other.navigators.Clone ();
+                       currentPosition = other.currentPosition;
                }
-               public override XPathNodeIterator Clone () { return new AncestorOrSelfIterator (this); }
-               public override bool MoveNext ()
+
+               public override XPathNodeIterator Clone ()
                {
-                       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 ();
+                       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 ();
                        }
-                       if (initialIteration && startPosition.NodeType != XPathNodeType.Root) {
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
-                               return true;
-                       } else if (nextDepth + 1 == positions.Count) {
-                               nextDepth++;
-                               _pos++;
-                               _nav.MoveTo (startPosition);
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
-                               return true;
+                       currentPosition = navigators.Count;
+               }
+
+               public override bool MoveNextCore ()
+               {
+                       if (navigators == null) {
+                               CollectResults ();
+                               if (startPosition.NodeType != XPathNodeType.Root) {
+                                       // First time it returns Root
+                                       _nav.MoveToRoot ();
+                                       _current = null;
+                                       return true;
+                               }
                        }
-                       else if (nextDepth < positions.Count) {
-                               int thisTimePos = (int) positions [nextDepth];
-                               _nav.MoveToFirstChild ();
-                               for (int i = 0; i < thisTimePos; i++)
-                                       _nav.MoveToNext ();
-                               nextDepth++;
-                               _pos++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
-                               return true;
+                       if (currentPosition == -1)
+                               return false;
+                       if (currentPosition-- == 0) {
+                               _nav.MoveTo (startPosition);
+                               _current = null;
+                               return true; // returns self.
                        }
-                       finished = true;
-                       return false;
+                       _nav.MoveTo ((XPathNavigator) navigators [currentPosition]);
+                       _current = null;
+                       return true;
                }
 
                public override bool ReverseAxis {
@@ -501,26 +498,31 @@ 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
        {
-               protected int _depth;
+               private int _depth;
                private bool _finished;
 
                public DescendantIterator (BaseIterator iter) : base (iter) {}
 
-               protected DescendantIterator (DescendantIterator other) : base (other)
+               private DescendantIterator (DescendantIterator other) : base (other)
                {
                        _depth = other._depth;
                        _finished = other._finished;
-                       _current = other._current.Clone ();
                }
 
                public override XPathNodeIterator Clone () { return new DescendantIterator (this); }
 
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        if (_finished)
                                return false;
@@ -528,18 +530,14 @@ namespace System.Xml.XPath
                        if (_nav.MoveToFirstChild ())
                        {
                                _depth ++;
-                               _pos ++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                        while (_depth != 0)
                        {
                                if (_nav.MoveToNext ())
                                {
-                                       _pos ++;
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _current = null;
                                        return true;
                                }
                                if (!_nav.MoveToParent ())      // should NEVER fail!
@@ -555,47 +553,40 @@ namespace System.Xml.XPath
 
        internal class DescendantOrSelfIterator : SimpleIterator
        {
-               protected int _depth;
+               private int _depth;
                private bool _finished;
 
                public DescendantOrSelfIterator (BaseIterator iter) : base (iter) {}
 
-               protected DescendantOrSelfIterator (DescendantOrSelfIterator other) : base (other)
+               private DescendantOrSelfIterator (DescendantOrSelfIterator other) : base (other, true)
                {
                        _depth = other._depth;
-                       _current = other._current.Clone ();
                }
 
                public override XPathNodeIterator Clone () { return new DescendantOrSelfIterator (this); }
 
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        if (_finished)
                                return false;
 
-                       if (_pos == 0)
+                       if (CurrentPosition == 0)
                        {
                                // self
-                               _pos ++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                        if (_nav.MoveToFirstChild ())
                        {
                                _depth ++;
-                               _pos ++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                        while (_depth != 0)
                        {
                                if (_nav.MoveToNext ())
                                {
-                                       _pos ++;
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _current = null;
                                        return true;
                                }
                                if (!_nav.MoveToParent ())      // should NEVER fail!
@@ -613,26 +604,22 @@ namespace System.Xml.XPath
        {
                private bool _finished = false;
                public FollowingIterator (BaseIterator iter) : base (iter) {}
-               protected FollowingIterator (FollowingIterator other) : base (other) {}
+               private FollowingIterator (FollowingIterator other) : base (other, true) {}
                public override XPathNodeIterator Clone () { return new FollowingIterator (this); }
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        if (_finished)
                                return false;
-                       if (_pos == 0)
+                       if (CurrentPosition == 0)
                        {
                                if (_nav.MoveToNext ())
                                {
-                                       _pos ++;
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _current = null;
                                        return true;
                                } else {
                                        while (_nav.MoveToParent ()) {
                                                if (_nav.MoveToNext ()) {
-                                                       _pos ++;
-                                                       // This clone cannot be omitted
-                                                       _current = _nav.Clone ();
+                                                       _current = null;
                                                        return true;
                                                }
                                        }
@@ -642,18 +629,14 @@ namespace System.Xml.XPath
                        {
                                if (_nav.MoveToFirstChild ())
                                {
-                                       _pos ++;
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _current = null;
                                        return true;
                                }
                                do
                                {
                                        if (_nav.MoveToNext ())
                                        {
-                                               _pos ++;
-                                               // This clone cannot be omitted
-                                               _current = _nav.Clone ();
+                                               _current = null;
                                                return true;
                                        }
                                }
@@ -675,17 +658,15 @@ namespace System.Xml.XPath
                public PrecedingIterator (BaseIterator iter) : base (iter) 
                {
                        startPosition = iter.Current.Clone ();
-                       _current = startPosition.Clone ();
                }
-               protected PrecedingIterator (PrecedingIterator other) : base (other
+               private PrecedingIterator (PrecedingIterator other) : base (other, true
                {
                        startPosition = other.startPosition;
                        started = other.started;
                        finished = other.finished;
-                       _current = other._current.Clone ();
                }
                public override XPathNodeIterator Clone () { return new PrecedingIterator (this); }
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        if (finished)
                                return false;
@@ -714,9 +695,7 @@ namespace System.Xml.XPath
                                finished = true;
                                return false;
                        } else {
-                               _pos ++;
-                               // This cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                }
@@ -730,25 +709,21 @@ namespace System.Xml.XPath
        internal class NamespaceIterator : SimpleIterator
        {
                public NamespaceIterator (BaseIterator iter) : base (iter) {}
-               protected NamespaceIterator (NamespaceIterator other) : base (other) {}
+               private NamespaceIterator (NamespaceIterator other) : base (other, true) {}
                public override XPathNodeIterator Clone () { return new NamespaceIterator (this); }
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
-                       if (_pos == 0)
+                       if (CurrentPosition == 0)
                        {
                                if (_nav.MoveToFirstNamespace ())
                                {
-                                       _pos ++;
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _current = null;
                                        return true;
                                }
                        }
                        else if (_nav.MoveToNextNamespace ())
                        {
-                               _pos ++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                        return false;
@@ -761,25 +736,21 @@ namespace System.Xml.XPath
        internal class AttributeIterator : SimpleIterator
        {
                public AttributeIterator (BaseIterator iter) : base (iter) {}
-               protected AttributeIterator (AttributeIterator other) : base (other) {}
+               private AttributeIterator (AttributeIterator other) : base (other, true) {}
                public override XPathNodeIterator Clone () { return new AttributeIterator (this); }
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
-                       if (_pos == 0)
+                       if (CurrentPosition == 0)
                        {
                                if (_nav.MoveToFirstAttribute ())
                                {
-                                       _pos += 1;
-                                       // This clone cannot be omitted
-                                       _current = _nav.Clone ();
+                                       _current = null;
                                        return true;
                                }
                        }
                        else if (_nav.MoveToNextAttribute ())
                        {
-                               _pos ++;
-                               // This clone cannot be omitted
-                               _current = _nav.Clone ();
+                               _current = null;
                                return true;
                        }
                        return false;                   
@@ -790,14 +761,13 @@ namespace System.Xml.XPath
 
        internal class AxisIterator : BaseIterator
        {
-               protected SimpleIterator _iter;
-               protected NodeTest _test;
-               protected int _pos;
+               private SimpleIterator _iter;
+               private NodeTest _test;
                        
                string name, ns;
                XPathNodeType matchType;
 
-               public AxisIterator (SimpleIterator iter, NodeTest test) : base (iter)
+               public AxisIterator (SimpleIterator iter, NodeTest test) : base (iter.NamespaceManager)
                {
                        _iter = iter;
                        _test = test;
@@ -809,31 +779,28 @@ namespace System.Xml.XPath
 //                             ns = Current.NameTable.Add (ns);
                }
 
-               protected AxisIterator (AxisIterator other) : base (other)
+               private AxisIterator (AxisIterator other) : base (other)
                {
                        _iter = (SimpleIterator) other._iter.Clone ();
                        _test = other._test;
-                       _pos = other._pos;
                        name = other.name;
                        ns = other.ns;
                        matchType = other.matchType;
                }
                public override XPathNodeIterator Clone () { return new AxisIterator (this); }
 
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        while (_iter.MoveNext ())
                        {
                                if (_test.Match (NamespaceManager, Current))
                                {
-                                       _pos ++;
                                        return true;
                                }
                        }
                        return false;
                }
                public override XPathNavigator Current { get { return _iter.Current; }}
-               public override int CurrentPosition { get { return _pos; }}
                
                bool Match ()
                {
@@ -855,28 +822,28 @@ namespace System.Xml.XPath
 
        internal class SlashIterator : BaseIterator
        {
-               protected BaseIterator _iterLeft;
-               protected BaseIterator _iterRight;
-               protected NodeSet _expr;
-               protected int _pos;
+               private BaseIterator _iterLeft;
+               private BaseIterator _iterRight;
+               private NodeSet _expr;
                ArrayList _navStore;
                SortedList _iterList;
                bool _finished;
                BaseIterator _nextIterRight;
 
-               public SlashIterator (BaseIterator iter, NodeSet expr) : base (iter)
+               public SlashIterator (BaseIterator iter, NodeSet expr) : base (iter.NamespaceManager)
                {
                        _iterLeft = iter;
                        _expr = expr;
+                       if (_iterLeft.RequireSorting || _expr.RequireSorting)
+                               CollectResults ();
                }
 
-               protected SlashIterator (SlashIterator other) : base (other)
+               private SlashIterator (SlashIterator other) : base (other)
                {
                        _iterLeft = (BaseIterator) other._iterLeft.Clone ();
                        if (other._iterRight != null)
                                _iterRight = (BaseIterator) other._iterRight.Clone ();
                        _expr = other._expr;
-                       _pos = other._pos;
                        if (other._iterList != null)
                                _iterList = (SortedList) other._iterList.Clone ();
                        if (other._navStore != null)
@@ -887,119 +854,110 @@ namespace System.Xml.XPath
                }
                public override XPathNodeIterator Clone () { return new SlashIterator (this); }
 
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        if (_finished)
                                return false;
-                       if (RequireSorting) {
-                               if (_navStore == null) {
-                                       CollectResults ();
-                                       if (_navStore.Count == 0) {
-                                               _finished = true;
-                                               return false;
-                                       }
-                               }
-                               _pos++;
-                               if (_navStore.Count < _pos) {
+                       if (_navStore != null) {
+                               // Which requires sorting::
+                               if (_navStore.Count < CurrentPosition + 1) {
                                        _finished = true;
-                                       _pos--;
                                        return false;
                                }
-                               while (_navStore.Count > _pos) {
-                                       if (((XPathNavigator) _navStore [_pos]).ComparePosition (
-                                               (XPathNavigator) _navStore [_pos - 1]) == XmlNodeOrder.Same)
-                                               _navStore.RemoveAt (_pos);
+                               while (_navStore.Count > CurrentPosition + 1) {
+                                       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;
                                                }
                                        }
-                                       _pos ++;
-                                       return true;
                                }
+                               return true;
                        }
                }
+
                private void CollectResults ()
                {
-                       if (_navStore != null)
-                               return;
                        _navStore = new ArrayList ();
                        while (true) {
                                while (_iterRight == null || !_iterRight.MoveNext ()) {
@@ -1010,26 +968,24 @@ namespace System.Xml.XPath
                                        _iterRight = _expr.EvaluateNodeSet (_iterLeft);
                                }
                                XPathNavigator nav = _iterRight.Current;
-                               _navStore.Add (_needClone ? nav.Clone () : nav);
+                               _navStore.Add (nav);
                        }
                }
 
                public override XPathNavigator Current { 
                        get {
-                               if (_pos <= 0) return null;
-                               if (RequireSorting) {
-                                       return (XPathNavigator) _navStore [_pos - 1];
+                               if (CurrentPosition <= 0) return null;
+                               if (_navStore != null) {
+                                       return (XPathNavigator) _navStore [CurrentPosition - 1];
                                } else {
                                        return _iterRight.Current;
                                }
                        }
                }
-               public override int CurrentPosition { get { return _pos; }}
 
                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; } }
@@ -1037,28 +993,26 @@ namespace System.Xml.XPath
 
        internal class PredicateIterator : BaseIterator
        {
-               protected BaseIterator _iter;
-               protected Expression _pred;
-               protected int _pos;
-               protected XPathResultType resType;
+               private BaseIterator _iter;
+               private Expression _pred;
+               private XPathResultType resType;
 
-               public PredicateIterator (BaseIterator iter, Expression pred) : base (iter)
+               public PredicateIterator (BaseIterator iter, Expression pred) : base (iter.NamespaceManager)
                {
                        _iter = iter;
                        _pred = pred;
                        resType = pred.GetReturnType (iter);
                }
 
-               protected PredicateIterator (PredicateIterator other) : base (other)
+               private PredicateIterator (PredicateIterator other) : base (other)
                {
                        _iter = (BaseIterator) other._iter.Clone ();
                        _pred = other._pred;
-                       _pos = other._pos;
                        resType = other.resType;
                }
                public override XPathNodeIterator Clone () { return new PredicateIterator (this); }
 
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        while (_iter.MoveNext ())
                        {
@@ -1084,73 +1038,24 @@ namespace System.Xml.XPath
                                                break;
                                }
 
-                               _pos ++;
                                return true;
                        }
                        return false;
                }
                public override XPathNavigator Current { get { return _iter.Current; }}
-               public override int CurrentPosition { get { return _pos; }}
                public override bool ReverseAxis {
                        get { return _iter.ReverseAxis; }
                }
 
-               public override bool RequireSorting { get { return true; } }
-       }
-
-       /*
-       internal class EnumeratorIterator : BaseIterator
-       {
-               protected IEnumerator _enum;
-               protected int _pos;
-               bool _requireSorting;
-
-               public EnumeratorIterator (BaseIterator iter, IEnumerator enumerator, bool requireSorting) : base (iter)
-               {
-                       if (!(enumerator is ICloneable))
-                               throw new ArgumentException ("Target enumerator must be cloneable.");
-                       _enum = enumerator;
-                       _requireSorting = requireSorting;
-               }
-               
-               public EnumeratorIterator (IEnumerator enumerator, XmlNamespaceManager nsm, bool requireSorting) : base (nsm)
-               {
-                       if (!(enumerator is ICloneable))
-                               throw new ArgumentException ("Target enumerator must be cloneable.");
-                       _enum = enumerator;
-                       _requireSorting = requireSorting;
-               }
-
-               protected EnumeratorIterator (EnumeratorIterator other) : base (other)
-               {
-                       ICloneable enumClone = other._enum as ICloneable;
-                       _enum = (IEnumerator) enumClone.Clone ();
-                       _pos = other._pos;
-                       _requireSorting = other._requireSorting;
-               }
-               public override XPathNodeIterator Clone () { return new EnumeratorIterator (this); }
-
-               public override bool MoveNext ()
-               {
-                       if (!_enum.MoveNext ())
-                               return false;
-                       _pos++;
-                       return true;
-               }
-               public override XPathNavigator Current { get { return (XPathNavigator) _enum.Current; }}
-               public override int CurrentPosition { get { return _pos; }}
-
-               public override bool RequireSorting { get { return _requireSorting; } }
+               public override bool RequireSorting { get { return _iter.RequireSorting || _pred.RequireSorting; } }
        }
-       */
 
        internal class ListIterator : BaseIterator
        {
-               protected IList _list;
-               protected int _pos;
+               private IList _list;
                bool _requireSorting;
 
-               public ListIterator (BaseIterator iter, IList list, bool requireSorting) : base (iter)
+               public ListIterator (BaseIterator iter, IList list, bool requireSorting) : base (iter.NamespaceManager)
                {
                        if (!(list is ICloneable))
                                throw new ArgumentException ("Target enumerator must be cloneable.");
@@ -1158,7 +1063,7 @@ namespace System.Xml.XPath
                        _requireSorting = requireSorting;
                }
                
-               public ListIterator (IList list, XmlNamespaceManager nsm, bool requireSorting) : base (nsm)
+               public ListIterator (IList list, NSResolver nsm, bool requireSorting) : base (nsm)
                {
                        if (!(list is ICloneable))
                                throw new ArgumentException ("Target enumerator must be cloneable.");
@@ -1166,30 +1071,27 @@ namespace System.Xml.XPath
                        _requireSorting = requireSorting;
                }
 
-               protected ListIterator (ListIterator other) : base (other)
+               private ListIterator (ListIterator other) : base (other)
                {
                        ICloneable listClone = other._list as ICloneable;
                        _list = (IList) listClone.Clone ();
-                       _pos = other._pos;
                        _requireSorting = other._requireSorting;
                }
                public override XPathNodeIterator Clone () { return new ListIterator (this); }
 
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
-                       if (_pos >= _list.Count)
+                       if (CurrentPosition >= _list.Count)
                                return false;
-                       _pos++;
                        return true;
                }
                public override XPathNavigator Current {
                        get {
                                if (_list.Count == 0)
                                        return null;
-                               return (XPathNavigator) _list [_pos - 1]; 
+                               return (XPathNavigator) _list [CurrentPosition - 1]; 
                        }
                }
-               public override int CurrentPosition { get { return _pos; }}
 
                public override bool RequireSorting { get { return _requireSorting; } }
 
@@ -1199,30 +1101,28 @@ namespace System.Xml.XPath
        
        internal class UnionIterator : BaseIterator
        {
-               protected BaseIterator _left, _right;
-               private int _pos;
+               private BaseIterator _left, _right;
                private bool keepLeft;
                private bool keepRight;
                private bool useRight;
 
-               public UnionIterator (BaseIterator iter, BaseIterator left, BaseIterator right) : base (iter)
+               public UnionIterator (BaseIterator iter, BaseIterator left, BaseIterator right) : base (iter.NamespaceManager)
                {
                        _left = left;
                        _right = right;
                }
 
-               protected UnionIterator (UnionIterator other) : base (other)
+               private UnionIterator (UnionIterator other) : base (other)
                {
                        _left = (BaseIterator) other._left.Clone ();
                        _right = (BaseIterator) other._right.Clone ();
-                       _pos = other._pos;
                        keepLeft = other.keepLeft;
                        keepRight = other.keepRight;
                        useRight = other.useRight;
                }
                public override XPathNodeIterator Clone () { return new UnionIterator (this); }
 
-               public override bool MoveNext ()
+               public override bool MoveNextCore ()
                {
                        if (!keepLeft)
                                keepLeft = _left.MoveNext ();
@@ -1232,7 +1132,6 @@ namespace System.Xml.XPath
                        if (!keepLeft && !keepRight)
                                return false;
 
-                       _pos ++;
                        if (!keepRight) {
                                keepLeft = useRight = false;
                                return true;
@@ -1264,7 +1163,7 @@ namespace System.Xml.XPath
                {
                        get
                        {
-                               if (_pos == 0)
+                               if (CurrentPosition == 0)
                                        return null;
                                if (useRight)
                                        return _right.Current;
@@ -1272,7 +1171,6 @@ namespace System.Xml.XPath
                                        return _left.Current;
                        }
                }
-               public override int CurrentPosition { get { return _pos; }}
 
                public override bool RequireSorting { get { return _left.RequireSorting || _right.RequireSorting; } }
        }