Nowadays, XmlDeclaratoin.WriteTo() writes PI instead of raw.
[mono.git] / mcs / class / System.XML / System.Xml / XmlDocumentNavigator.cs
1 //
2 // System.Xml.XmlDocumentNavigator
3 //
4 // Authors:
5 //   Jason Diamond <jason@injektilo.org>
6 //   Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
7 //
8 // (C) 2002 Jason Diamond
9 // (C) 2003 Atsushi Enomoto
10 //
11
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System;
34 using System.Collections;
35 using System.Xml;
36 using System.Xml.Schema;
37 using System.Xml.XPath;
38
39 namespace System.Xml
40 {
41         internal class XmlDocumentNavigator : XPathNavigator, IHasXmlNode
42         {
43                 #region Constructors
44
45                 internal XmlDocumentNavigator (XmlNode node)
46                 {
47                         this.node = node;
48                         if (node.NodeType == XmlNodeType.Attribute && node.NamespaceURI == XmlNamespaceManager.XmlnsXmlns) {
49                                 nsNode = (XmlAttribute) node; 
50                                 node = nsNode.OwnerElement;
51                         }
52                 }
53
54                 #endregion
55
56                 #region Fields
57                 private const string Xmlns = "http://www.w3.org/2000/xmlns/";
58                 private const string XmlnsXML = "http://www.w3.org/XML/1998/namespace";
59
60                 private XmlNode node;
61                 // Current namespace node (ancestor's attribute of current node).
62                 private XmlAttribute nsNode;
63                 private ArrayList iteratedNsNames;
64                 #endregion
65
66                 #region Properties
67
68                 internal XmlDocument Document {
69                         get { return node.NodeType == XmlNodeType.Document ? node as XmlDocument : node.OwnerDocument; }
70                 }
71
72                 public override string BaseURI {
73                         get {
74                                 return node.BaseURI;
75                         }
76                 }
77
78                 public override bool HasAttributes {
79                         get {
80                                 if (NsNode != null)
81                                         return false;
82
83                                 XmlElement el = node as XmlElement;
84                                 if (el == null || !el.HasAttributes)
85                                         return false;
86
87                                 for (int i = 0; i < node.Attributes.Count; i++)
88                                         if (node.Attributes [i].NamespaceURI != Xmlns)
89                                                 return true;
90                                 return false;
91                         }
92                 }
93
94                 public override bool HasChildren {
95                         get {
96                                 if (NsNode != null)
97                                         return false;
98
99                                 XPathNodeType nodeType = NodeType;
100                                 bool canHaveChildren = nodeType == XPathNodeType.Root || nodeType == XPathNodeType.Element;
101                                 return canHaveChildren && GetFirstChild (node) != null;
102                         }
103                 }
104
105                 public override bool IsEmptyElement {
106                         get {
107                                 if (NsNode != null)
108                                         return false;
109
110                                 return node.NodeType == XmlNodeType.Element 
111                                         && ((XmlElement) node).IsEmpty;
112                         }
113                 }
114
115                 public XmlAttribute NsNode {
116                         get { return nsNode; }
117                         set {
118                                 if (value == null)
119                                         iteratedNsNames = null;
120                                 else
121                                 {
122                                         if (iteratedNsNames == null)
123                                                 iteratedNsNames = new ArrayList();
124                                         else
125                                         {
126                                                 if (iteratedNsNames.IsReadOnly)
127                                                         iteratedNsNames = new ArrayList(iteratedNsNames);
128                                         }
129                                         iteratedNsNames.Add (value.Name);
130                                 }
131                                 nsNode = value;
132                         }
133                 }
134
135                 public override string LocalName {
136                         get {
137                                 XmlAttribute nsNode = NsNode;
138                                 if (nsNode != null) {
139                                         if (nsNode == Document.NsNodeXml)
140                                                 return "xml";
141                                         else
142                                                 return (nsNode.Name == "xmlns") ? String.Empty : nsNode.LocalName;
143                                 }
144
145                                 XPathNodeType nodeType = NodeType;
146                                 bool canHaveName = 
147                                         nodeType == XPathNodeType.Element || 
148                                         nodeType == XPathNodeType.Attribute || 
149                                         nodeType == XPathNodeType.ProcessingInstruction ||
150                                         nodeType == XPathNodeType.Namespace;
151                                 return canHaveName ? node.LocalName : String.Empty;
152                         }
153                 }
154
155                 public override string Name {
156                         get {
157                                 if (NsNode != null)
158                                         return LocalName;
159
160                                 XPathNodeType nodeType = NodeType;
161                                 bool canHaveName = 
162                                         nodeType == XPathNodeType.Element || 
163                                         nodeType == XPathNodeType.Attribute || 
164                                         nodeType == XPathNodeType.ProcessingInstruction ||
165                                         nodeType == XPathNodeType.Namespace;
166                                 return canHaveName ? node.Name : String.Empty;
167                         }
168                 }
169
170                 public override string NamespaceURI {
171                         get { return (NsNode != null) ? String.Empty : node.NamespaceURI; }
172                 }
173
174                 public override XmlNameTable NameTable {
175                         get { return Document.NameTable; }
176                 }
177
178                 public override XPathNodeType NodeType {
179                         get {
180                                 if (NsNode != null)
181                                         return XPathNodeType.Namespace;
182                                 XmlNode n = node;
183                                 bool sw = false;
184                                 do {
185                                         switch (n.NodeType) {
186                                         case XmlNodeType.SignificantWhitespace:
187                                                 sw = true;
188                                                 n = GetNextSibling (n);
189                                                 break;
190                                         case XmlNodeType.Whitespace:
191                                                 n = GetNextSibling (n);
192                                                 break;
193                                         case XmlNodeType.Text:
194                                         case XmlNodeType.CDATA:
195                                                 return XPathNodeType.Text;
196                                         default:
197                                                 n = null;
198                                                 break;
199                                         }
200                                 } while (n != null);
201                                 return sw ?
202                                         XPathNodeType.SignificantWhitespace :
203                                         node.XPathNodeType;
204                         }
205                 }
206
207                 public override string Prefix {
208                         get { return (NsNode != null) ? String.Empty : node.Prefix; }
209                 }
210
211 #if NET_2_0
212                 public override IXmlSchemaInfo SchemaInfo {
213                         get { return NsNode != null ? null : node.SchemaInfo; }
214                 }
215
216                 public override object UnderlyingObject {
217                         get { return node; }
218                 }
219 #endif
220
221                 public override string Value {
222                         get {
223                                 switch (NodeType) {
224                                 case XPathNodeType.Attribute:
225                                 case XPathNodeType.Comment:
226                                 case XPathNodeType.ProcessingInstruction:
227                                         return node.Value;
228                                 case XPathNodeType.Text:
229                                 case XPathNodeType.Whitespace:
230                                 case XPathNodeType.SignificantWhitespace:
231                                         string value = node.Value;
232                                         for (XmlNode n = GetNextSibling (node); n != null; n = GetNextSibling (n)) {
233                                                 switch (n.XPathNodeType) {
234                                                 case XPathNodeType.Text:
235                                                 case XPathNodeType.Whitespace:
236                                                 case XPathNodeType.SignificantWhitespace:
237                                                         value += n.Value;
238                                                         continue;
239                                                 }
240                                                 break;
241                                         }
242                                         return value;
243                                 case XPathNodeType.Element:
244                                 case XPathNodeType.Root:
245                                         return node.InnerText;
246                                 case XPathNodeType.Namespace:
247                                         return NsNode == Document.NsNodeXml ? XmlnsXML : NsNode.Value;
248                                 }
249                                 return String.Empty;
250                         }
251                 }
252
253                 public override string XmlLang {
254                         get {
255                                 return node.XmlLang;
256                         }
257                 }
258
259                 #endregion
260
261                 #region Methods
262
263                 private bool CheckNsNameAppearance (string name, string ns)
264                 {
265                         if (iteratedNsNames != null && iteratedNsNames.Contains (name))
266                                 return true;
267                         // default namespace erasure - just add name and never return this node
268                         if (ns == String.Empty) {
269                                 if (iteratedNsNames == null)
270                                         iteratedNsNames = new ArrayList();
271                                 else
272                                 {
273                                         if (iteratedNsNames.IsReadOnly)
274                                                 iteratedNsNames = new ArrayList(iteratedNsNames);
275                                 }
276                                 iteratedNsNames.Add ("xmlns");
277                                 return true;
278                         }
279
280                         return false;
281                 }
282
283                 public override XPathNavigator Clone ()
284                 {
285                         XmlDocumentNavigator clone = new XmlDocumentNavigator (node);
286                         clone.nsNode = nsNode;
287                         clone.iteratedNsNames = (iteratedNsNames == null || iteratedNsNames.IsReadOnly) ? iteratedNsNames : ArrayList.ReadOnly(iteratedNsNames);
288                         return clone;
289                 }
290
291                 public override string GetAttribute (string localName, string namespaceURI)
292                 {
293                         if (HasAttributes) {
294                                 XmlElement el = Node as XmlElement;
295                                 return el != null ? el.GetAttribute (localName, namespaceURI) : String.Empty;
296                         }
297                         return String.Empty;
298                 }
299
300                 public override string GetNamespace (string name)
301                 {
302                         // MSDN says "String.Empty if a matching namespace 
303                         // node is not found or if the navigator is not 
304                         // positioned on an element node", but in fact it
305                         // returns actual namespace for the other nodes.
306                         return Node.GetNamespaceOfPrefix (name);
307                 }
308
309                 public override bool IsDescendant (XPathNavigator other)
310                 {
311                         if (NsNode != null)
312                                 return false;
313                         XmlDocumentNavigator o = other as XmlDocumentNavigator;
314                         if (o == null)
315                                 return false;
316                         XmlNode n =
317                                 o.node.NodeType == XmlNodeType.Attribute ?
318                                 ((XmlAttribute) o.node).OwnerElement :
319                                 o.node.ParentNode;
320                         for (;n != null; n = n.ParentNode)
321                                 if (n == node)
322                                         return true;
323                         return false;
324                 }
325
326                 public override bool IsSamePosition (XPathNavigator other)
327                 {
328                         XmlDocumentNavigator otherDocumentNavigator = other as XmlDocumentNavigator;
329                         if (otherDocumentNavigator != null)
330                                 return node == otherDocumentNavigator.node
331                                         && NsNode == otherDocumentNavigator.NsNode;
332                         return false;
333                 }
334
335                 public override bool MoveTo (XPathNavigator other)
336                 {
337                         XmlDocumentNavigator otherDocumentNavigator = other as XmlDocumentNavigator;
338                         if (otherDocumentNavigator != null) {
339                                 if (Document == otherDocumentNavigator.Document) {
340                                         node = otherDocumentNavigator.node;
341                                         NsNode = otherDocumentNavigator.NsNode;
342                                         return true;
343                                 }
344                         }
345                         return false;
346                 }
347
348                 public override bool MoveToAttribute (string localName, string namespaceURI)
349                 {
350                         if (HasAttributes) {
351                                 XmlAttribute attr = node.Attributes [localName, namespaceURI];
352                                 if (attr != null) {
353                                         node = attr;
354                                         NsNode = null;
355                                         return true;
356                                 }
357                         }
358                         return false;
359                 }
360
361 #if NET_2_0
362 #else
363                 public override bool MoveToFirst ()
364                 {
365                         return MoveToFirstImpl ();
366                 }
367 #endif
368
369                 public override bool MoveToFirstAttribute ()
370                 {
371                         if (NodeType == XPathNodeType.Element) {
372                                 XmlElement el = node as XmlElement;
373                                 if (!el.HasAttributes)
374                                         return false;
375                                 for (int i = 0; i < node.Attributes.Count; i++) {
376                                         XmlAttribute attr = node.Attributes [i];
377                                         if (attr.NamespaceURI != Xmlns) {
378                                                 node = attr;
379                                                 NsNode = null;
380                                                 return true;
381                                         }
382                                 }
383                         }
384                         return false;
385                 }
386
387                 public override bool MoveToFirstChild ()
388                 {
389                         if (HasChildren) {
390                                 XmlNode n = GetFirstChild (node);
391                                 if (n == null)
392                                         return false;
393                                 node = n;
394                                 return true;
395                         }
396                         return false;
397                 }
398
399                 public override bool MoveToFirstNamespace (XPathNamespaceScope namespaceScope)
400                 {
401                         if (NodeType != XPathNodeType.Element)
402                                 return false;
403                         XmlElement el = node as XmlElement;
404                         do {
405                                 if (el.HasAttributes) {
406                                         for (int i = 0; i < el.Attributes.Count; i++) {
407                                                 XmlAttribute attr = el.Attributes [i];
408                                                 if (attr.NamespaceURI == Xmlns) {
409                                                         if (CheckNsNameAppearance (attr.Name, attr.Value))
410                                                                 continue;
411                                                         NsNode = attr;
412                                                         return true;
413                                                 }
414                                         }
415                                 }
416                                 if (namespaceScope == XPathNamespaceScope.Local)
417                                         return false;
418                                 el = GetParentNode (el) as XmlElement;
419                         } while (el != null);
420
421                         if (namespaceScope == XPathNamespaceScope.All) {
422                                 if (CheckNsNameAppearance (Document.NsNodeXml.Name, Document.NsNodeXml.Value))
423                                         return false;
424                                 NsNode = Document.NsNodeXml;
425                                 return true;
426                         }
427                         else
428                                 return false;
429                 }
430
431                 public override bool MoveToId (string id)
432                 {
433                         XmlElement eltNew = Document.GetElementById (id);
434                         if (eltNew == null)
435                                 return false;
436
437                         node = eltNew;
438                         return true;
439                 }
440
441                 public override bool MoveToNamespace (string name)
442                 {
443                         if (name == "xml") {
444                                 NsNode = Document.NsNodeXml;
445                                 return true;
446                         }
447
448                         if (NodeType != XPathNodeType.Element)
449                                 return false;
450
451                         XmlElement el = node as XmlElement;
452                         do {
453                                 if (el.HasAttributes) {
454                                         for (int i = 0; i < el.Attributes.Count; i++) {
455                                                 XmlAttribute attr = el.Attributes [i];
456                                                 if (attr.NamespaceURI == Xmlns && attr.Name == name) {
457                                                         NsNode = attr;
458                                                         return true;
459                                                 }
460                                         }
461                                 }
462                                 el = GetParentNode (node) as XmlElement;
463                         } while (el != null);
464                         return false;
465                 }
466
467                 public override bool MoveToNext ()
468                 {
469                         if (NsNode != null)
470                                 return false;
471
472                         XmlNode n = node;
473                         if (NodeType == XPathNodeType.Text) {
474                                 do {
475                                         n = GetNextSibling (n);
476                                         if (n == null)
477                                                 return false;
478                                         switch (n.NodeType) {
479                                         case XmlNodeType.CDATA:
480                                         case XmlNodeType.SignificantWhitespace:
481                                         case XmlNodeType.Text:
482                                         case XmlNodeType.Whitespace:
483                                                 continue;
484                                         default:
485                                                 break;
486                                         }
487                                         break;
488                                 } while (true);
489                         }
490                         else
491                                 n = GetNextSibling (n);
492                         if (n == null)
493                                 return false;
494                         node = n;
495                         return true;
496                 }
497
498                 public override bool MoveToNextAttribute ()
499                 {
500                         if (node == null)
501                                 return false;
502                         if (NodeType != XPathNodeType.Attribute)
503                                 return false;
504
505                         // Find current attribute.
506                         int pos = 0;
507                         XmlElement owner = ((XmlAttribute) node).OwnerElement;
508                         if (owner == null)
509                                 return false;
510
511                         int count = owner.Attributes.Count;
512                         for(; pos < count; pos++)
513                                 if (owner.Attributes [pos] == node)
514                                         break;
515                         if (pos == count)
516                                 return false;   // Where is current attribute? Maybe removed.
517
518                         // Find next attribute.
519                         for(pos++; pos < count; pos++) {
520                                 if (owner.Attributes [pos].NamespaceURI != Xmlns) {
521                                         node = owner.Attributes [pos];
522                                         NsNode = null;
523                                         return true;
524                                 }
525                         }
526                         return false;
527                 }
528
529                 public override bool MoveToNextNamespace (XPathNamespaceScope namespaceScope)
530                 {
531                         if (NsNode == Document.NsNodeXml)
532                                 // Current namespace is "xml", so there should be no more namespace nodes.
533                                 return false;
534
535                         if (NsNode == null)
536                                 return false;
537
538                         // Get current attribute's position.
539                         int pos = 0;
540                         XmlElement owner = ((XmlAttribute) NsNode).OwnerElement;
541                         if (owner == null)
542                                 return false;
543
544                         int count = owner.Attributes.Count;
545                         for(; pos < count; pos++)
546                                 if (owner.Attributes [pos] == NsNode)
547                                         break;
548                         if (pos == count)
549                                 return false;   // Where is current attribute? Maybe removed.
550
551                         // Find next namespace from the same element as current ns node.
552                         for(pos++; pos < count; pos++) {
553                                 if (owner.Attributes [pos].NamespaceURI == Xmlns) {
554                                         XmlAttribute a = owner.Attributes [pos];
555                                         if (CheckNsNameAppearance (a.Name, a.Value))
556                                                 continue;
557                                         NsNode = a;
558                                         return true;
559                                 }
560                         }
561
562                         // If not found more, then find from ancestors.
563                         // But if scope is Local, then it returns false here.
564                         if (namespaceScope == XPathNamespaceScope.Local)
565                                 return false;
566                         owner = GetParentNode (owner) as XmlElement;
567                         while (owner != null) {
568                                 if (owner.HasAttributes) {
569                                         for (int i = 0; i < owner.Attributes.Count; i++) {
570                                                 XmlAttribute attr = owner.Attributes [i];
571                                                 if (attr.NamespaceURI == Xmlns) {
572                                                         if (CheckNsNameAppearance (attr.Name, attr.Value))
573                                                                 continue;
574                                                         NsNode = attr;
575                                                         return true;
576                                                 }
577                                         }
578                                 }
579                                 owner = GetParentNode (owner) as XmlElement;
580                         }
581
582                         if (namespaceScope == XPathNamespaceScope.All) {
583                                 if (CheckNsNameAppearance (Document.NsNodeXml.Name, Document.NsNodeXml.Value))
584                                         return false;
585                                 NsNode = Document.NsNodeXml;
586                                 return true;
587                         }
588                         return false;
589                 }
590
591                 public override bool MoveToParent ()
592                 {
593                         if (NsNode != null) {
594                                 NsNode = null;
595                                 return true;
596                         }
597                         else if (node.NodeType == XmlNodeType.Attribute) {
598                                 XmlElement ownerElement = ((XmlAttribute)node).OwnerElement;
599                                 if (ownerElement != null) {
600                                         node = ownerElement;
601                                         NsNode = null;
602                                         return true;
603                                 }
604                                 else
605                                         return false;
606                         }
607                         XmlNode n = GetParentNode (node);
608                         if (n == null)
609                                 return false;
610                         node = n;
611                         NsNode = null;
612                         return true;
613                 }
614
615                 public override bool MoveToPrevious ()
616                 {
617                         if (NsNode != null)
618                                 return false;
619
620                         XmlNode p = GetPreviousSibling (node);
621                         if (p == null)
622                                 return false;
623                         node = p;
624                         return true;
625                 }
626
627                 public override void MoveToRoot ()
628                 {
629                         XmlAttribute attr = node as XmlAttribute;
630                         XmlNode tmp = attr != null ? attr.OwnerElement : node;
631                         if (tmp == null)
632                                 return; // i.e. attr has null OwnerElement.
633                         for (XmlNode tmp2 = GetParentNode (tmp); tmp2 != null; tmp2 = GetParentNode (tmp2))
634                                 tmp = tmp2;
635                         node = tmp;
636                         NsNode = null;
637                 }
638
639                 private XmlNode Node { get { return NsNode != null ? NsNode : node; } }
640
641                 XmlNode IHasXmlNode.GetNode ()
642                 {
643                         return Node;
644                 }
645
646                 private XmlNode GetFirstChild (XmlNode n)
647                 {
648                         if (n.FirstChild == null)
649                                 return null;
650                         switch (n.FirstChild.NodeType) {
651                         case XmlNodeType.XmlDeclaration:
652                         case XmlNodeType.DocumentType:
653                                 return GetNextSibling (n.FirstChild);
654                         case XmlNodeType.EntityReference:
655                                 foreach (XmlNode c in n.ChildNodes) {
656                                         if (c.NodeType == XmlNodeType.EntityReference) {
657                                                 XmlNode ec = GetFirstChild (c);
658                                                 if (ec != null)
659                                                         return ec;
660                                         }
661                                         else
662                                                 return c;
663                                 }
664                                 return null;
665                         default:
666                                 return n.FirstChild;
667                         }
668                 }
669
670                 private XmlNode GetLastChild (XmlNode n)
671                 {
672                         if (n.LastChild == null)
673                                 return null;
674                         switch (n.LastChild.NodeType) {
675                         case XmlNodeType.XmlDeclaration:
676                         case XmlNodeType.DocumentType:
677                                 return GetPreviousSibling (n.LastChild);
678                         case XmlNodeType.EntityReference:
679                                 for (XmlNode c = n.LastChild; c != null; c = c.PreviousSibling) {
680                                         if (c.NodeType == XmlNodeType.EntityReference) {
681                                                 XmlNode ec = GetLastChild (c);
682                                                 if (ec != null)
683                                                         return ec;
684                                         }
685                                         else
686                                                 return c;
687                                 }
688                                 return null;
689                         default:
690                                 return n.LastChild;
691                         }
692                 }
693
694                 private XmlNode GetPreviousSibling (XmlNode n)
695                 {
696                         XmlNode p = n.PreviousSibling;
697                         if (p != null) {
698                                 switch (p.NodeType) {
699                                 case XmlNodeType.EntityReference:
700                                         XmlNode c = GetLastChild (p);
701                                         if (c != null)
702                                                 return c;
703                                         else // empty entity reference etc.
704                                                 return GetPreviousSibling (p);
705                                 case XmlNodeType.XmlDeclaration:
706                                 case XmlNodeType.DocumentType:
707                                         return GetPreviousSibling (p);
708                                 default:
709                                         return p;
710                                 }
711                         } else {
712                                 if (n.ParentNode == null || n.ParentNode.NodeType != XmlNodeType.EntityReference)
713                                         return null;
714                                 return GetPreviousSibling (n.ParentNode);
715                         }
716                 }
717
718                 private XmlNode GetNextSibling (XmlNode n)
719                 {
720                         XmlNode nx = n.NextSibling;
721                         if (nx != null) {
722                                 switch (nx.NodeType) {
723                                 case XmlNodeType.EntityReference:
724                                         XmlNode c = GetFirstChild (nx);
725                                         if (c != null)
726                                                 return c;
727                                         else // empty entity reference etc.
728                                                 return GetNextSibling (nx);
729                                 case XmlNodeType.XmlDeclaration:
730                                 case XmlNodeType.DocumentType:
731                                         return GetNextSibling (nx);
732                                 default:
733                                         return n.NextSibling;
734                                 }
735                         } else {
736                                 if (n.ParentNode == null || n.ParentNode.NodeType != XmlNodeType.EntityReference)
737                                         return null;
738                                 return GetNextSibling (n.ParentNode);
739                         }
740                 }
741
742                 private XmlNode GetParentNode (XmlNode n)
743                 {
744                         if (n.ParentNode == null)
745                                 return null;
746                         for (XmlNode p = n.ParentNode; p != null; p = p.ParentNode)
747                                 if (p.NodeType != XmlNodeType.EntityReference)
748                                         return p;
749                         return null;
750                 }
751
752 #if NET_2_0
753                 public
754 #else
755                 internal
756 #endif
757                 override string LookupNamespace (string prefix)
758                 {
759                         // FIXME: optimize
760                         return base.LookupNamespace (prefix);
761                 }
762
763 #if NET_2_0
764                 public
765 #else
766                 internal
767 #endif
768                 override string LookupPrefix (string namespaceUri)
769                 {
770                         // FIXME: optimize
771                         return base.LookupPrefix (namespaceUri);
772                 }
773
774 #if NET_2_0
775                 public
776 #else
777                 internal
778 #endif
779                 override bool MoveToChild (XPathNodeType type)
780                 {
781                         // FIXME: optimize
782                         return base.MoveToChild (type);
783                 }
784
785 #if NET_2_0
786                 public
787 #else
788                 internal
789 #endif
790                 override bool MoveToChild (string localName, string namespaceURI)
791                 {
792                         // FIXME: optimize
793                         return base.MoveToChild (localName, namespaceURI);
794                 }
795
796 #if NET_2_0
797                 public
798 #else
799                 internal
800 #endif
801                 override bool MoveToNext (string localName, string namespaceURI)
802                 {
803                         // FIXME: optimize
804                         return base.MoveToNext (localName, namespaceURI);
805                 }
806
807 #if NET_2_0
808                 public
809 #else
810                 internal
811 #endif
812                 override bool MoveToNext (XPathNodeType type)
813                 {
814                         // FIXME: optimize
815                         return base.MoveToNext (type);
816                 }
817
818 #if NET_2_0
819                 public
820 #else
821                 internal
822 #endif
823                 override bool MoveToFollowing (string localName,
824                         string namespaceURI, XPathNavigator end)
825                 {
826                         // FIXME: optimize
827                         return base.MoveToFollowing (localName, namespaceURI, end);
828                 }
829
830 #if NET_2_0
831                 public
832 #else
833                 internal
834 #endif
835                 override bool MoveToFollowing (XPathNodeType type,
836                         XPathNavigator end)
837                 {
838                         // FIXME: optimize
839                         return base.MoveToFollowing (type, end);
840                 }
841                 #endregion
842         }
843 }