| 
									
										
										
										
											2016-08-03 10:59:49 +00:00
										 |  |  | //------------------------------------------------------------------------------ | 
					
						
							|  |  |  | // <copyright file="DocumentXPathNavigator.cs" company="Microsoft"> | 
					
						
							|  |  |  | //     Copyright (c) Microsoft Corporation.  All rights reserved. | 
					
						
							|  |  |  | // </copyright>                                                                 | 
					
						
							| 
									
										
										
										
											2017-08-21 15:34:15 +00:00
										 |  |  | // <owner current="true" primary="true">Microsoft</owner> | 
					
						
							| 
									
										
										
										
											2016-08-03 10:59:49 +00:00
										 |  |  | //------------------------------------------------------------------------------ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using System; | 
					
						
							|  |  |  | using System.Collections; | 
					
						
							|  |  |  | using System.Collections.Generic; | 
					
						
							|  |  |  | using System.Text; | 
					
						
							|  |  |  | using System.Xml.Schema; | 
					
						
							|  |  |  | using System.Xml.XPath; | 
					
						
							|  |  |  | using System.Diagnostics; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace System.Xml { | 
					
						
							|  |  |  |     internal sealed class DocumentXPathNavigator : XPathNavigator, IHasXmlNode { | 
					
						
							|  |  |  |         private XmlDocument document; // owner document | 
					
						
							|  |  |  |         private XmlNode source; // navigator position  | 
					
						
							|  |  |  |         private int attributeIndex; // index in attribute collection for attribute  | 
					
						
							|  |  |  |         private XmlElement namespaceParent; // parent for namespace | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public DocumentXPathNavigator(XmlDocument document, XmlNode node) { | 
					
						
							|  |  |  |             this.document = document; | 
					
						
							|  |  |  |             ResetPosition(node); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public DocumentXPathNavigator(DocumentXPathNavigator other) { | 
					
						
							|  |  |  |             document = other.document; | 
					
						
							|  |  |  |             source = other.source; | 
					
						
							|  |  |  |             attributeIndex = other.attributeIndex; | 
					
						
							|  |  |  |             namespaceParent = other.namespaceParent; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XPathNavigator Clone() { | 
					
						
							|  |  |  |             return new DocumentXPathNavigator(this); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override void SetValue(string value) { | 
					
						
							|  |  |  |             if (value == null) { | 
					
						
							|  |  |  |                 throw new ArgumentNullException("value"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             XmlNode node = source; | 
					
						
							|  |  |  |             XmlNode end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             switch (node.NodeType) { | 
					
						
							|  |  |  |                 case XmlNodeType.Attribute: | 
					
						
							|  |  |  |                     if (((XmlAttribute)node).IsNamespace) { | 
					
						
							|  |  |  |                         goto default; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     node.InnerText = value; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case XmlNodeType.Text: | 
					
						
							|  |  |  |                 case XmlNodeType.CDATA: | 
					
						
							|  |  |  |                 case XmlNodeType.Whitespace: | 
					
						
							|  |  |  |                 case XmlNodeType.SignificantWhitespace: | 
					
						
							|  |  |  |                     CalibrateText(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     node = source; | 
					
						
							|  |  |  |                     end = TextEnd(node); | 
					
						
							|  |  |  |                     if (node != end) { | 
					
						
							|  |  |  |                         if (node.IsReadOnly) { | 
					
						
							|  |  |  |                             throw new InvalidOperationException(Res.GetString(Res.Xdom_Node_Modify_ReadOnly)); | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         DeleteToFollowingSibling(node.NextSibling, end); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     goto case XmlNodeType.Element; | 
					
						
							|  |  |  |                 case XmlNodeType.Element: | 
					
						
							|  |  |  |                 case XmlNodeType.ProcessingInstruction: | 
					
						
							|  |  |  |                 case XmlNodeType.Comment: | 
					
						
							|  |  |  |                     node.InnerText = value; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                     throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XmlNameTable NameTable { | 
					
						
							|  |  |  |             get {  | 
					
						
							|  |  |  |                 return document.NameTable; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XPathNodeType NodeType { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 CalibrateText(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return (XPathNodeType)source.XPNodeType; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override string LocalName { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 return source.XPLocalName; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override string NamespaceURI { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 XmlAttribute attribute = source as XmlAttribute;  | 
					
						
							|  |  |  |                 if (attribute != null | 
					
						
							|  |  |  |                     && attribute.IsNamespace) { | 
					
						
							|  |  |  |                     return string.Empty;  | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return source.NamespaceURI;  | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override string Name { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 switch (source.NodeType) { | 
					
						
							|  |  |  |                     case XmlNodeType.Element: | 
					
						
							|  |  |  |                     case XmlNodeType.ProcessingInstruction: | 
					
						
							|  |  |  |                         return source.Name; | 
					
						
							|  |  |  |                     case XmlNodeType.Attribute: | 
					
						
							|  |  |  |                         if (((XmlAttribute)source).IsNamespace) { | 
					
						
							|  |  |  |                             string localName = source.LocalName; | 
					
						
							|  |  |  |                             if (Ref.Equal(localName, document.strXmlns)) { | 
					
						
							|  |  |  |                                 return string.Empty; // xmlns declaration | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                             return localName; // xmlns:name declaration | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         return source.Name; // attribute   | 
					
						
							|  |  |  |                     default: | 
					
						
							|  |  |  |                         return string.Empty; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override string Prefix { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 XmlAttribute attribute = source as XmlAttribute; | 
					
						
							|  |  |  |                 if (attribute != null | 
					
						
							|  |  |  |                     && attribute.IsNamespace) { | 
					
						
							|  |  |  |                     return string.Empty; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return source.Prefix; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override string Value { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 switch (source.NodeType) { | 
					
						
							|  |  |  |                     case XmlNodeType.Element: | 
					
						
							|  |  |  |                     case XmlNodeType.DocumentFragment: | 
					
						
							|  |  |  |                         return source.InnerText; | 
					
						
							|  |  |  |                     case XmlNodeType.Document: | 
					
						
							|  |  |  |                         return ValueDocument; | 
					
						
							|  |  |  |                     case XmlNodeType.Text: | 
					
						
							|  |  |  |                     case XmlNodeType.CDATA: | 
					
						
							|  |  |  |                     case XmlNodeType.Whitespace: | 
					
						
							|  |  |  |                     case XmlNodeType.SignificantWhitespace: | 
					
						
							|  |  |  |                         return ValueText;  | 
					
						
							|  |  |  |                     default: | 
					
						
							|  |  |  |                         return source.Value; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private string ValueDocument { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 XmlElement element = document.DocumentElement; | 
					
						
							|  |  |  |                 if (element != null) { | 
					
						
							|  |  |  |                     return element.InnerText; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return string.Empty; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private string ValueText { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 CalibrateText(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 string value = source.Value; | 
					
						
							|  |  |  |                 XmlNode nextSibling = NextSibling(source); | 
					
						
							|  |  |  |                 if (nextSibling != null | 
					
						
							|  |  |  |                     && nextSibling.IsText) { | 
					
						
							|  |  |  |                     StringBuilder builder = new StringBuilder(value); | 
					
						
							|  |  |  |                     do { | 
					
						
							|  |  |  |                         builder.Append(nextSibling.Value); | 
					
						
							|  |  |  |                         nextSibling = NextSibling(nextSibling); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     while (nextSibling != null | 
					
						
							|  |  |  |                            && nextSibling.IsText); | 
					
						
							|  |  |  |                     value = builder.ToString(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return value; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override string BaseURI { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 return source.BaseURI; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool IsEmptyElement { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 XmlElement element = source as XmlElement; | 
					
						
							|  |  |  |                 if (element != null) { | 
					
						
							|  |  |  |                     return element.IsEmpty; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override string XmlLang { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 return source.XmlLang; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override object UnderlyingObject { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 CalibrateText(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return source; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool HasAttributes {  | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 XmlElement element = source as XmlElement; | 
					
						
							|  |  |  |                 if (element != null | 
					
						
							|  |  |  |                     && element.HasAttributes) { | 
					
						
							|  |  |  |                     XmlAttributeCollection attributes = element.Attributes; | 
					
						
							|  |  |  |                     for (int i = 0; i < attributes.Count; i++) { | 
					
						
							|  |  |  |                         XmlAttribute attribute = attributes[i]; | 
					
						
							|  |  |  |                         if (!attribute.IsNamespace) { | 
					
						
							|  |  |  |                             return true; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             }  | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override string GetAttribute(string localName, string namespaceURI) { | 
					
						
							|  |  |  |             return source.GetXPAttribute(localName, namespaceURI); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToAttribute(string localName, string namespaceURI) { | 
					
						
							|  |  |  |             XmlElement element = source as XmlElement; | 
					
						
							|  |  |  |             if (element != null | 
					
						
							|  |  |  |                 && element.HasAttributes) {  | 
					
						
							|  |  |  |                 XmlAttributeCollection attributes = element.Attributes; | 
					
						
							|  |  |  |                 for (int i = 0; i < attributes.Count; i++) { | 
					
						
							|  |  |  |                     XmlAttribute attribute = attributes[i]; | 
					
						
							|  |  |  |                     if (attribute.LocalName == localName | 
					
						
							|  |  |  |                         && attribute.NamespaceURI == namespaceURI) { | 
					
						
							|  |  |  |                         if (!attribute.IsNamespace) { | 
					
						
							|  |  |  |                             source = attribute; | 
					
						
							|  |  |  |                             attributeIndex = i; | 
					
						
							|  |  |  |                             return true; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         else { | 
					
						
							|  |  |  |                             return false; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToFirstAttribute() { | 
					
						
							|  |  |  |             XmlElement element = source as XmlElement; | 
					
						
							|  |  |  |             if (element != null | 
					
						
							|  |  |  |                 && element.HasAttributes) { | 
					
						
							|  |  |  |                 XmlAttributeCollection attributes = element.Attributes; | 
					
						
							|  |  |  |                 for (int i = 0; i < attributes.Count; i++) { | 
					
						
							|  |  |  |                     XmlAttribute attribute = attributes[i]; | 
					
						
							|  |  |  |                     if (!attribute.IsNamespace) { | 
					
						
							|  |  |  |                         source = attribute; | 
					
						
							|  |  |  |                         attributeIndex = i; | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToNextAttribute() { | 
					
						
							|  |  |  |             XmlAttribute attribute = source as XmlAttribute; | 
					
						
							|  |  |  |             if (attribute == null | 
					
						
							|  |  |  |                 || attribute.IsNamespace) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             XmlAttributeCollection attributes; | 
					
						
							|  |  |  |             if (!CheckAttributePosition(attribute, out attributes, attributeIndex) | 
					
						
							|  |  |  |                 && !ResetAttributePosition(attribute, attributes, out attributeIndex)) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             for (int i = attributeIndex + 1; i < attributes.Count; i++) { | 
					
						
							|  |  |  |                 attribute = attributes[i];  | 
					
						
							|  |  |  |                 if (!attribute.IsNamespace) { | 
					
						
							|  |  |  |                     source = attribute; | 
					
						
							|  |  |  |                     attributeIndex = i; | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override string GetNamespace(string name) { | 
					
						
							|  |  |  |             XmlNode node = source; | 
					
						
							|  |  |  |             while (node != null | 
					
						
							|  |  |  |                    && node.NodeType != XmlNodeType.Element) { | 
					
						
							|  |  |  |                 XmlAttribute attribute = node as XmlAttribute; | 
					
						
							|  |  |  |                 if (attribute != null) { | 
					
						
							|  |  |  |                     node = attribute.OwnerElement; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     node = node.ParentNode; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             XmlElement element = node as XmlElement; | 
					
						
							|  |  |  |             if (element != null) { | 
					
						
							|  |  |  |                 string localName; | 
					
						
							|  |  |  |                 if (name != null | 
					
						
							|  |  |  |                     && name.Length != 0) { | 
					
						
							|  |  |  |                     localName = name; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     localName = document.strXmlns; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 string namespaceUri = document.strReservedXmlns; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 do | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     XmlAttribute attribute = element.GetAttributeNode(localName, namespaceUri); | 
					
						
							|  |  |  |                     if (attribute != null) { | 
					
						
							|  |  |  |                         return attribute.Value; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     element = element.ParentNode as XmlElement; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 while (element != null); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (name == document.strXml) { | 
					
						
							|  |  |  |                 return document.strReservedXml; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else if (name == document.strXmlns) { | 
					
						
							|  |  |  |                 return document.strReservedXmlns; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return string.Empty; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToNamespace(string name) { | 
					
						
							|  |  |  |             if (name == document.strXmlns) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             XmlElement element = source as XmlElement; | 
					
						
							|  |  |  |             if (element != null) { | 
					
						
							|  |  |  |                 string localName; | 
					
						
							|  |  |  |                 if (name != null | 
					
						
							|  |  |  |                     && name.Length != 0) { | 
					
						
							|  |  |  |                     localName = name; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     localName = document.strXmlns; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 string namespaceUri = document.strReservedXmlns; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 do { | 
					
						
							|  |  |  |                     XmlAttribute attribute = element.GetAttributeNode(localName, namespaceUri); | 
					
						
							|  |  |  |                     if (attribute != null) { | 
					
						
							|  |  |  |                         namespaceParent = (XmlElement)source; | 
					
						
							|  |  |  |                         source = attribute; | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     }  | 
					
						
							|  |  |  |                     element = element.ParentNode as XmlElement; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 while (element != null); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (name == document.strXml) { | 
					
						
							|  |  |  |                     namespaceParent = (XmlElement)source; | 
					
						
							|  |  |  |                     source = document.NamespaceXml; | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToFirstNamespace(XPathNamespaceScope scope) { | 
					
						
							|  |  |  |             XmlElement element = source as XmlElement; | 
					
						
							|  |  |  |             if (element == null) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             XmlAttributeCollection attributes; | 
					
						
							|  |  |  |             int index = Int32.MaxValue; | 
					
						
							|  |  |  |             switch (scope) { | 
					
						
							|  |  |  |                 case XPathNamespaceScope.Local: | 
					
						
							|  |  |  |                     if (!element.HasAttributes) { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     attributes = element.Attributes; | 
					
						
							|  |  |  |                     if (!MoveToFirstNamespaceLocal(attributes, ref index)) { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     source = attributes[index]; | 
					
						
							|  |  |  |                     attributeIndex = index; | 
					
						
							|  |  |  |                     namespaceParent = element; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case XPathNamespaceScope.ExcludeXml: | 
					
						
							|  |  |  |                     attributes = element.Attributes; | 
					
						
							|  |  |  |                     if (!MoveToFirstNamespaceGlobal(ref attributes, ref index)) { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     XmlAttribute attribute = attributes[index]; | 
					
						
							|  |  |  |                     while (Ref.Equal(attribute.LocalName, document.strXml)) { | 
					
						
							|  |  |  |                         if (!MoveToNextNamespaceGlobal(ref attributes, ref index)) { | 
					
						
							|  |  |  |                             return false; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         attribute = attributes[index]; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     source = attribute; | 
					
						
							|  |  |  |                     attributeIndex = index; | 
					
						
							|  |  |  |                     namespaceParent = element; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case XPathNamespaceScope.All: | 
					
						
							|  |  |  |                     attributes = element.Attributes; | 
					
						
							|  |  |  |                     if (!MoveToFirstNamespaceGlobal(ref attributes, ref index)) { | 
					
						
							|  |  |  |                         source = document.NamespaceXml; | 
					
						
							|  |  |  |                         // attributeIndex = 0; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     else { | 
					
						
							|  |  |  |                         source = attributes[index];  | 
					
						
							|  |  |  |                         attributeIndex = index; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     namespaceParent = element; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                     Debug.Assert(false); | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static bool MoveToFirstNamespaceLocal(XmlAttributeCollection attributes, ref int index) { | 
					
						
							|  |  |  |             Debug.Assert(attributes != null); | 
					
						
							|  |  |  |             for (int i = attributes.Count - 1; i >= 0; i--) { | 
					
						
							|  |  |  |                 XmlAttribute attribute = attributes[i]; | 
					
						
							|  |  |  |                 if (attribute.IsNamespace) { | 
					
						
							|  |  |  |                     index = i; | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static bool MoveToFirstNamespaceGlobal(ref XmlAttributeCollection attributes, ref int index) { | 
					
						
							|  |  |  |             if (MoveToFirstNamespaceLocal(attributes, ref index)) { | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             Debug.Assert(attributes != null && attributes.parent != null); | 
					
						
							|  |  |  |             XmlElement element = attributes.parent.ParentNode as XmlElement; | 
					
						
							|  |  |  |             while (element != null) { | 
					
						
							|  |  |  |                 if (element.HasAttributes) { | 
					
						
							|  |  |  |                     attributes = element.Attributes;  | 
					
						
							|  |  |  |                     if (MoveToFirstNamespaceLocal(attributes, ref index)) { | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 element = element.ParentNode as XmlElement; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToNextNamespace(XPathNamespaceScope scope) { | 
					
						
							|  |  |  |             XmlAttribute attribute = source as XmlAttribute; | 
					
						
							|  |  |  |             if (attribute == null | 
					
						
							|  |  |  |                 || !attribute.IsNamespace) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             XmlAttributeCollection attributes; | 
					
						
							|  |  |  |             int index = attributeIndex; | 
					
						
							|  |  |  |             if (!CheckAttributePosition(attribute, out attributes, index) | 
					
						
							|  |  |  |                 && !ResetAttributePosition(attribute, attributes, out index)) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             Debug.Assert(namespaceParent != null); | 
					
						
							|  |  |  |             switch (scope) { | 
					
						
							|  |  |  |                 case XPathNamespaceScope.Local: | 
					
						
							|  |  |  |                     if (attribute.OwnerElement != namespaceParent) { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     if (!MoveToNextNamespaceLocal(attributes, ref index)) { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     source = attributes[index]; | 
					
						
							|  |  |  |                     attributeIndex = index; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case XPathNamespaceScope.ExcludeXml: | 
					
						
							|  |  |  |                     string localName; | 
					
						
							|  |  |  |                     do { | 
					
						
							|  |  |  |                         if (!MoveToNextNamespaceGlobal(ref attributes, ref index)) { | 
					
						
							|  |  |  |                             return false; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         attribute = attributes[index]; | 
					
						
							|  |  |  |                         localName = attribute.LocalName; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     while (PathHasDuplicateNamespace(attribute.OwnerElement, namespaceParent, localName) | 
					
						
							|  |  |  |                            || Ref.Equal(localName, document.strXml)); | 
					
						
							|  |  |  |                     source = attribute;  | 
					
						
							|  |  |  |                     attributeIndex = index; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case XPathNamespaceScope.All: | 
					
						
							|  |  |  |                     do { | 
					
						
							|  |  |  |                         if (!MoveToNextNamespaceGlobal(ref attributes, ref index)) { | 
					
						
							|  |  |  |                             if (PathHasDuplicateNamespace(null, namespaceParent, document.strXml)) { | 
					
						
							|  |  |  |                                 return false; | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                             else { | 
					
						
							|  |  |  |                                 source = document.NamespaceXml; | 
					
						
							|  |  |  |                                 // attributeIndex = 0; | 
					
						
							|  |  |  |                                 return true; | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         attribute = attributes[index]; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     while (PathHasDuplicateNamespace(attribute.OwnerElement, namespaceParent, attribute.LocalName)); | 
					
						
							|  |  |  |                     source = attribute; | 
					
						
							|  |  |  |                     attributeIndex = index; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                     Debug.Assert(false); | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static bool MoveToNextNamespaceLocal(XmlAttributeCollection attributes, ref int index) { | 
					
						
							|  |  |  |             Debug.Assert(attributes != null); | 
					
						
							|  |  |  |             Debug.Assert(0 <= index && index < attributes.Count); | 
					
						
							|  |  |  |             for (int i = index - 1; i >= 0; i--) { | 
					
						
							|  |  |  |                 XmlAttribute attribute = attributes[i]; | 
					
						
							|  |  |  |                 if (attribute.IsNamespace) { | 
					
						
							|  |  |  |                     index = i; | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static bool MoveToNextNamespaceGlobal(ref XmlAttributeCollection attributes, ref int index) { | 
					
						
							|  |  |  |             if (MoveToNextNamespaceLocal(attributes, ref index)) { | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             Debug.Assert(attributes != null && attributes.parent != null); | 
					
						
							|  |  |  |             XmlElement element = attributes.parent.ParentNode as XmlElement;  | 
					
						
							|  |  |  |             while (element != null) { | 
					
						
							|  |  |  |                 if (element.HasAttributes) { | 
					
						
							|  |  |  |                     attributes = element.Attributes; | 
					
						
							|  |  |  |                     if (MoveToFirstNamespaceLocal(attributes, ref index)) { | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 element = element.ParentNode as XmlElement; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private bool PathHasDuplicateNamespace(XmlElement top, XmlElement bottom, string localName) { | 
					
						
							|  |  |  |             string namespaceUri = document.strReservedXmlns; | 
					
						
							|  |  |  |             while (bottom != null | 
					
						
							|  |  |  |                    && bottom != top) { | 
					
						
							|  |  |  |                 XmlAttribute attribute = bottom.GetAttributeNode(localName, namespaceUri); | 
					
						
							|  |  |  |                 if (attribute != null) { | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 bottom = bottom.ParentNode as XmlElement; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         public override string LookupNamespace(string prefix) { | 
					
						
							|  |  |  |             string ns = base.LookupNamespace(prefix); | 
					
						
							|  |  |  |             if (ns != null) { | 
					
						
							|  |  |  |                 ns = this.NameTable.Add(ns); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return ns; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToNext() { | 
					
						
							|  |  |  |             XmlNode sibling = NextSibling(source); | 
					
						
							|  |  |  |             if (sibling == null) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (sibling.IsText) { | 
					
						
							|  |  |  |                 if (source.IsText) { | 
					
						
							|  |  |  |                     sibling = NextSibling(TextEnd(sibling)); | 
					
						
							|  |  |  |                     if (sibling == null) { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             XmlNode parent = ParentNode(sibling); | 
					
						
							|  |  |  |             Debug.Assert(parent != null); | 
					
						
							|  |  |  |             while (!IsValidChild(parent, sibling)) { | 
					
						
							|  |  |  |                 sibling = NextSibling(sibling); | 
					
						
							|  |  |  |                 if (sibling == null) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             source = sibling; | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToPrevious() { | 
					
						
							|  |  |  |             XmlNode sibling = PreviousSibling(source); | 
					
						
							|  |  |  |             if (sibling == null) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (sibling.IsText) { | 
					
						
							|  |  |  |                 if (source.IsText) { | 
					
						
							|  |  |  |                     sibling = PreviousSibling(TextStart(sibling)); | 
					
						
							|  |  |  |                     if (sibling == null) { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     sibling = TextStart(sibling); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             XmlNode parent = ParentNode(sibling); | 
					
						
							|  |  |  |             Debug.Assert(parent != null); | 
					
						
							|  |  |  |             while (!IsValidChild(parent, sibling)) { | 
					
						
							|  |  |  |                 sibling = PreviousSibling(sibling); | 
					
						
							|  |  |  |                 if (sibling == null) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 // if (sibling.IsText) { | 
					
						
							|  |  |  |                 //     sibling = TextStart(sibling); | 
					
						
							|  |  |  |                 // } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             source = sibling; | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToFirst() { | 
					
						
							|  |  |  |             if (source.NodeType == XmlNodeType.Attribute) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             XmlNode parent = ParentNode(source); | 
					
						
							|  |  |  |             if (parent == null) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             XmlNode sibling = FirstChild(parent); | 
					
						
							|  |  |  |             Debug.Assert(sibling != null); | 
					
						
							|  |  |  |             while (!IsValidChild(parent, sibling)) { | 
					
						
							|  |  |  |                 sibling = NextSibling(sibling); | 
					
						
							|  |  |  |                 if (sibling == null) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             source = sibling; | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToFirstChild() { | 
					
						
							|  |  |  |             XmlNode child; | 
					
						
							|  |  |  |             switch (source.NodeType) { | 
					
						
							|  |  |  |                 case XmlNodeType.Element: | 
					
						
							|  |  |  |                     child = FirstChild(source); | 
					
						
							|  |  |  |                     if (child == null) { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case XmlNodeType.DocumentFragment: | 
					
						
							|  |  |  |                 case XmlNodeType.Document: | 
					
						
							|  |  |  |                     child = FirstChild(source); | 
					
						
							|  |  |  |                     if (child == null) { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     while (!IsValidChild(source, child)) { | 
					
						
							|  |  |  |                         child = NextSibling(child); | 
					
						
							|  |  |  |                         if (child == null) { | 
					
						
							|  |  |  |                             return false; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                      | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             source = child; | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToParent() { | 
					
						
							|  |  |  |             XmlNode parent = ParentNode(source); | 
					
						
							|  |  |  |             if (parent != null) { | 
					
						
							|  |  |  |                 source = parent; | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             XmlAttribute attribute = source as XmlAttribute; | 
					
						
							|  |  |  |             if (attribute != null) { | 
					
						
							|  |  |  |                 parent = attribute.IsNamespace ? namespaceParent : attribute.OwnerElement; | 
					
						
							|  |  |  |                 if (parent != null) { | 
					
						
							|  |  |  |                     source = parent; | 
					
						
							|  |  |  |                     namespaceParent = null; | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override void MoveToRoot() { | 
					
						
							|  |  |  |             for (;;) { | 
					
						
							|  |  |  |                 XmlNode parent = source.ParentNode; | 
					
						
							|  |  |  |                 if (parent == null) { | 
					
						
							|  |  |  |                     XmlAttribute attribute = source as XmlAttribute;  | 
					
						
							|  |  |  |                     if (attribute == null) { | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     parent = attribute.IsNamespace ? namespaceParent : attribute.OwnerElement; | 
					
						
							|  |  |  |                     if (parent == null) { | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 source = parent; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             namespaceParent = null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveTo(XPathNavigator other) { | 
					
						
							|  |  |  |             DocumentXPathNavigator that = other as DocumentXPathNavigator; | 
					
						
							|  |  |  |             if (that != null | 
					
						
							|  |  |  |                 && document == that.document) { | 
					
						
							|  |  |  |                 source = that.source; | 
					
						
							|  |  |  |                 attributeIndex = that.attributeIndex; | 
					
						
							|  |  |  |                 namespaceParent = that.namespaceParent; | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToId(string id) { | 
					
						
							|  |  |  |             XmlElement element = document.GetElementById(id); | 
					
						
							|  |  |  |             if (element != null) { | 
					
						
							|  |  |  |                 source = element; | 
					
						
							|  |  |  |                 namespaceParent = null; | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToChild(string localName, string namespaceUri) { | 
					
						
							|  |  |  |             if (source.NodeType == XmlNodeType.Attribute) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             XmlNode child = FirstChild(source); | 
					
						
							|  |  |  |             if (child != null) { | 
					
						
							|  |  |  |                 do { | 
					
						
							|  |  |  |                     if (child.NodeType == XmlNodeType.Element | 
					
						
							|  |  |  |                         && child.LocalName == localName | 
					
						
							|  |  |  |                         && child.NamespaceURI == namespaceUri) { | 
					
						
							|  |  |  |                         source = child; | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     child = NextSibling(child); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 while (child != null); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToChild(XPathNodeType type) { | 
					
						
							|  |  |  |             if (source.NodeType == XmlNodeType.Attribute) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             XmlNode child = FirstChild(source); | 
					
						
							|  |  |  |             if (child != null) { | 
					
						
							|  |  |  |                 int mask = GetContentKindMask(type); | 
					
						
							|  |  |  |                 if (mask == 0) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 do { | 
					
						
							|  |  |  |                     if (((1 << (int)child.XPNodeType) & mask) != 0) { | 
					
						
							|  |  |  |                         source = child; | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     child = NextSibling(child); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 while (child != null); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToFollowing(string localName, string namespaceUri, XPathNavigator end) { | 
					
						
							|  |  |  |             XmlNode pastFollowing = null; | 
					
						
							|  |  |  |             DocumentXPathNavigator that = end as DocumentXPathNavigator; | 
					
						
							|  |  |  |             if (that != null) { | 
					
						
							|  |  |  |                 if (document != that.document) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 switch (that.source.NodeType) { | 
					
						
							|  |  |  |                     case XmlNodeType.Attribute: | 
					
						
							|  |  |  |                         that = (DocumentXPathNavigator)that.Clone(); | 
					
						
							|  |  |  |                         if (!that.MoveToNonDescendant()) { | 
					
						
							|  |  |  |                             return false; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 pastFollowing = that.source; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             XmlNode following = source; | 
					
						
							|  |  |  |             if (following.NodeType == XmlNodeType.Attribute) { | 
					
						
							|  |  |  |                 following = ((XmlAttribute)following).OwnerElement; | 
					
						
							|  |  |  |                 if (following == null) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             do { | 
					
						
							|  |  |  |                 XmlNode firstChild = following.FirstChild; | 
					
						
							|  |  |  |                 if (firstChild != null) { | 
					
						
							|  |  |  |                     following = firstChild; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     for (;;) { | 
					
						
							|  |  |  |                         XmlNode nextSibling = following.NextSibling; | 
					
						
							|  |  |  |                         if (nextSibling != null) { | 
					
						
							|  |  |  |                             following = nextSibling; | 
					
						
							|  |  |  |                             break; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         else { | 
					
						
							|  |  |  |                             XmlNode parent = following.ParentNode; | 
					
						
							|  |  |  |                             if (parent != null) { | 
					
						
							|  |  |  |                                 following = parent; | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                             else { | 
					
						
							|  |  |  |                                 return false; | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (following == pastFollowing) {  | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             while (following.NodeType != XmlNodeType.Element | 
					
						
							|  |  |  |                    || following.LocalName != localName | 
					
						
							|  |  |  |                    || following.NamespaceURI != namespaceUri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             source = following; | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) { | 
					
						
							|  |  |  |             XmlNode pastFollowing = null; | 
					
						
							|  |  |  |             DocumentXPathNavigator that = end as DocumentXPathNavigator; | 
					
						
							|  |  |  |             if (that != null) { | 
					
						
							|  |  |  |                 if (document != that.document) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 switch (that.source.NodeType) { | 
					
						
							|  |  |  |                     case XmlNodeType.Attribute: | 
					
						
							|  |  |  |                         that = (DocumentXPathNavigator)that.Clone(); | 
					
						
							|  |  |  |                         if (!that.MoveToNonDescendant()) { | 
					
						
							|  |  |  |                             return false; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 pastFollowing = that.source; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             int mask = GetContentKindMask(type); | 
					
						
							|  |  |  |             if (mask == 0) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             XmlNode following = source; | 
					
						
							|  |  |  |             switch (following.NodeType) { | 
					
						
							|  |  |  |                 case XmlNodeType.Attribute: | 
					
						
							|  |  |  |                     following = ((XmlAttribute)following).OwnerElement;  | 
					
						
							|  |  |  |                     if (following == null) { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case XmlNodeType.Text: | 
					
						
							|  |  |  |                 case XmlNodeType.CDATA: | 
					
						
							|  |  |  |                 case XmlNodeType.SignificantWhitespace: | 
					
						
							|  |  |  |                 case XmlNodeType.Whitespace: | 
					
						
							|  |  |  |                     following = TextEnd(following); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             do { | 
					
						
							|  |  |  |                 XmlNode firstChild = following.FirstChild; | 
					
						
							|  |  |  |                 if (firstChild != null) { | 
					
						
							|  |  |  |                     following = firstChild; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     for (;;) { | 
					
						
							|  |  |  |                         XmlNode nextSibling = following.NextSibling; | 
					
						
							|  |  |  |                         if (nextSibling != null) { | 
					
						
							|  |  |  |                             following = nextSibling; | 
					
						
							|  |  |  |                             break; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         else { | 
					
						
							|  |  |  |                             XmlNode parent = following.ParentNode; | 
					
						
							|  |  |  |                             if (parent != null) { | 
					
						
							|  |  |  |                                 following = parent; | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                             else { | 
					
						
							|  |  |  |                                 return false; | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (following == pastFollowing) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             while (((1 << (int)following.XPNodeType) & mask) == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             source = following; | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToNext(string localName, string namespaceUri) { | 
					
						
							|  |  |  |             XmlNode sibling = NextSibling(source); | 
					
						
							|  |  |  |             if (sibling == null) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             do { | 
					
						
							|  |  |  |                 if (sibling.NodeType == XmlNodeType.Element | 
					
						
							|  |  |  |                     && sibling.LocalName == localName | 
					
						
							|  |  |  |                     && sibling.NamespaceURI == namespaceUri) { | 
					
						
							|  |  |  |                     source = sibling; | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 sibling = NextSibling(sibling); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             while (sibling != null); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveToNext(XPathNodeType type) { | 
					
						
							|  |  |  |             XmlNode sibling = NextSibling(source); | 
					
						
							|  |  |  |             if (sibling == null) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (sibling.IsText | 
					
						
							|  |  |  |                 && source.IsText) { | 
					
						
							|  |  |  |                 sibling = NextSibling(TextEnd(sibling)); | 
					
						
							|  |  |  |                 if (sibling == null) { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             int mask = GetContentKindMask(type); | 
					
						
							|  |  |  |             if (mask == 0) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             do { | 
					
						
							|  |  |  |                 if (((1 << (int)sibling.XPNodeType) & mask) != 0) { | 
					
						
							|  |  |  |                     source = sibling; | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 sibling = NextSibling(sibling); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             while (sibling != null); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool HasChildren { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 XmlNode child; | 
					
						
							|  |  |  |                 switch (source.NodeType) { | 
					
						
							|  |  |  |                     case XmlNodeType.Element: | 
					
						
							|  |  |  |                         child = FirstChild(source); | 
					
						
							|  |  |  |                         if (child == null) { | 
					
						
							|  |  |  |                             return false; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     case XmlNodeType.DocumentFragment: | 
					
						
							|  |  |  |                     case XmlNodeType.Document: | 
					
						
							|  |  |  |                         child = FirstChild(source); | 
					
						
							|  |  |  |                         if (child == null) { | 
					
						
							|  |  |  |                             return false;  | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         while (!IsValidChild(source, child)) { | 
					
						
							|  |  |  |                             child = NextSibling(child); | 
					
						
							|  |  |  |                             if (child == null) { | 
					
						
							|  |  |  |                                 return false;  | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     default: | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool IsSamePosition(XPathNavigator other) { | 
					
						
							|  |  |  |             DocumentXPathNavigator that = other as DocumentXPathNavigator; | 
					
						
							|  |  |  |             if (that != null) { | 
					
						
							|  |  |  |                 this.CalibrateText(); | 
					
						
							|  |  |  |                 that.CalibrateText(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return this.source == that.source | 
					
						
							|  |  |  |                        && this.namespaceParent == that.namespaceParent; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool IsDescendant(XPathNavigator other) { | 
					
						
							|  |  |  |             DocumentXPathNavigator that = other as DocumentXPathNavigator; | 
					
						
							|  |  |  |             if (that != null) { | 
					
						
							|  |  |  |                 return IsDescendant(this.source, that.source);  | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override IXmlSchemaInfo SchemaInfo { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 return source.SchemaInfo; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool CheckValidity(XmlSchemaSet schemas, ValidationEventHandler validationEventHandler) { | 
					
						
							|  |  |  |             XmlDocument ownerDocument; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (source.NodeType == XmlNodeType.Document) { | 
					
						
							|  |  |  |                 ownerDocument = (XmlDocument)source; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 ownerDocument = source.OwnerDocument; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (schemas != null) { | 
					
						
							|  |  |  |                     throw new ArgumentException(Res.GetString(Res.XPathDocument_SchemaSetNotAllowed, null)); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (schemas == null && ownerDocument != null) { | 
					
						
							|  |  |  |                 schemas = ownerDocument.Schemas; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (schemas == null || schemas.Count == 0) { | 
					
						
							|  |  |  |                 throw new InvalidOperationException(Res.GetString(Res.XmlDocument_NoSchemaInfo)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             DocumentSchemaValidator validator = new DocumentSchemaValidator(ownerDocument, schemas, validationEventHandler); | 
					
						
							|  |  |  |             validator.PsviAugmentation = false; | 
					
						
							|  |  |  |             return validator.Validate(source); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static XmlNode OwnerNode(XmlNode node) { | 
					
						
							|  |  |  |             XmlNode parent = node.ParentNode; | 
					
						
							|  |  |  |             if (parent != null) { | 
					
						
							|  |  |  |                 return parent; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             XmlAttribute attribute = node as XmlAttribute; | 
					
						
							|  |  |  |             if (attribute != null) { | 
					
						
							|  |  |  |                 return attribute.OwnerElement; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static int GetDepth(XmlNode node) { | 
					
						
							|  |  |  |             int depth = 0; | 
					
						
							|  |  |  |             XmlNode owner = OwnerNode(node);  | 
					
						
							|  |  |  |             while (owner != null) { | 
					
						
							|  |  |  |                 depth++; | 
					
						
							|  |  |  |                 owner = OwnerNode(owner); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return depth; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         //Assuming that node1 and node2 are in the same level; Except when they are namespace nodes, they should have the same parent node | 
					
						
							|  |  |  |         //the returned value is node2's position corresponding to node1  | 
					
						
							|  |  |  |         private XmlNodeOrder Compare( XmlNode node1, XmlNode node2 ) { | 
					
						
							|  |  |  |             Debug.Assert( node1 != null ); | 
					
						
							|  |  |  |             Debug.Assert( node2 != null ); | 
					
						
							|  |  |  |             Debug.Assert( node1 != node2, "Should be handled by ComparePosition()" ); | 
					
						
							|  |  |  |             //Attribute nodes come before other children nodes except namespace nodes | 
					
						
							|  |  |  |             Debug.Assert( OwnerNode(node1) == OwnerNode(node2) ); | 
					
						
							|  |  |  |             if (node1.XPNodeType == XPathNodeType.Attribute) { | 
					
						
							|  |  |  |                 if (node2.XPNodeType == XPathNodeType.Attribute) { | 
					
						
							|  |  |  |                     XmlElement element = ((XmlAttribute)node1).OwnerElement; | 
					
						
							|  |  |  |                     if (element.HasAttributes) { | 
					
						
							|  |  |  |                         XmlAttributeCollection attributes = element.Attributes; | 
					
						
							|  |  |  |                         for (int i = 0; i < attributes.Count; i++) { | 
					
						
							|  |  |  |                             XmlAttribute attribute = attributes[i]; | 
					
						
							|  |  |  |                             if (attribute == node1) { | 
					
						
							|  |  |  |                                 return XmlNodeOrder.Before; | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                             else if (attribute == node2) { | 
					
						
							|  |  |  |                                 return XmlNodeOrder.After; | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     return XmlNodeOrder.Unknown; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     return XmlNodeOrder.Before; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (node2.XPNodeType == XPathNodeType.Attribute) { | 
					
						
							|  |  |  |                 return XmlNodeOrder.After; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             //neither of the node is Namespace node or Attribute node | 
					
						
							|  |  |  |             XmlNode nextNode = node1.NextSibling; | 
					
						
							|  |  |  |             while ( nextNode != null && nextNode != node2 ) | 
					
						
							|  |  |  |                 nextNode = nextNode.NextSibling; | 
					
						
							|  |  |  |             if ( nextNode == null ) | 
					
						
							|  |  |  |                 //didn't meet node2 in the path to the end, thus it has to be in the front of node1 | 
					
						
							|  |  |  |                 return XmlNodeOrder.After; | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 //met node2 in the path to the end, so node1 is at front | 
					
						
							|  |  |  |                 return XmlNodeOrder.Before; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XmlNodeOrder ComparePosition(XPathNavigator other) { | 
					
						
							|  |  |  |             DocumentXPathNavigator that = other as DocumentXPathNavigator; | 
					
						
							|  |  |  |             if (that == null) { | 
					
						
							|  |  |  |                 return XmlNodeOrder.Unknown; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             this.CalibrateText(); | 
					
						
							|  |  |  |             that.CalibrateText(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (this.source == that.source | 
					
						
							|  |  |  |                 && this.namespaceParent == that.namespaceParent) { | 
					
						
							|  |  |  |                 return XmlNodeOrder.Same; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (this.namespaceParent != null | 
					
						
							|  |  |  |                 || that.namespaceParent != null) { | 
					
						
							|  |  |  |                 return base.ComparePosition(other); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             XmlNode node1 = this.source; | 
					
						
							|  |  |  |             XmlNode node2 = that.source; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             XmlNode parent1 = OwnerNode(node1); | 
					
						
							|  |  |  |             XmlNode parent2 = OwnerNode(node2); | 
					
						
							|  |  |  |             if (parent1 == parent2) { | 
					
						
							|  |  |  |                 if (parent1 == null) { | 
					
						
							|  |  |  |                     return XmlNodeOrder.Unknown;  | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     Debug.Assert(node1 != node2); | 
					
						
							|  |  |  |                     return Compare(node1, node2); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             int depth1 = GetDepth(node1); | 
					
						
							|  |  |  |             int depth2 = GetDepth(node2); | 
					
						
							|  |  |  |             if (depth2 > depth1) { | 
					
						
							|  |  |  |                 while (node2 != null  | 
					
						
							|  |  |  |                        && depth2 > depth1) { | 
					
						
							|  |  |  |                     node2 = OwnerNode(node2); | 
					
						
							|  |  |  |                     depth2--; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (node1 == node2) { | 
					
						
							|  |  |  |                     return XmlNodeOrder.Before; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 parent2 = OwnerNode(node2); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else if (depth1 > depth2) { | 
					
						
							|  |  |  |                 while (node1 != null  | 
					
						
							|  |  |  |                        && depth1 > depth2) { | 
					
						
							|  |  |  |                     node1 = OwnerNode(node1); | 
					
						
							|  |  |  |                     depth1--; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (node1 == node2) { | 
					
						
							|  |  |  |                     return XmlNodeOrder.After; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 parent1 = OwnerNode(node1); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             while (parent1 != null  | 
					
						
							|  |  |  |                    && parent2 != null) { | 
					
						
							|  |  |  |                 if (parent1 == parent2) { | 
					
						
							|  |  |  |                     Debug.Assert(node1 != node2); | 
					
						
							|  |  |  |                     return Compare(node1, node2); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 node1 = parent1; | 
					
						
							|  |  |  |                 node2 = parent2; | 
					
						
							|  |  |  |                 parent1 = OwnerNode(node1); | 
					
						
							|  |  |  |                 parent2 = OwnerNode(node2); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return XmlNodeOrder.Unknown; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         //the function just for XPathNodeList to enumerate current Node. | 
					
						
							|  |  |  |         XmlNode IHasXmlNode.GetNode() { return source; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XPathNodeIterator SelectDescendants( string localName, string namespaceURI, bool matchSelf ) { | 
					
						
							|  |  |  |             string nsAtom = document.NameTable.Get( namespaceURI ); | 
					
						
							|  |  |  |             if ( nsAtom == null || this.source.NodeType == XmlNodeType.Attribute ) | 
					
						
							|  |  |  |                 return new DocumentXPathNodeIterator_Empty( this ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             Debug.Assert( this.NodeType != XPathNodeType.Attribute && this.NodeType != XPathNodeType.Namespace && this.NodeType != XPathNodeType.All ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             string localNameAtom = document.NameTable.Get( localName ); | 
					
						
							|  |  |  |             if ( localNameAtom == null ) | 
					
						
							|  |  |  |                 return new DocumentXPathNodeIterator_Empty( this ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ( localNameAtom.Length == 0 ) { | 
					
						
							|  |  |  |                 if ( matchSelf ) | 
					
						
							|  |  |  |                     return new DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName( this, nsAtom ); | 
					
						
							|  |  |  |                 return new DocumentXPathNodeIterator_ElemChildren_NoLocalName( this, nsAtom ); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ( matchSelf ) | 
					
						
							|  |  |  |                 return new DocumentXPathNodeIterator_ElemChildren_AndSelf( this, localNameAtom, nsAtom ); | 
					
						
							|  |  |  |             return new DocumentXPathNodeIterator_ElemChildren( this, localNameAtom, nsAtom ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         public override XPathNodeIterator SelectDescendants( XPathNodeType nt, bool includeSelf ) { | 
					
						
							|  |  |  |             if ( nt == XPathNodeType.Element ) { | 
					
						
							|  |  |  |                 XmlNodeType curNT = source.NodeType; | 
					
						
							|  |  |  |                 if ( curNT != XmlNodeType.Document && curNT != XmlNodeType.Element ) { | 
					
						
							|  |  |  |                     //only Document, Entity, Element node can have Element node as children ( descendant ) | 
					
						
							|  |  |  |                     //entity nodes should be invisible to XPath data model | 
					
						
							|  |  |  |                     return new DocumentXPathNodeIterator_Empty( this ); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if ( includeSelf ) | 
					
						
							|  |  |  |                     return new DocumentXPathNodeIterator_AllElemChildren_AndSelf( this ); | 
					
						
							|  |  |  |                 return new DocumentXPathNodeIterator_AllElemChildren( this ); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return base.SelectDescendants( nt, includeSelf ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool CanEdit { | 
					
						
							|  |  |  |             get { | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XmlWriter PrependChild() { | 
					
						
							|  |  |  |             switch (source.NodeType) { | 
					
						
							|  |  |  |                 case XmlNodeType.Element: | 
					
						
							|  |  |  |                 case XmlNodeType.Document: | 
					
						
							|  |  |  |                 case XmlNodeType.DocumentFragment: | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                     throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.PrependChild, source, document); | 
					
						
							|  |  |  |             writer.NamespaceManager = GetNamespaceManager(source, document); | 
					
						
							|  |  |  |             return new XmlWellFormedWriter(writer, writer.Settings); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XmlWriter AppendChild() { | 
					
						
							|  |  |  |             switch (source.NodeType) { | 
					
						
							|  |  |  |                 case XmlNodeType.Element: | 
					
						
							|  |  |  |                 case XmlNodeType.Document: | 
					
						
							|  |  |  |                 case XmlNodeType.DocumentFragment: | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                     throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.AppendChild, source, document); | 
					
						
							|  |  |  |             writer.NamespaceManager = GetNamespaceManager(source, document); | 
					
						
							|  |  |  |             return new XmlWellFormedWriter(writer, writer.Settings); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XmlWriter InsertAfter() { | 
					
						
							|  |  |  |             XmlNode node = source; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             switch (node.NodeType) { | 
					
						
							|  |  |  |                 case XmlNodeType.Attribute: | 
					
						
							|  |  |  |                 case XmlNodeType.Document: | 
					
						
							|  |  |  |                 case XmlNodeType.DocumentFragment: | 
					
						
							|  |  |  |                     throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); | 
					
						
							|  |  |  |                 case XmlNodeType.Text: | 
					
						
							|  |  |  |                 case XmlNodeType.CDATA: | 
					
						
							|  |  |  |                 case XmlNodeType.SignificantWhitespace: | 
					
						
							|  |  |  |                 case XmlNodeType.Whitespace: | 
					
						
							|  |  |  |                     node = TextEnd(node); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.InsertSiblingAfter, node, document); | 
					
						
							|  |  |  |             writer.NamespaceManager = GetNamespaceManager(node.ParentNode, document); | 
					
						
							|  |  |  |             return new XmlWellFormedWriter(writer, writer.Settings); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XmlWriter InsertBefore() { | 
					
						
							|  |  |  |             switch (source.NodeType) { | 
					
						
							|  |  |  |                 case XmlNodeType.Attribute: | 
					
						
							|  |  |  |                 case XmlNodeType.Document: | 
					
						
							|  |  |  |                 case XmlNodeType.DocumentFragment: | 
					
						
							|  |  |  |                     throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); | 
					
						
							|  |  |  |                 case XmlNodeType.Text: | 
					
						
							|  |  |  |                 case XmlNodeType.CDATA: | 
					
						
							|  |  |  |                 case XmlNodeType.SignificantWhitespace: | 
					
						
							|  |  |  |                 case XmlNodeType.Whitespace: | 
					
						
							|  |  |  |                     CalibrateText(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.InsertSiblingBefore, source, document); | 
					
						
							|  |  |  |             writer.NamespaceManager = GetNamespaceManager(source.ParentNode, document); | 
					
						
							|  |  |  |             return new XmlWellFormedWriter(writer, writer.Settings); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XmlWriter CreateAttributes() { | 
					
						
							|  |  |  |             if (source.NodeType != XmlNodeType.Element) { | 
					
						
							|  |  |  |                 throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.AppendAttribute, source, document); | 
					
						
							|  |  |  |             writer.NamespaceManager = GetNamespaceManager(source, document); | 
					
						
							|  |  |  |             return new XmlWellFormedWriter(writer, writer.Settings); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XmlWriter ReplaceRange(XPathNavigator lastSiblingToReplace) { | 
					
						
							|  |  |  |             DocumentXPathNavigator that = lastSiblingToReplace as DocumentXPathNavigator; | 
					
						
							|  |  |  |             if (that == null) { | 
					
						
							|  |  |  |                 if (lastSiblingToReplace == null) { | 
					
						
							|  |  |  |                     throw new ArgumentNullException("lastSiblingToReplace"); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     throw new NotSupportedException(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             this.CalibrateText(); | 
					
						
							|  |  |  |             that.CalibrateText(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             XmlNode node = this.source; | 
					
						
							|  |  |  |             XmlNode end = that.source; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (node == end) { | 
					
						
							|  |  |  |                 switch (node.NodeType) { | 
					
						
							|  |  |  |                     case XmlNodeType.Attribute: | 
					
						
							|  |  |  |                     case XmlNodeType.Document: | 
					
						
							|  |  |  |                     case XmlNodeType.DocumentFragment: | 
					
						
							|  |  |  |                         throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); | 
					
						
							|  |  |  |                     case XmlNodeType.Text: | 
					
						
							|  |  |  |                     case XmlNodeType.CDATA: | 
					
						
							|  |  |  |                     case XmlNodeType.SignificantWhitespace: | 
					
						
							|  |  |  |                     case XmlNodeType.Whitespace: | 
					
						
							|  |  |  |                         end = that.TextEnd(end); | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     default: | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 if (end.IsText) { | 
					
						
							|  |  |  |                     end = that.TextEnd(end); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (!IsFollowingSibling(node, end)) { | 
					
						
							|  |  |  |                     throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.ReplaceToFollowingSibling, node, document); | 
					
						
							|  |  |  |             writer.NamespaceManager = GetNamespaceManager(node.ParentNode, document); | 
					
						
							|  |  |  |             writer.Navigator = this; | 
					
						
							|  |  |  |             writer.EndNode = end; | 
					
						
							|  |  |  |             return new XmlWellFormedWriter(writer, writer.Settings); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override void DeleteRange(XPathNavigator lastSiblingToDelete) { | 
					
						
							|  |  |  |             DocumentXPathNavigator that = lastSiblingToDelete as DocumentXPathNavigator; | 
					
						
							|  |  |  |             if (that == null) { | 
					
						
							|  |  |  |                 if (lastSiblingToDelete == null) { | 
					
						
							|  |  |  |                     throw new ArgumentNullException("lastSiblingToDelete"); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     throw new NotSupportedException(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             this.CalibrateText(); | 
					
						
							|  |  |  |             that.CalibrateText(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             XmlNode node = this.source; | 
					
						
							|  |  |  |             XmlNode end = that.source; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (node == end) { | 
					
						
							|  |  |  |                 switch (node.NodeType) { | 
					
						
							|  |  |  |                     case XmlNodeType.Attribute: | 
					
						
							|  |  |  |                         XmlAttribute attribute = (XmlAttribute)node; | 
					
						
							|  |  |  |                         if (attribute.IsNamespace) { | 
					
						
							|  |  |  |                             goto default; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         XmlNode parent = OwnerNode(attribute); | 
					
						
							|  |  |  |                         DeleteAttribute(attribute, attributeIndex); | 
					
						
							|  |  |  |                         if (parent != null) { | 
					
						
							|  |  |  |                             ResetPosition(parent); | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     case XmlNodeType.Text: | 
					
						
							|  |  |  |                     case XmlNodeType.CDATA: | 
					
						
							|  |  |  |                     case XmlNodeType.SignificantWhitespace: | 
					
						
							|  |  |  |                     case XmlNodeType.Whitespace: | 
					
						
							|  |  |  |                         end = that.TextEnd(end); | 
					
						
							|  |  |  |                         goto case XmlNodeType.Element; | 
					
						
							|  |  |  |                     case XmlNodeType.Element: | 
					
						
							|  |  |  |                     case XmlNodeType.ProcessingInstruction: | 
					
						
							|  |  |  |                     case XmlNodeType.Comment: | 
					
						
							|  |  |  |                         parent = OwnerNode(node); | 
					
						
							|  |  |  |                         DeleteToFollowingSibling(node, end); | 
					
						
							|  |  |  |                         if (parent != null) { | 
					
						
							|  |  |  |                             ResetPosition(parent); | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     default: | 
					
						
							|  |  |  |                         throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 if (end.IsText) { | 
					
						
							|  |  |  |                     end = that.TextEnd(end); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (!IsFollowingSibling(node, end)) {   | 
					
						
							|  |  |  |                     throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 XmlNode parent = OwnerNode(node);  | 
					
						
							|  |  |  |                 DeleteToFollowingSibling(node, end); | 
					
						
							|  |  |  |                 if (parent != null) { | 
					
						
							|  |  |  |                     ResetPosition(parent); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override void DeleteSelf() { | 
					
						
							|  |  |  |             XmlNode node = source; | 
					
						
							|  |  |  |             XmlNode end = node; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             switch (node.NodeType) { | 
					
						
							|  |  |  |                 case XmlNodeType.Attribute: | 
					
						
							|  |  |  |                     XmlAttribute attribute = (XmlAttribute)node; | 
					
						
							|  |  |  |                     if (attribute.IsNamespace) { | 
					
						
							|  |  |  |                         goto default; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     XmlNode parent = OwnerNode(attribute); | 
					
						
							|  |  |  |                     DeleteAttribute(attribute, attributeIndex); | 
					
						
							|  |  |  |                     if (parent != null) { | 
					
						
							|  |  |  |                         ResetPosition(parent); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case XmlNodeType.Text: | 
					
						
							|  |  |  |                 case XmlNodeType.CDATA: | 
					
						
							|  |  |  |                 case XmlNodeType.SignificantWhitespace: | 
					
						
							|  |  |  |                 case XmlNodeType.Whitespace: | 
					
						
							|  |  |  |                     CalibrateText(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     node = source;  | 
					
						
							|  |  |  |                     end = TextEnd(node); | 
					
						
							|  |  |  |                     goto case XmlNodeType.Element; | 
					
						
							|  |  |  |                 case XmlNodeType.Element: | 
					
						
							|  |  |  |                 case XmlNodeType.ProcessingInstruction: | 
					
						
							|  |  |  |                 case XmlNodeType.Comment: | 
					
						
							|  |  |  |                     parent = OwnerNode(node); | 
					
						
							|  |  |  |                     DeleteToFollowingSibling(node, end); | 
					
						
							|  |  |  |                     if (parent != null) { | 
					
						
							|  |  |  |                         ResetPosition(parent); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                     throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static void DeleteAttribute(XmlAttribute attribute, int index) { | 
					
						
							|  |  |  |             XmlAttributeCollection attributes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!CheckAttributePosition(attribute, out attributes, index) | 
					
						
							|  |  |  |                 && !ResetAttributePosition(attribute, attributes, out index)) { | 
					
						
							|  |  |  |                 throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (attribute.IsReadOnly) { | 
					
						
							|  |  |  |                 throw new InvalidOperationException(Res.GetString(Res.Xdom_Node_Modify_ReadOnly));  | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             attributes.RemoveAt(index); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         internal static void DeleteToFollowingSibling(XmlNode node, XmlNode end) { | 
					
						
							|  |  |  |             XmlNode parent = node.ParentNode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (parent == null) { | 
					
						
							|  |  |  |                 throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (node.IsReadOnly | 
					
						
							|  |  |  |                 || end.IsReadOnly) { | 
					
						
							|  |  |  |                 throw new InvalidOperationException(Res.GetString(Res.Xdom_Node_Modify_ReadOnly)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             while (node != end) { | 
					
						
							|  |  |  |                 XmlNode temp = node; | 
					
						
							|  |  |  |                 node = node.NextSibling; | 
					
						
							|  |  |  |                 parent.RemoveChild(temp); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             parent.RemoveChild(node); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static XmlNamespaceManager GetNamespaceManager(XmlNode node, XmlDocument document) { | 
					
						
							|  |  |  |             XmlNamespaceManager namespaceManager = new XmlNamespaceManager(document.NameTable); | 
					
						
							|  |  |  |             List<XmlElement> elements = new List<XmlElement>();  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             while (node != null) { | 
					
						
							|  |  |  |                 XmlElement element = node as XmlElement; | 
					
						
							|  |  |  |                 if (element != null | 
					
						
							|  |  |  |                     && element.HasAttributes) { | 
					
						
							|  |  |  |                     elements.Add(element); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 node = node.ParentNode; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             for (int i = elements.Count - 1; i >= 0; i--) { | 
					
						
							|  |  |  |                 namespaceManager.PushScope(); | 
					
						
							|  |  |  |                 XmlAttributeCollection attributes = elements[i].Attributes; | 
					
						
							|  |  |  |                 for (int j = 0; j < attributes.Count; j++) { | 
					
						
							|  |  |  |                     XmlAttribute attribute = attributes[j]; | 
					
						
							|  |  |  |                     if (attribute.IsNamespace) { | 
					
						
							|  |  |  |                         string prefix = attribute.Prefix.Length == 0 ? string.Empty : attribute.LocalName; | 
					
						
							|  |  |  |                         namespaceManager.AddNamespace(prefix, attribute.Value); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return namespaceManager; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         internal void ResetPosition(XmlNode node) { | 
					
						
							|  |  |  |             Debug.Assert(node != null, "Undefined navigator position"); | 
					
						
							|  |  |  |             Debug.Assert(node == document || node.OwnerDocument == document, "Navigator switched documents");  | 
					
						
							|  |  |  |             source = node; | 
					
						
							|  |  |  |             XmlAttribute attribute = node as XmlAttribute; | 
					
						
							|  |  |  |             if (attribute != null) { | 
					
						
							|  |  |  |                 XmlElement element = attribute.OwnerElement;  | 
					
						
							|  |  |  |                 if (element != null) { | 
					
						
							|  |  |  |                     ResetAttributePosition(attribute, element.Attributes, out attributeIndex); | 
					
						
							|  |  |  |                     if (attribute.IsNamespace) { | 
					
						
							|  |  |  |                         namespaceParent = element; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static bool ResetAttributePosition(XmlAttribute attribute, XmlAttributeCollection attributes, out int index) { | 
					
						
							|  |  |  |             if (attributes != null) { | 
					
						
							|  |  |  |                 for (int i = 0; i < attributes.Count; i++) { | 
					
						
							|  |  |  |                     if (attribute == attributes[i]) { | 
					
						
							|  |  |  |                         index = i; | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             index = 0; | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static bool CheckAttributePosition(XmlAttribute attribute, out XmlAttributeCollection attributes, int index) { | 
					
						
							|  |  |  |             XmlElement element = attribute.OwnerElement; | 
					
						
							|  |  |  |             if (element != null) { | 
					
						
							|  |  |  |                 attributes = element.Attributes; | 
					
						
							|  |  |  |                 if (index >= 0 | 
					
						
							|  |  |  |                     && index < attributes.Count | 
					
						
							|  |  |  |                     && attribute == attributes[index]) { | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 attributes = null; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private void CalibrateText() { | 
					
						
							|  |  |  |             XmlNode text = PreviousText(source); | 
					
						
							|  |  |  |             while (text != null) { | 
					
						
							|  |  |  |                 ResetPosition(text);  | 
					
						
							|  |  |  |                 text = PreviousText(text); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private XmlNode ParentNode(XmlNode node) { | 
					
						
							|  |  |  |             XmlNode parent = node.ParentNode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!document.HasEntityReferences) { | 
					
						
							|  |  |  |                 return parent; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return ParentNodeTail(parent); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private XmlNode ParentNodeTail(XmlNode parent) { | 
					
						
							|  |  |  |             while (parent != null | 
					
						
							|  |  |  |                    && parent.NodeType == XmlNodeType.EntityReference) { | 
					
						
							|  |  |  |                 parent = parent.ParentNode; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return parent; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private XmlNode FirstChild(XmlNode node) { | 
					
						
							|  |  |  |             XmlNode child = node.FirstChild; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!document.HasEntityReferences) { | 
					
						
							|  |  |  |                 return child; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return FirstChildTail(child); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private XmlNode FirstChildTail(XmlNode child) { | 
					
						
							|  |  |  |             while (child != null | 
					
						
							|  |  |  |                    && child.NodeType == XmlNodeType.EntityReference) { | 
					
						
							|  |  |  |                 child = child.FirstChild; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return child; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private XmlNode NextSibling(XmlNode node) { | 
					
						
							|  |  |  |             XmlNode sibling = node.NextSibling;  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!document.HasEntityReferences) { | 
					
						
							|  |  |  |                 return sibling;  | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return NextSiblingTail(node, sibling); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private XmlNode NextSiblingTail(XmlNode node, XmlNode sibling) { | 
					
						
							|  |  |  |             while (sibling == null) { | 
					
						
							|  |  |  |                 node = node.ParentNode; | 
					
						
							|  |  |  |                 if (node == null | 
					
						
							|  |  |  |                     || node.NodeType != XmlNodeType.EntityReference) { | 
					
						
							|  |  |  |                     return null; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 sibling = node.NextSibling; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             while (sibling != null | 
					
						
							|  |  |  |                    && sibling.NodeType == XmlNodeType.EntityReference) { | 
					
						
							|  |  |  |                 sibling = sibling.FirstChild; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return sibling; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private XmlNode PreviousSibling(XmlNode node) { | 
					
						
							|  |  |  |             XmlNode sibling = node.PreviousSibling;  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!document.HasEntityReferences) { | 
					
						
							|  |  |  |                 return sibling;  | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return PreviousSiblingTail(node, sibling); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private XmlNode PreviousSiblingTail(XmlNode node, XmlNode sibling) { | 
					
						
							|  |  |  |             while (sibling == null) { | 
					
						
							|  |  |  |                 node = node.ParentNode; | 
					
						
							|  |  |  |                 if (node == null | 
					
						
							|  |  |  |                     || node.NodeType != XmlNodeType.EntityReference) { | 
					
						
							|  |  |  |                     return null; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 sibling = node.PreviousSibling; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             while (sibling != null | 
					
						
							|  |  |  |                    && sibling.NodeType == XmlNodeType.EntityReference) { | 
					
						
							|  |  |  |                 sibling = sibling.LastChild; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return sibling; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private XmlNode PreviousText(XmlNode node) { | 
					
						
							|  |  |  |             XmlNode text = node.PreviousText; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!document.HasEntityReferences) { | 
					
						
							|  |  |  |                 return text; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return PreviousTextTail(node, text); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private XmlNode PreviousTextTail(XmlNode node, XmlNode text) { | 
					
						
							|  |  |  |             if (text != null) { | 
					
						
							|  |  |  |                 return text; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (!node.IsText) { | 
					
						
							|  |  |  |                 return null; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             XmlNode sibling = node.PreviousSibling; | 
					
						
							|  |  |  |             while (sibling == null) { | 
					
						
							|  |  |  |                 node = node.ParentNode; | 
					
						
							|  |  |  |                 if (node == null | 
					
						
							|  |  |  |                     || node.NodeType != XmlNodeType.EntityReference) { | 
					
						
							|  |  |  |                     return null; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 sibling = node.PreviousSibling; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             while (sibling != null) { | 
					
						
							|  |  |  |                 switch (sibling.NodeType) { | 
					
						
							|  |  |  |                     case XmlNodeType.EntityReference: | 
					
						
							|  |  |  |                         sibling = sibling.LastChild; | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     case XmlNodeType.Text: | 
					
						
							|  |  |  |                     case XmlNodeType.CDATA: | 
					
						
							|  |  |  |                     case XmlNodeType.Whitespace: | 
					
						
							|  |  |  |                     case XmlNodeType.SignificantWhitespace: | 
					
						
							|  |  |  |                         return sibling;  | 
					
						
							|  |  |  |                     default: | 
					
						
							|  |  |  |                         return null; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         internal static bool IsFollowingSibling(XmlNode left, XmlNode right) { | 
					
						
							|  |  |  |             for (;;) { | 
					
						
							|  |  |  |                 left = left.NextSibling; | 
					
						
							|  |  |  |                 if (left == null) { | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (left == right) { | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static bool IsDescendant(XmlNode top, XmlNode bottom) { | 
					
						
							|  |  |  |             for (;;) { | 
					
						
							|  |  |  |                 XmlNode parent = bottom.ParentNode; | 
					
						
							|  |  |  |                 if (parent == null) { | 
					
						
							|  |  |  |                     XmlAttribute attribute = bottom as XmlAttribute; | 
					
						
							|  |  |  |                     if (attribute == null) { | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     parent = attribute.OwnerElement; | 
					
						
							|  |  |  |                     if (parent == null) { | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 bottom = parent; | 
					
						
							|  |  |  |                 if (top == bottom) { | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private static bool IsValidChild(XmlNode parent, XmlNode child) { | 
					
						
							|  |  |  |             switch (parent.NodeType) { | 
					
						
							|  |  |  |                 case XmlNodeType.Element: | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 case XmlNodeType.DocumentFragment: | 
					
						
							|  |  |  |                     switch (child.NodeType) { | 
					
						
							|  |  |  |                         case XmlNodeType.Element: | 
					
						
							|  |  |  |                         case XmlNodeType.Text: | 
					
						
							|  |  |  |                         case XmlNodeType.CDATA: | 
					
						
							|  |  |  |                         case XmlNodeType.ProcessingInstruction: | 
					
						
							|  |  |  |                         case XmlNodeType.Comment: | 
					
						
							|  |  |  |                         case XmlNodeType.Whitespace: | 
					
						
							|  |  |  |                         case XmlNodeType.SignificantWhitespace: | 
					
						
							|  |  |  |                             return true; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case XmlNodeType.Document: | 
					
						
							|  |  |  |                     switch (child.NodeType) { | 
					
						
							|  |  |  |                         case XmlNodeType.Element: | 
					
						
							|  |  |  |                         case XmlNodeType.ProcessingInstruction: | 
					
						
							|  |  |  |                         case XmlNodeType.Comment: | 
					
						
							|  |  |  |                             return true; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private XmlNode TextStart(XmlNode node) { | 
					
						
							|  |  |  |             XmlNode start; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             do { | 
					
						
							|  |  |  |                 start = node; | 
					
						
							|  |  |  |                 node = PreviousSibling(node); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             while (node != null  | 
					
						
							|  |  |  |                    && node.IsText); | 
					
						
							|  |  |  |             return start; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private XmlNode TextEnd(XmlNode node) { | 
					
						
							|  |  |  |             XmlNode end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             do { | 
					
						
							|  |  |  |                 end = node; | 
					
						
							|  |  |  |                 node = NextSibling(node); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             while (node != null | 
					
						
							|  |  |  |                    && node.IsText); | 
					
						
							|  |  |  |             return end; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // An iterator that matches no nodes | 
					
						
							|  |  |  |     internal sealed class DocumentXPathNodeIterator_Empty : XPathNodeIterator { | 
					
						
							|  |  |  |         private XPathNavigator nav; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_Empty( DocumentXPathNavigator nav )               { this.nav = nav.Clone(); } | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_Empty( DocumentXPathNodeIterator_Empty other )    { this.nav = other.nav.Clone(); } | 
					
						
							|  |  |  |         public override XPathNodeIterator Clone()   { return new DocumentXPathNodeIterator_Empty( this ); } | 
					
						
							|  |  |  |         public override bool MoveNext()         { return false; } | 
					
						
							|  |  |  |         public override XPathNavigator Current  { get { return nav; } } | 
					
						
							|  |  |  |         public override int CurrentPosition     { get { return 0; } } | 
					
						
							|  |  |  |         public override int Count                { get { return 0; } }  | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // An iterator that can match any child elements that match the Match condition (overrided in the derived class) | 
					
						
							|  |  |  |     internal abstract class DocumentXPathNodeIterator_ElemDescendants : XPathNodeIterator { | 
					
						
							|  |  |  |         private DocumentXPathNavigator nav; | 
					
						
							|  |  |  |         private int level; | 
					
						
							|  |  |  |         private int position; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_ElemDescendants( DocumentXPathNavigator nav ) { | 
					
						
							|  |  |  |             this.nav      = (DocumentXPathNavigator)(nav.Clone()); | 
					
						
							|  |  |  |             this.level    = 0; | 
					
						
							|  |  |  |             this.position = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_ElemDescendants( DocumentXPathNodeIterator_ElemDescendants other ) { | 
					
						
							|  |  |  |             this.nav      = (DocumentXPathNavigator)(other.nav.Clone()); | 
					
						
							|  |  |  |             this.level    = other.level; | 
					
						
							|  |  |  |             this.position = other.position; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         protected abstract bool Match( XmlNode node ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XPathNavigator Current { | 
					
						
							|  |  |  |             get { return nav; } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override int CurrentPosition { | 
					
						
							|  |  |  |             get { return position; } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         protected void SetPosition( int pos ) { | 
					
						
							|  |  |  |             position = pos; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveNext() { | 
					
						
							|  |  |  |             for (;;) { | 
					
						
							|  |  |  |                 if (nav.MoveToFirstChild()) { | 
					
						
							|  |  |  |                     level++; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     if (level == 0) { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     while (!nav.MoveToNext()) { | 
					
						
							|  |  |  |                         level--; | 
					
						
							|  |  |  |                         if (level == 0) { | 
					
						
							|  |  |  |                             return false; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         if (!nav.MoveToParent()) { | 
					
						
							|  |  |  |                             return false; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 XmlNode node = (XmlNode)nav.UnderlyingObject; | 
					
						
							|  |  |  |                 if (node.NodeType == XmlNodeType.Element && Match(node)) { | 
					
						
							|  |  |  |                     position++; | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Iterate over all element children irrespective of the localName and namespace | 
					
						
							|  |  |  |     internal class DocumentXPathNodeIterator_AllElemChildren : DocumentXPathNodeIterator_ElemDescendants { | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_AllElemChildren( DocumentXPathNavigator nav ) : base( nav ) { | 
					
						
							|  |  |  |             Debug.Assert( ((XmlNode)nav.UnderlyingObject).NodeType != XmlNodeType.Attribute ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_AllElemChildren( DocumentXPathNodeIterator_AllElemChildren other ) : base( other ) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XPathNodeIterator Clone() { | 
					
						
							|  |  |  |             return new DocumentXPathNodeIterator_AllElemChildren( this ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         protected override bool Match( XmlNode node ) { | 
					
						
							|  |  |  |             Debug.Assert( node != null ); | 
					
						
							|  |  |  |             return ( node.NodeType == XmlNodeType.Element ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Iterate over all element children irrespective of the localName and namespace, include the self node when testing for localName/ns | 
					
						
							|  |  |  |     internal sealed class DocumentXPathNodeIterator_AllElemChildren_AndSelf :  DocumentXPathNodeIterator_AllElemChildren { | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_AllElemChildren_AndSelf( DocumentXPathNavigator nav ) : base( nav ) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_AllElemChildren_AndSelf( DocumentXPathNodeIterator_AllElemChildren_AndSelf other ) : base( other ) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XPathNodeIterator Clone() { | 
					
						
							|  |  |  |             return new DocumentXPathNodeIterator_AllElemChildren_AndSelf( this ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveNext() { | 
					
						
							|  |  |  |             if( CurrentPosition == 0 ) { | 
					
						
							|  |  |  |                 DocumentXPathNavigator nav = (DocumentXPathNavigator)this.Current; | 
					
						
							|  |  |  |                 XmlNode node = (XmlNode)nav.UnderlyingObject; | 
					
						
							|  |  |  |                 if ( node.NodeType == XmlNodeType.Element && Match( node ) ) { | 
					
						
							|  |  |  |                     SetPosition( 1 ); | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return base.MoveNext(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Iterate over all element children that have a given namespace but irrespective of the localName | 
					
						
							|  |  |  |     internal class DocumentXPathNodeIterator_ElemChildren_NoLocalName : DocumentXPathNodeIterator_ElemDescendants { | 
					
						
							|  |  |  |         private string nsAtom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_ElemChildren_NoLocalName( DocumentXPathNavigator nav, string nsAtom ) : base( nav ) { | 
					
						
							|  |  |  |             Debug.Assert( ((XmlNode)nav.UnderlyingObject).NodeType != XmlNodeType.Attribute ); | 
					
						
							|  |  |  |             Debug.Assert( Ref.Equal(nav.NameTable.Get( nsAtom ), nsAtom) ); | 
					
						
							|  |  |  |             this.nsAtom = nsAtom; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_ElemChildren_NoLocalName( DocumentXPathNodeIterator_ElemChildren_NoLocalName other ) : base( other ) { | 
					
						
							|  |  |  |             this.nsAtom = other.nsAtom; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         public override XPathNodeIterator Clone() { | 
					
						
							|  |  |  |             return new DocumentXPathNodeIterator_ElemChildren_NoLocalName( this ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         protected override bool Match( XmlNode node ) { | 
					
						
							|  |  |  |             Debug.Assert( node != null ); | 
					
						
							|  |  |  |             Debug.Assert( node.NodeType == XmlNodeType.Element ); | 
					
						
							|  |  |  |             return Ref.Equal(node.NamespaceURI, nsAtom); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Iterate over all element children that have a given namespace but irrespective of the localName, include self node when checking for ns | 
					
						
							|  |  |  |     internal sealed class DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName :  DocumentXPathNodeIterator_ElemChildren_NoLocalName { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName( DocumentXPathNavigator nav, string nsAtom ) : base( nav, nsAtom ) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName( DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName other ) : base( other ) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XPathNodeIterator Clone() { | 
					
						
							|  |  |  |             return new DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName( this ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveNext() { | 
					
						
							|  |  |  |             if( CurrentPosition == 0 ) { | 
					
						
							|  |  |  |                 DocumentXPathNavigator nav = (DocumentXPathNavigator)this.Current; | 
					
						
							|  |  |  |                 XmlNode node = (XmlNode)nav.UnderlyingObject; | 
					
						
							|  |  |  |                 if ( node.NodeType == XmlNodeType.Element && Match( node ) ) { | 
					
						
							|  |  |  |                     SetPosition( 1 ); | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return base.MoveNext(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Iterate over all element children that have a given name and namespace | 
					
						
							|  |  |  |     internal class DocumentXPathNodeIterator_ElemChildren : DocumentXPathNodeIterator_ElemDescendants { | 
					
						
							|  |  |  |         protected string localNameAtom; | 
					
						
							|  |  |  |         protected string nsAtom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_ElemChildren( DocumentXPathNavigator nav, string localNameAtom, string nsAtom ) : base( nav ) { | 
					
						
							|  |  |  |             Debug.Assert( ((XmlNode)nav.UnderlyingObject).NodeType != XmlNodeType.Attribute ); | 
					
						
							|  |  |  |             Debug.Assert( Ref.Equal(nav.NameTable.Get( localNameAtom ), localNameAtom) ); | 
					
						
							|  |  |  |             Debug.Assert( Ref.Equal(nav.NameTable.Get( nsAtom ), nsAtom) ); | 
					
						
							|  |  |  |             Debug.Assert( localNameAtom.Length > 0 );   // Use DocumentXPathNodeIterator_ElemChildren_NoLocalName class for special magic value of localNameAtom | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             this.localNameAtom = localNameAtom; | 
					
						
							|  |  |  |             this.nsAtom        = nsAtom; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_ElemChildren( DocumentXPathNodeIterator_ElemChildren other ) : base( other ) { | 
					
						
							|  |  |  |             this.localNameAtom = other.localNameAtom; | 
					
						
							|  |  |  |             this.nsAtom        = other.nsAtom; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XPathNodeIterator Clone() { | 
					
						
							|  |  |  |             return new DocumentXPathNodeIterator_ElemChildren( this ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         protected override bool Match( XmlNode node ) { | 
					
						
							|  |  |  |             Debug.Assert( node != null ); | 
					
						
							|  |  |  |             Debug.Assert( node.NodeType == XmlNodeType.Element ); | 
					
						
							|  |  |  |             return Ref.Equal(node.LocalName, localNameAtom) && Ref.Equal(node.NamespaceURI, nsAtom); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }     | 
					
						
							|  |  |  |     // Iterate over all elem children and itself and check for the given localName (including the magic value "") and namespace | 
					
						
							|  |  |  |     internal sealed class DocumentXPathNodeIterator_ElemChildren_AndSelf : DocumentXPathNodeIterator_ElemChildren { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_ElemChildren_AndSelf( DocumentXPathNavigator nav, string localNameAtom, string nsAtom ) | 
					
						
							|  |  |  |             : base( nav, localNameAtom, nsAtom ) { | 
					
						
							|  |  |  |             Debug.Assert( localNameAtom.Length > 0 );   // Use DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName if localName == String.Empty | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         internal DocumentXPathNodeIterator_ElemChildren_AndSelf( DocumentXPathNodeIterator_ElemChildren_AndSelf other ) : base( other ) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override XPathNodeIterator Clone() { | 
					
						
							|  |  |  |             return new DocumentXPathNodeIterator_ElemChildren_AndSelf( this ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool MoveNext() { | 
					
						
							|  |  |  |             if( CurrentPosition == 0 ) { | 
					
						
							|  |  |  |                 DocumentXPathNavigator nav = (DocumentXPathNavigator)this.Current; | 
					
						
							|  |  |  |                 XmlNode node = (XmlNode)nav.UnderlyingObject; | 
					
						
							|  |  |  |                 if ( node.NodeType == XmlNodeType.Element && Match( node ) ) { | 
					
						
							|  |  |  |                     SetPosition( 1 ); | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return base.MoveNext(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |