Bug 15572. Lookup KnownTypeCollection element types in MSSimpleNamespace
[mono.git] / mcs / class / System.XML / System.Xml / XmlReader.cs
1 //
2 // XmlReader.cs
3 //
4 // Authors:
5 //      Jason Diamond (jason@injektilo.org)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //      Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
8 //
9 // (C) 2001, 2002 Jason Diamond  http://injektilo.org/
10 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
11 // (C) 2003 Atsushi Enomoto
12 //
13
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34 using System.Collections;
35 using System.Diagnostics;
36 using System.IO;
37 using System.Text;
38 using System.Xml.Schema; // only required for NET_2_0 (SchemaInfo)
39 using System.Xml.Serialization; // only required for NET_2_0 (SchemaInfo)
40 using Mono.Xml.Schema; // only required for NET_2_0
41 using Mono.Xml; // only required for NET_2_0
42 #if NET_4_5
43 using System.Threading;
44 using System.Threading.Tasks;
45 #endif
46
47 namespace System.Xml
48 {
49 #if NET_2_0
50         public abstract class XmlReader : IDisposable
51 #else
52         public abstract class XmlReader
53 #endif
54         {
55                 private StringBuilder readStringBuffer;
56                 private XmlReaderBinarySupport binary;
57 #if NET_2_0
58                 private XmlReaderSettings settings;
59 #endif
60
61                 #region Constructor
62
63                 protected XmlReader ()
64                 {
65                 }
66
67                 #endregion
68
69                 #region Properties
70
71                 public abstract int AttributeCount { get; }
72
73                 public abstract string BaseURI { get; }
74
75                 internal XmlReaderBinarySupport Binary {
76                         get { return binary; }
77                 }
78
79                 internal XmlReaderBinarySupport.CharGetter BinaryCharGetter {
80                         get { return binary != null ? binary.Getter : null; }
81                         set {
82                                 if (binary == null)
83                                         binary = new XmlReaderBinarySupport (this);
84                                 binary.Getter = value;
85                         }
86                 }
87
88 #if NET_2_0
89                 // To enable it internally in sys.xml, just insert these
90                 // two lines into Read():
91                 //
92                 //      #if NET_2_0
93                 //      if (Binary != null)
94                 //              Binary.Reset ();
95                 //      #endif
96                 //
97                 public virtual bool CanReadBinaryContent {
98                         get { return false; }
99                 }
100
101                 public virtual bool CanReadValueChunk {
102                         get { return false; }
103                 }
104 #else
105                 internal virtual bool CanReadBinaryContent {
106                         get { return false; }
107                 }
108
109                 internal virtual bool CanReadValueChunk {
110                         get { return false; }
111                 }
112 #endif
113
114                 public virtual bool CanResolveEntity
115                 {
116                         get     { return false; }
117                 }
118
119                 public abstract int Depth { get; }
120
121                 public abstract bool EOF { get; }
122
123                 public virtual bool HasAttributes
124                 {
125                         get { return AttributeCount > 0; }
126                 }
127
128 #if NET_4_0
129                 public virtual bool HasValue {
130                         get {
131                                 switch (NodeType) {
132                                 case XmlNodeType.Attribute:
133                                 case XmlNodeType.Comment:
134                                 case XmlNodeType.ProcessingInstruction:
135                                 case XmlNodeType.SignificantWhitespace:
136                                 case XmlNodeType.CDATA:
137                                 case XmlNodeType.Text:
138                                 case XmlNodeType.Whitespace:
139                                 case XmlNodeType.XmlDeclaration:
140                                         return true;
141                                 }
142                                 return false;
143                         }
144                 }
145 #else
146                 public abstract bool HasValue { get; }
147 #endif
148
149                 public abstract bool IsEmptyElement { get; }
150
151 #if NET_2_0
152                 public virtual bool IsDefault {
153                         get { return false; }
154                 }
155
156                 public virtual string this [int i] {
157                         get { return GetAttribute (i); }
158                 }
159
160                 public virtual string this [string name] {
161                         get { return GetAttribute (name); }
162                 }
163
164                 public virtual string this [string name, string namespaceURI] {
165                         get { return GetAttribute (name, namespaceURI); }
166                 }
167 #else
168                 public abstract bool IsDefault { get; }
169
170                 public abstract string this [int i] { get; }
171
172                 public abstract string this [string name] { get; }
173
174                 public abstract string this [string localName, string namespaceName] { get; }
175 #endif
176
177                 public abstract string LocalName { get; }
178
179 #if NET_2_0
180                 public virtual string Name {
181                         get {
182                                 return Prefix.Length > 0 ?
183                                         String.Concat (Prefix, ":", LocalName) :
184                                         LocalName;
185                         }
186                 }
187 #else
188                 public abstract string Name { get; }
189 #endif
190
191                 public abstract string NamespaceURI { get; }
192
193                 public abstract XmlNameTable NameTable { get; }
194
195                 public abstract XmlNodeType NodeType { get; }
196
197                 public abstract string Prefix { get; }
198
199 #if NET_2_0
200                 public virtual char QuoteChar {
201                         get { return '\"'; }
202                 }
203 #else
204                 public abstract char QuoteChar { get; }
205 #endif
206
207                 public abstract ReadState ReadState { get; }
208
209 #if NET_2_0
210                 public virtual IXmlSchemaInfo SchemaInfo {
211                         get { return null; }
212                 }
213
214                 public virtual XmlReaderSettings Settings {
215                         get { return settings; }
216                 }
217 #endif
218
219                 public abstract string Value { get; }
220
221 #if NET_2_0
222                 public virtual string XmlLang {
223                         get { return String.Empty; }
224                 }
225
226                 public virtual XmlSpace XmlSpace {
227                         get { return XmlSpace.None; }
228                 }
229 #else
230                 public abstract string XmlLang { get; }
231
232                 public abstract XmlSpace XmlSpace { get; }
233 #endif
234
235                 #endregion
236
237                 #region Methods
238
239 #if NET_4_5
240                 public virtual void Close ()
241                 {
242                         if (asyncRunning)
243                                 throw new InvalidOperationException ("An asynchronous operation is already in progress.");
244                 }
245 #else
246                 public abstract void Close ();
247 #endif
248
249 #if NET_2_0
250                 private static XmlNameTable PopulateNameTable (
251                         XmlReaderSettings settings)
252                 {
253                         XmlNameTable nameTable = settings.NameTable;
254                         if (nameTable == null)
255                                 nameTable = new NameTable ();
256                         return nameTable;
257                 }
258
259                 private static XmlParserContext PopulateParserContext (
260                         XmlReaderSettings settings, string baseUri)
261                 {
262                         XmlNameTable nt = PopulateNameTable (settings);
263                         return new XmlParserContext (nt,
264                                 new XmlNamespaceManager (nt),
265                                 null,
266                                 null,
267                                 null,
268                                 null,
269                                 baseUri,
270                                 null,
271                                 XmlSpace.None,
272                                 null);
273                 }
274
275                 private static XmlNodeType GetNodeType (
276                         XmlReaderSettings settings)
277                 {
278                         ConformanceLevel level = settings != null ? settings.ConformanceLevel : ConformanceLevel.Auto;
279                         return
280                                 level == ConformanceLevel.Fragment ?
281                                 XmlNodeType.Element :
282                                 XmlNodeType.Document;
283                 }
284
285                 public static XmlReader Create (Stream input)
286                 {
287                         return Create (input, null);
288                 }
289
290                 public static XmlReader Create (string inputUri)
291                 {
292                         return Create (inputUri, null);
293                 }
294
295                 public static XmlReader Create (TextReader input)
296                 {
297                         return Create (input, null);
298                 }
299
300                 public static XmlReader Create (string inputUri, XmlReaderSettings settings)
301                 {
302                         return Create (inputUri, settings, null);
303                 }
304
305                 public static XmlReader Create (Stream input, XmlReaderSettings settings)
306                 {
307                         return Create (input, settings, String.Empty);
308                 }
309
310                 public static XmlReader Create (TextReader input, XmlReaderSettings settings)
311                 {
312                         return Create (input, settings, String.Empty);
313                 }
314
315                 static XmlReaderSettings PopulateSettings (XmlReaderSettings src)
316                 {
317                         XmlReaderSettings copy;
318                         if (src == null)
319                                 copy = new XmlReaderSettings ();
320                         else
321                                 copy = src.Clone ();
322 #if NET_4_5
323                         copy.SetReadOnly ();
324 #endif
325                         return copy;
326                 }
327
328                 static XmlReaderSettings PopulateSettings (XmlReader reader, XmlReaderSettings src)
329                 {
330                         XmlReaderSettings copy;
331                         if (src == null)
332                                 copy = new XmlReaderSettings ();
333                         else
334                                 copy = src.Clone ();
335 #if NET_4_5
336                         if (reader.Settings != null)
337                                 copy.Async = reader.Settings.Async;
338                         copy.SetReadOnly ();
339 #endif
340                         return copy;
341                 }
342
343                 public static XmlReader Create (Stream input, XmlReaderSettings settings, string baseUri)
344                 {
345                         settings = PopulateSettings (settings);
346                         return Create (input, settings,
347                                 PopulateParserContext (settings, baseUri));
348                 }
349
350                 public static XmlReader Create (TextReader input, XmlReaderSettings settings, string baseUri)
351                 {
352                         settings = PopulateSettings (settings);
353                         return Create (input, settings,
354                                 PopulateParserContext (settings, baseUri));
355                 }
356
357                 public static XmlReader Create (XmlReader reader, XmlReaderSettings settings)
358                 {
359                         settings = PopulateSettings (reader, settings);
360                         XmlReader r = CreateFilteredXmlReader (reader, settings);
361                         r.settings = settings;
362                         return r;
363                 }
364
365                 public static XmlReader Create (string inputUri, XmlReaderSettings settings, XmlParserContext inputContext)
366                 {
367                         settings = PopulateSettings (settings);
368                         bool closeInputBak = settings.CloseInput;
369                         try {
370                                 settings.CloseInput = true; // forced. See XmlReaderCommonTests.CreateFromUrlClose().
371                                 if (inputContext == null)
372                                         inputContext = PopulateParserContext (settings, inputUri);
373                                 XmlTextReader xtr = new XmlTextReader (false, settings.XmlResolver, inputUri, GetNodeType (settings), inputContext);
374                                 XmlReader ret = CreateCustomizedTextReader (xtr, settings);
375                                 return ret;
376                         } finally {
377                                 settings.CloseInput = closeInputBak;
378                         }
379                 }
380
381                 public static XmlReader Create (Stream input, XmlReaderSettings settings, XmlParserContext inputContext)
382                 {
383                         settings = PopulateSettings (settings);
384                         if (inputContext == null)
385                                 inputContext = PopulateParserContext (settings, String.Empty);
386                         return CreateCustomizedTextReader (new XmlTextReader (input, GetNodeType (settings), inputContext), settings);
387                 }
388
389                 public static XmlReader Create (TextReader input, XmlReaderSettings settings, XmlParserContext inputContext)
390                 {
391                         settings = PopulateSettings (settings);
392                         if (inputContext == null)
393                                 inputContext = PopulateParserContext (settings, String.Empty);
394                         return CreateCustomizedTextReader (new XmlTextReader (inputContext.BaseURI, input, GetNodeType (settings), inputContext), settings);
395                 }
396
397                 private static XmlReader CreateCustomizedTextReader (XmlTextReader reader, XmlReaderSettings settings)
398                 {
399                         reader.XmlResolver = settings.XmlResolver;
400                         // Normalization is set true by default.
401                         reader.Normalization = true;
402                         reader.EntityHandling = EntityHandling.ExpandEntities;
403
404                         if (settings.ProhibitDtd)
405                                 reader.ProhibitDtd = true;
406
407                         if (!settings.CheckCharacters)
408                                 reader.CharacterChecking = false;
409
410                         // I guess it might be changed in 2.0 RTM to set true
411                         // as default, or just disappear. It goes against
412                         // XmlTextReader's default usage and users will have 
413                         // to close input manually (that's annoying). Moreover,
414                         // MS XmlTextReader consumes text input more than 
415                         // actually read and users can acquire those extra
416                         // consumption by GetRemainder() that returns different
417                         // TextReader.
418                         reader.CloseInput = settings.CloseInput;
419
420                         // I would like to support it in detail later;
421                         // MSDN description looks source of confusion. We don't
422                         // need examples, but precise list of how it works.
423                         reader.Conformance = settings.ConformanceLevel;
424
425                         reader.AdjustLineInfoOffset (settings.LineNumberOffset,
426                                 settings.LinePositionOffset);
427
428                         if (settings.NameTable != null)
429                                 reader.SetNameTable (settings.NameTable);
430
431                         XmlReader r = CreateFilteredXmlReader (reader, settings);
432                         r.settings = settings;
433                         return r;
434                 }
435
436                 private static XmlReader CreateFilteredXmlReader (XmlReader reader, XmlReaderSettings settings)
437                 {
438                         ConformanceLevel conf = ConformanceLevel.Auto;
439                         if (reader is XmlTextReader)
440                                 conf = ((XmlTextReader) reader).Conformance;
441                         else if (reader.Settings != null)
442                                 conf = reader.Settings.ConformanceLevel;
443                         else
444                                 conf = settings.ConformanceLevel;
445                         if (settings.ConformanceLevel != ConformanceLevel.Auto &&
446                                 conf != settings.ConformanceLevel)
447                                 throw new InvalidOperationException (String.Format ("ConformanceLevel cannot be overwritten by a wrapping XmlReader. The source reader has {0}, while {1} is specified.", conf, settings.ConformanceLevel));
448                         settings.ConformanceLevel = conf;
449
450                         reader = CreateValidatingXmlReader (reader, settings);
451
452                         if ( settings.IgnoreComments ||
453                              settings.IgnoreProcessingInstructions ||
454                              settings.IgnoreWhitespace)
455                                 return new XmlFilterReader (reader, settings);
456                         else {
457                                 reader.settings = settings;
458                                 return reader;
459                         }
460                 }
461
462                 private static XmlReader CreateValidatingXmlReader (XmlReader reader, XmlReaderSettings settings)
463                 {
464                         XmlValidatingReader xvr = null;
465                         switch (settings.ValidationType) {
466                         // Auto and XDR are obsoleted in 2.0 and therefore ignored.
467                         default:
468                                 return reader;
469                         case ValidationType.DTD:
470                                 xvr = new XmlValidatingReader (reader);
471                                 xvr.XmlResolver = settings.XmlResolver;
472                                 xvr.ValidationType = ValidationType.DTD;
473                                 break;
474                         case ValidationType.Schema:
475                                 return new XmlSchemaValidatingReader (reader, settings);
476                         }
477
478                         // Actually I don't think they are treated in DTD validation though...
479                         if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessIdentityConstraints) == 0)
480                                 throw new NotImplementedException ();
481                         //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) != 0)
482                         //      throw new NotImplementedException ();
483                         //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessSchemaLocation) != 0)
484                         //      throw new NotImplementedException ();
485                         //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ReportValidationWarnings) == 0)
486                         //      throw new NotImplementedException ();
487
488                         return xvr != null ? xvr : reader;
489                 }
490
491 #if NET_4_0
492                 public void Dispose ()
493 #else
494                 void IDisposable.Dispose() 
495 #endif
496                 {
497                         Dispose (false);
498                 }
499
500                 protected virtual void Dispose (bool disposing)
501                 {
502                         if (ReadState != ReadState.Closed)
503                                 Close ();
504                 }
505 #endif
506
507                 public abstract string GetAttribute (int i);
508
509                 public abstract string GetAttribute (string name);
510
511                 public abstract string GetAttribute (string name, string namespaceURI);
512
513                 public static bool IsName (string str)
514                 {
515                         return str != null && XmlChar.IsName (str);
516                 }
517
518                 public static bool IsNameToken (string str)
519                 {
520                         return str != null && XmlChar.IsNmToken (str);
521                 }
522
523                 public virtual bool IsStartElement ()
524                 {
525                         return (MoveToContent () == XmlNodeType.Element);
526                 }
527
528                 public virtual bool IsStartElement (string name)
529                 {
530                         if (!IsStartElement ())
531                                 return false;
532
533                         return (Name == name);
534                 }
535
536                 public virtual bool IsStartElement (string localname, string ns)
537                 {
538                         if (!IsStartElement ())
539                                 return false;
540
541                         return (LocalName == localname && NamespaceURI == ns);
542                 }
543
544                 public abstract string LookupNamespace (string prefix);
545
546 #if NET_2_0
547                 public virtual void MoveToAttribute (int i)
548                 {
549                         if (i >= AttributeCount)
550                                 throw new ArgumentOutOfRangeException ();
551                         MoveToFirstAttribute ();
552                         for (int a = 0; a < i; a++)
553                                 MoveToNextAttribute ();
554                 }
555 #else
556                 public abstract void MoveToAttribute (int i);
557 #endif
558
559                 public abstract bool MoveToAttribute (string name);
560
561                 public abstract bool MoveToAttribute (string name, string ns);
562
563                 private bool IsContent (XmlNodeType nodeType)
564                 {
565                         /* MS doc says:
566                          * (non-white space text, CDATA, Element, EndElement, EntityReference, or EndEntity)
567                          */
568                         switch (nodeType) {
569                         case XmlNodeType.Text:
570                                 return true;
571                         case XmlNodeType.CDATA:
572                                 return true;
573                         case XmlNodeType.Element:
574                                 return true;
575                         case XmlNodeType.EndElement:
576                                 return true;
577                         case XmlNodeType.EntityReference:
578                                 return true;
579                         case XmlNodeType.EndEntity:
580                                 return true;
581                         }
582
583                         return false;
584                 }
585
586                 public virtual XmlNodeType MoveToContent ()
587                 {
588                         switch (ReadState) {
589                         case ReadState.Initial:
590                         case ReadState.Interactive:
591                                 break;
592                         default:
593                                 return NodeType;
594                         }
595
596                         if (NodeType == XmlNodeType.Attribute)
597                                 MoveToElement ();
598
599                         do {
600                                 if (IsContent (NodeType))
601                                         return NodeType;
602                                 Read ();
603                         } while (!EOF);
604                         return XmlNodeType.None;
605                 }
606
607                 public abstract bool MoveToElement ();
608
609                 public abstract bool MoveToFirstAttribute ();
610
611                 public abstract bool MoveToNextAttribute ();
612
613                 public abstract bool Read ();
614
615                 public abstract bool ReadAttributeValue ();
616
617                 public virtual string ReadElementString ()
618                 {
619                         if (MoveToContent () != XmlNodeType.Element) {
620                                 string error = String.Format ("'{0}' is an invalid node type.",
621                                                               NodeType.ToString ());
622                                 throw XmlError (error);
623                         }
624
625                         string result = String.Empty;
626                         if (!IsEmptyElement) {
627                                 Read ();
628                                 result = ReadString ();
629                                 if (NodeType != XmlNodeType.EndElement) {
630                                         string error = String.Format ("'{0}' is an invalid node type.",
631                                                                       NodeType.ToString ());
632                                         throw XmlError (error);
633                                 }
634                         }
635
636                         Read ();
637                         return result;
638                 }
639
640                 public virtual string ReadElementString (string name)
641                 {
642                         if (MoveToContent () != XmlNodeType.Element) {
643                                 string error = String.Format ("'{0}' is an invalid node type.",
644                                                               NodeType.ToString ());
645                                 throw XmlError (error);
646                         }
647
648                         if (name != Name) {
649                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
650                                                               Name, NamespaceURI);
651                                 throw XmlError (error);
652                         }
653
654                         string result = String.Empty;
655                         if (!IsEmptyElement) {
656                                 Read ();
657                                 result = ReadString ();
658                                 if (NodeType != XmlNodeType.EndElement) {
659                                         string error = String.Format ("'{0}' is an invalid node type.",
660                                                                       NodeType.ToString ());
661                                         throw XmlError (error);
662                                 }
663                         }
664
665                         Read ();
666                         return result;
667                 }
668
669                 public virtual string ReadElementString (string localname, string ns)
670                 {
671                         if (MoveToContent () != XmlNodeType.Element) {
672                                 string error = String.Format ("'{0}' is an invalid node type.",
673                                                               NodeType.ToString ());
674                                 throw XmlError (error);
675                         }
676
677                         if (localname != LocalName || NamespaceURI != ns) {
678                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
679                                                               LocalName, NamespaceURI);
680                                 throw XmlError (error);
681                         }
682
683                         string result = String.Empty;
684                         if (!IsEmptyElement) {
685                                 Read ();
686                                 result = ReadString ();
687                                 if (NodeType != XmlNodeType.EndElement) {
688                                         string error = String.Format ("'{0}' is an invalid node type.",
689                                                                       NodeType.ToString ());
690                                         throw XmlError (error);
691                                 }
692                         }
693
694                         Read ();
695                         return result;
696                 }
697
698                 public virtual void ReadEndElement ()
699                 {
700                         if (MoveToContent () != XmlNodeType.EndElement) {
701                                 string error = String.Format ("'{0}' is an invalid node type.",
702                                                               NodeType.ToString ());
703                                 throw XmlError (error);
704                         }
705
706                         Read ();
707                 }
708
709                 public virtual string ReadInnerXml ()
710                 {
711                         if (ReadState != ReadState.Interactive || NodeType == XmlNodeType.EndElement)
712                                 return String.Empty;
713
714                         if (IsEmptyElement) {
715                                 Read ();
716                                 return String.Empty;
717                         }
718                         StringWriter sw = new StringWriter ();
719                         XmlTextWriter xtw = new XmlTextWriter (sw);
720                         if (NodeType == XmlNodeType.Element) {
721                                 int startDepth = Depth;
722                                 Read ();
723                                 while (startDepth < Depth) {
724                                         if (ReadState != ReadState.Interactive)
725                                                 throw XmlError ("Unexpected end of the XML reader.");
726                                         xtw.WriteNode (this, false);
727                                 }
728                                 // reader is now end element, then proceed once more.
729                                 Read ();
730                         }
731                         else
732                                 xtw.WriteNode (this, false);
733
734                         return sw.ToString ();
735                 }
736
737                 public virtual string ReadOuterXml ()
738                 {
739                         if (ReadState != ReadState.Interactive || NodeType == XmlNodeType.EndElement)
740                                 return String.Empty;
741
742                         switch (NodeType) {
743                         case XmlNodeType.Element:
744                         case XmlNodeType.Attribute:
745                                 StringWriter sw = new StringWriter ();
746                                 XmlTextWriter xtw = new XmlTextWriter (sw);
747                                 xtw.WriteNode (this, false);
748                                 return sw.ToString ();
749                         default:
750                                 Skip ();
751                                 return String.Empty;
752                         }
753                 }
754
755                 public virtual void ReadStartElement ()
756                 {
757                         if (MoveToContent () != XmlNodeType.Element) {
758                                 string error = String.Format ("'{0}' is an invalid node type.",
759                                                               NodeType.ToString ());
760                                 throw XmlError (error);
761                         }
762
763                         Read ();
764                 }
765
766                 public virtual void ReadStartElement (string name)
767                 {
768                         if (MoveToContent () != XmlNodeType.Element) {
769                                 string error = String.Format ("'{0}' is an invalid node type.",
770                                                               NodeType.ToString ());
771                                 throw XmlError (error);
772                         }
773
774                         if (name != Name) {
775                                 string error = String.Format ("The {0} tag from namespace {1} is expected.",
776                                                               Name, NamespaceURI);
777                                 throw XmlError (error);
778                         }
779
780                         Read ();
781                 }
782
783                 public virtual void ReadStartElement (string localname, string ns)
784                 {
785                         if (MoveToContent () != XmlNodeType.Element) {
786                                 string error = String.Format ("'{0}' is an invalid node type.",
787                                                               NodeType.ToString ());
788                                 throw XmlError (error);
789                         }
790
791                         if (localname != LocalName || NamespaceURI != ns) {
792                                 string error = String.Format ("Expecting {0} tag from namespace {1}, got {2} and {3} instead",
793                                                               localname, ns,
794                                                               LocalName, NamespaceURI);
795                                 throw XmlError (error);
796                         }
797
798                         Read ();
799                 }
800
801                 public virtual string ReadString ()
802                 {
803                         if (readStringBuffer == null)
804                                 readStringBuffer = new StringBuilder ();
805                         readStringBuffer.Length = 0;
806
807                         MoveToElement ();
808
809                         switch (NodeType) {
810                         default:
811                                 return String.Empty;
812                         case XmlNodeType.Element:
813                                 if (IsEmptyElement)
814                                         return String.Empty;
815                                 do {
816                                         Read ();
817                                         switch (NodeType) {
818                                         case XmlNodeType.Text:
819                                         case XmlNodeType.CDATA:
820                                         case XmlNodeType.Whitespace:
821                                         case XmlNodeType.SignificantWhitespace:
822                                                 readStringBuffer.Append (Value);
823                                                 continue;
824                                         }
825                                         break;
826                                 } while (true);
827                                 break;
828                         case XmlNodeType.Text:
829                         case XmlNodeType.CDATA:
830                         case XmlNodeType.Whitespace:
831                         case XmlNodeType.SignificantWhitespace:
832                                 do {
833                                         switch (NodeType) {
834                                         case XmlNodeType.Text:
835                                         case XmlNodeType.CDATA:
836                                         case XmlNodeType.Whitespace:
837                                         case XmlNodeType.SignificantWhitespace:
838                                                 readStringBuffer.Append (Value);
839                                                 Read ();
840                                                 continue;
841                                         }
842                                         break;
843                                 } while (true);
844                                 break;
845                         }
846                         string ret = readStringBuffer.ToString ();
847                         readStringBuffer.Length = 0;
848                         return ret;
849                 }
850
851 #if NET_2_0
852                 public virtual Type ValueType {
853                         get { return typeof (string); }
854                 }
855
856                 public virtual bool ReadToDescendant (string name)
857                 {
858                         if (ReadState == ReadState.Initial) {
859                                 MoveToContent ();
860                                 if (IsStartElement (name))
861                                         return true;
862                         }
863                         if (NodeType != XmlNodeType.Element || IsEmptyElement)
864                                 return false;
865                         int depth = Depth;
866                         for (Read (); depth < Depth; Read ())
867                                 if (NodeType == XmlNodeType.Element && name == Name)
868                                         return true;
869                         return false;
870                 }
871
872                 public virtual bool ReadToDescendant (string localName, string namespaceURI)
873                 {
874                         if (ReadState == ReadState.Initial) {
875                                 MoveToContent ();
876                                 if (IsStartElement (localName, namespaceURI))
877                                         return true;
878                         }
879                         if (NodeType != XmlNodeType.Element || IsEmptyElement)
880                                 return false;
881                         int depth = Depth;
882                         for (Read (); depth < Depth; Read ())
883                                 if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
884                                         return true;
885                         return false;
886                 }
887
888                 public virtual bool ReadToFollowing (string name)
889                 {
890                         while (Read ())
891                                 if (NodeType == XmlNodeType.Element && name == Name)
892                                         return true;
893                         return false;
894                 }
895
896                 public virtual bool ReadToFollowing (string localName, string namespaceURI)
897                 {
898                         while (Read ())
899                                 if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
900                                         return true;
901                         return false;
902                 }
903
904                 public virtual bool ReadToNextSibling (string name)
905                 {
906                         if (ReadState != ReadState.Interactive)
907                                 return false;
908                         MoveToElement ();
909                         int depth = Depth;
910                         Skip ();
911                         for (; !EOF && depth <= Depth; Skip ())
912                                 if (NodeType == XmlNodeType.Element && name == Name)
913                                         return true;
914                         return false;
915                 }
916
917                 public virtual bool ReadToNextSibling (string localName, string namespaceURI)
918                 {
919                         if (ReadState != ReadState.Interactive)
920                                 return false;
921                         int depth = Depth;
922                         Skip ();
923                         for (; !EOF && depth <= Depth; Skip ())
924                                 if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
925                                         return true;
926                         return false;
927                 }
928
929                 public virtual XmlReader ReadSubtree ()
930                 {
931                         if (NodeType != XmlNodeType.Element)
932                                 throw new InvalidOperationException (String.Format ("ReadSubtree() can be invoked only when the reader is positioned on an element. Current node is {0}. {1}", NodeType, GetLocation ()));
933                         return new SubtreeXmlReader (this);
934                 }
935
936                 private string ReadContentString ()
937                 {
938                         // The latter condition indicates that this XmlReader is on an attribute value
939                         // (HasAttributes is to indicate it is on attribute value).
940                         if (NodeType == XmlNodeType.Attribute || NodeType != XmlNodeType.Element && HasAttributes)
941                                 return Value;
942                         return ReadContentString (true);
943                 }
944
945                 private string ReadContentString (bool isText)
946                 {
947                         if (isText) {
948                                 switch (NodeType) {
949                                 case XmlNodeType.Text:
950                                 case XmlNodeType.SignificantWhitespace:
951                                 case XmlNodeType.Whitespace:
952                                 case XmlNodeType.CDATA:
953                                         break;
954                                 case XmlNodeType.Element:
955                                         throw new InvalidOperationException (String.Format ("Node type {0} is not supported in this operation.{1}", NodeType, GetLocation ()));
956                                 default:
957                                         return String.Empty;
958                                 }
959                         }
960
961                         string value = String.Empty;
962                         do {
963                                 switch (NodeType) {
964                                 case XmlNodeType.Element:
965                                         if (isText)
966                                                 return value;
967                                         throw XmlError ("Child element is not expected in this operation.");
968                                 case XmlNodeType.EndElement:
969                                         return value;
970                                 case XmlNodeType.Text:
971                                 case XmlNodeType.CDATA:
972                                 case XmlNodeType.SignificantWhitespace:
973                                 case XmlNodeType.Whitespace:
974                                         value += Value;
975                                         break;
976                                 }
977                         } while (Read ());
978                         throw XmlError ("Unexpected end of document.");
979                 }
980
981                 string GetLocation ()
982                 {
983                         IXmlLineInfo li = this as IXmlLineInfo;
984                         return li != null && li.HasLineInfo () ?
985                                 String.Format (" {0} (line {1}, column {2})", BaseURI, li.LineNumber, li.LinePosition) : String.Empty;
986                 }
987
988                 [MonoTODO]
989                 public virtual object ReadElementContentAsObject ()
990                 {
991                         return ReadElementContentAs (ValueType, null);
992                 }
993
994                 [MonoTODO]
995                 public virtual object ReadElementContentAsObject (string localName, string namespaceURI)
996                 {
997                         return ReadElementContentAs (ValueType, null, localName, namespaceURI);
998                 }
999
1000                 [MonoTODO]
1001                 public virtual object ReadContentAsObject ()
1002                 {
1003                         return ReadContentAs (ValueType, null);
1004                 }
1005
1006 #if NET_4_5
1007                 public virtual DateTimeOffset ReadContentAsDateTimeOffset ()
1008                 {
1009                         return XmlConvert.ToDateTimeOffset (ReadContentString ());
1010                 }
1011 #endif
1012
1013                 public virtual object ReadElementContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver)
1014                 {
1015                         bool isEmpty = IsEmptyElement;
1016                         ReadStartElement ();
1017                         object obj = ValueAs (isEmpty ? String.Empty : ReadContentString (false), returnType, namespaceResolver, false);
1018                         if (!isEmpty)
1019                                 ReadEndElement ();
1020                         return obj;
1021                 }
1022
1023                 public virtual object ReadElementContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver, string localName, string namespaceURI)
1024                 {
1025                         bool isEmpty = IsEmptyElement;
1026                         ReadStartElement (localName, namespaceURI);
1027                         if (isEmpty)
1028                                 return ValueAs (String.Empty, returnType, namespaceResolver, false);
1029                         object obj = ReadContentAs (returnType, namespaceResolver);
1030                         ReadEndElement ();
1031                         return obj;
1032                 }
1033
1034                 public virtual object ReadContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver)
1035                 {
1036                         return ValueAs (ReadContentString (), returnType, namespaceResolver, false);
1037                 }
1038
1039                 private object ValueAs (string text, Type type, IXmlNamespaceResolver resolver, bool isArrayItem)
1040                 {
1041                         try {
1042                                 if (type == typeof (object))
1043                                         return text;
1044                                 if (type.IsArray && !isArrayItem) {
1045                                         var elemType = type.GetElementType ();
1046                                         var sarr = text.Split ((string []) null, StringSplitOptions.RemoveEmptyEntries);
1047                                         var ret = Array.CreateInstance (elemType, sarr.Length);
1048                                         for (int i = 0; i < ret.Length; i++)
1049                                                 ret.SetValue (ValueAs (sarr [i], elemType, resolver, true), i);
1050                                         return ret;
1051                                 }
1052
1053                                 if (type == typeof (XmlQualifiedName)) {
1054                                         if (resolver != null)
1055                                                 return XmlQualifiedName.Parse (text, resolver, true);
1056                                         else
1057                                                 return XmlQualifiedName.Parse (text, this, true);
1058                                 }
1059                                 if (type == typeof (Uri))
1060                                         return XmlConvert.ToUri (text);
1061                                 if (type == typeof (TimeSpan))
1062                                         return XmlConvert.ToTimeSpan (text);
1063                                 if (type == typeof (DateTimeOffset))
1064                                         return XmlConvert.ToDateTimeOffset (text);
1065
1066                                 switch (Type.GetTypeCode (type)) {
1067                                 case TypeCode.Boolean:
1068                                         return XQueryConvert.StringToBoolean (text);
1069                                 case TypeCode.DateTime:
1070                                         return XQueryConvert.StringToDateTime (text);
1071                                 case TypeCode.Decimal:
1072                                         return XQueryConvert.StringToDecimal (text);
1073                                 case TypeCode.Double:
1074                                         return XQueryConvert.StringToDouble (text);
1075                                 case TypeCode.Int32:
1076                                         return XQueryConvert.StringToInt (text);
1077                                 case TypeCode.Int64:
1078                                         return XQueryConvert.StringToInteger (text);
1079                                 case TypeCode.Single:
1080                                         return XQueryConvert.StringToFloat (text);
1081                                 case TypeCode.String:
1082                                         return text;
1083                                 }
1084                         } catch (Exception ex) {
1085                                 throw XmlError (String.Format ("Current text value '{0}' is not acceptable for specified type '{1}'. {2}", text, type, ex != null ? ex.Message : String.Empty), ex);
1086                         }
1087                         throw new ArgumentException (String.Format ("Specified type '{0}' is not supported.", type));
1088                 }
1089
1090                 public virtual bool ReadElementContentAsBoolean ()
1091                 {
1092                         try {
1093                                 return XQueryConvert.StringToBoolean (ReadElementContentAsString ());
1094                         } catch (FormatException ex) {
1095                                 throw XmlError ("Typed value is invalid.", ex);
1096                         }
1097                 }
1098
1099                 public virtual DateTime ReadElementContentAsDateTime ()
1100                 {
1101                         try {
1102                                 return XQueryConvert.StringToDateTime (ReadElementContentAsString ());
1103                         } catch (FormatException ex) {
1104                                 throw XmlError ("Typed value is invalid.", ex);
1105                         }
1106                 }
1107
1108                 public virtual decimal ReadElementContentAsDecimal ()
1109                 {
1110                         try {
1111                                 return XQueryConvert.StringToDecimal (ReadElementContentAsString ());
1112                         } catch (FormatException ex) {
1113                                 throw XmlError ("Typed value is invalid.", ex);
1114                         }
1115                 }
1116
1117                 public virtual double ReadElementContentAsDouble ()
1118                 {
1119                         try {
1120                                 return XQueryConvert.StringToDouble (ReadElementContentAsString ());
1121                         } catch (FormatException ex) {
1122                                 throw XmlError ("Typed value is invalid.", ex);
1123                         }
1124                 }
1125
1126                 public virtual float ReadElementContentAsFloat ()
1127                 {
1128                         try {
1129                                 return XQueryConvert.StringToFloat (ReadElementContentAsString ());
1130                         } catch (FormatException ex) {
1131                                 throw XmlError ("Typed value is invalid.", ex);
1132                         }
1133                 }
1134
1135                 public virtual int ReadElementContentAsInt ()
1136                 {
1137                         try {
1138                                 return XQueryConvert.StringToInt (ReadElementContentAsString ());
1139                         } catch (FormatException ex) {
1140                                 throw XmlError ("Typed value is invalid.", ex);
1141                         }
1142                 }
1143
1144                 public virtual long ReadElementContentAsLong ()
1145                 {
1146                         try {
1147                                 return XQueryConvert.StringToInteger (ReadElementContentAsString ());
1148                         } catch (FormatException ex) {
1149                                 throw XmlError ("Typed value is invalid.", ex);
1150                         }
1151                 }
1152
1153                 public virtual string ReadElementContentAsString ()
1154                 {
1155                         bool isEmpty = IsEmptyElement;
1156                         // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
1157                         if (NodeType != XmlNodeType.Element)
1158                                 throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
1159                         ReadStartElement ();
1160                         if (isEmpty)
1161                                 return String.Empty;
1162                         string s = ReadContentString (false);
1163                         ReadEndElement ();
1164                         return s;
1165                 }
1166
1167                 public virtual bool ReadElementContentAsBoolean (string localName, string namespaceURI)
1168                 {
1169                         try {
1170                                 return XQueryConvert.StringToBoolean (ReadElementContentAsString (localName, namespaceURI));
1171                         } catch (FormatException ex) {
1172                                 throw XmlError ("Typed value is invalid.", ex);
1173                         }
1174                 }
1175
1176                 public virtual DateTime ReadElementContentAsDateTime (string localName, string namespaceURI)
1177                 {
1178                         try {
1179                                 return XQueryConvert.StringToDateTime (ReadElementContentAsString (localName, namespaceURI));
1180                         } catch (FormatException ex) {
1181                                 throw XmlError ("Typed value is invalid.", ex);
1182                         }
1183                 }
1184
1185                 public virtual decimal ReadElementContentAsDecimal (string localName, string namespaceURI)
1186                 {
1187                         try {
1188                                 return XQueryConvert.StringToDecimal (ReadElementContentAsString (localName, namespaceURI));
1189                         } catch (FormatException ex) {
1190                                 throw XmlError ("Typed value is invalid.", ex);
1191                         }
1192                 }
1193
1194                 public virtual double ReadElementContentAsDouble (string localName, string namespaceURI)
1195                 {
1196                         try {
1197                                 return XQueryConvert.StringToDouble (ReadElementContentAsString (localName, namespaceURI));
1198                         } catch (FormatException ex) {
1199                                 throw XmlError ("Typed value is invalid.", ex);
1200                         }
1201                 }
1202
1203                 public virtual float ReadElementContentAsFloat (string localName, string namespaceURI)
1204                 {
1205                         try {
1206                                 return XQueryConvert.StringToFloat (ReadElementContentAsString (localName, namespaceURI));
1207                         } catch (FormatException ex) {
1208                                 throw XmlError ("Typed value is invalid.", ex);
1209                         }
1210                 }
1211
1212                 public virtual int ReadElementContentAsInt (string localName, string namespaceURI)
1213                 {
1214                         try {
1215                                 return XQueryConvert.StringToInt (ReadElementContentAsString (localName, namespaceURI));
1216                         } catch (FormatException ex) {
1217                                 throw XmlError ("Typed value is invalid.", ex);
1218                         }
1219                 }
1220
1221                 public virtual long ReadElementContentAsLong (string localName, string namespaceURI)
1222                 {
1223                         try {
1224                                 return XQueryConvert.StringToInteger (ReadElementContentAsString (localName, namespaceURI));
1225                         } catch (FormatException ex) {
1226                                 throw XmlError ("Typed value is invalid.", ex);
1227                         }
1228                 }
1229
1230                 public virtual string ReadElementContentAsString (string localName, string namespaceURI)
1231                 {
1232                         bool isEmpty = IsEmptyElement;
1233                         // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
1234                         if (NodeType != XmlNodeType.Element)
1235                                 throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
1236                         ReadStartElement (localName, namespaceURI);
1237                         if (isEmpty)
1238                                 return String.Empty;
1239                         string s = ReadContentString (false);
1240                         ReadEndElement ();
1241                         return s;
1242                 }
1243
1244                 public virtual bool ReadContentAsBoolean ()
1245                 {
1246                         try {
1247                                 return XQueryConvert.StringToBoolean (ReadContentString ());
1248                         } catch (FormatException ex) {
1249                                 throw XmlError ("Typed value is invalid.", ex);
1250                         }
1251                 }
1252
1253                 public virtual DateTime ReadContentAsDateTime ()
1254                 {
1255                         try {
1256                                 return XQueryConvert.StringToDateTime (ReadContentString ());
1257                         } catch (FormatException ex) {
1258                                 throw XmlError ("Typed value is invalid.", ex);
1259                         }
1260                 }
1261
1262                 public virtual decimal ReadContentAsDecimal ()
1263                 {
1264                         try {
1265                                 return XQueryConvert.StringToDecimal (ReadContentString ());
1266                         } catch (FormatException ex) {
1267                                 throw XmlError ("Typed value is invalid.", ex);
1268                         }
1269                 }
1270
1271                 public virtual double ReadContentAsDouble ()
1272                 {
1273                         try {
1274                                 return XQueryConvert.StringToDouble (ReadContentString ());
1275                         } catch (FormatException ex) {
1276                                 throw XmlError ("Typed value is invalid.", ex);
1277                         }
1278                 }
1279
1280                 public virtual float ReadContentAsFloat ()
1281                 {
1282                         try {
1283                                 return XQueryConvert.StringToFloat (ReadContentString ());
1284                         } catch (FormatException ex) {
1285                                 throw XmlError ("Typed value is invalid.", ex);
1286                         }
1287                 }
1288
1289                 public virtual int ReadContentAsInt ()
1290                 {
1291                         try {
1292                                 return XQueryConvert.StringToInt (ReadContentString ());
1293                         } catch (FormatException ex) {
1294                                 throw XmlError ("Typed value is invalid.", ex);
1295                         }
1296                 }
1297
1298                 public virtual long ReadContentAsLong ()
1299                 {
1300                         try {
1301                                 return XQueryConvert.StringToInteger (ReadContentString ());
1302                         } catch (FormatException ex) {
1303                                 throw XmlError ("Typed value is invalid.", ex);
1304                         }
1305                 }
1306
1307                 public virtual string ReadContentAsString ()
1308                 {
1309                         return ReadContentString ();
1310                 }
1311
1312                 public virtual int ReadContentAsBase64 (
1313                         byte [] buffer, int index, int count)
1314                 {
1315                         CheckSupport ();
1316                         return binary.ReadContentAsBase64 (
1317                                 buffer, index, count);
1318                 }
1319
1320                 public virtual int ReadContentAsBinHex (
1321                         byte [] buffer, int index, int count)
1322                 {
1323                         CheckSupport ();
1324                         return binary.ReadContentAsBinHex (
1325                                 buffer, index, count);
1326                 }
1327
1328                 public virtual int ReadElementContentAsBase64 (
1329                         byte [] buffer, int index, int count)
1330                 {
1331                         CheckSupport ();
1332                         return binary.ReadElementContentAsBase64 (
1333                                 buffer, index, count);
1334                 }
1335
1336                 public virtual int ReadElementContentAsBinHex (
1337                         byte [] buffer, int index, int count)
1338                 {
1339                         CheckSupport ();
1340                         return binary.ReadElementContentAsBinHex (
1341                                 buffer, index, count);
1342                 }
1343
1344                 private void CheckSupport ()
1345                 {
1346                         // Default implementation expects both.
1347                         if (!CanReadBinaryContent || !CanReadValueChunk)
1348                                 throw new NotSupportedException ();
1349                         if (binary == null)
1350                                 binary = new XmlReaderBinarySupport (this);
1351                 }
1352                 
1353 #endif
1354
1355                 public virtual int ReadValueChunk (char [] buffer, int index, int count)
1356                 {
1357                         if (!CanReadValueChunk)
1358                                 throw new NotSupportedException ();
1359                         if (binary == null)
1360                                 binary = new XmlReaderBinarySupport (this);
1361                         return binary.ReadValueChunk (buffer, index, count);
1362                 }
1363
1364                 public abstract void ResolveEntity ();
1365
1366                 public virtual void Skip ()
1367                 {
1368                         if (ReadState != ReadState.Interactive)
1369                                 return;
1370
1371                         MoveToElement ();
1372                         if (NodeType != XmlNodeType.Element || IsEmptyElement) {
1373                                 Read ();
1374                                 return;
1375                         }
1376                                 
1377                         int depth = Depth;
1378                         while (Read () && depth < Depth)
1379                                 ;
1380                         if (NodeType == XmlNodeType.EndElement)
1381                                 Read ();
1382                 }
1383
1384                 private XmlException XmlError (string message)
1385                 {
1386                         return new XmlException (this as IXmlLineInfo, BaseURI, message);
1387                 }
1388 #if NET_2_0
1389                 private XmlException XmlError (string message, Exception innerException)
1390                 {
1391                         return new XmlException (this as IXmlLineInfo, BaseURI, message);
1392                 }
1393 #endif
1394                 #endregion
1395
1396 #if NET_4_5
1397                 #region .NET 4.5 Async Methods
1398
1399                 bool asyncRunning;
1400
1401                 void StartAsync ()
1402                 {
1403                         if (!settings.Async)
1404                                 throw new InvalidOperationException ("Set XmlReaderSettings.Async to true if you want to use Async Methods.");
1405                         lock (this) {
1406                                 if (asyncRunning)
1407                                         throw new InvalidOperationException ("An asynchronous operation is already in progress.");
1408                                 asyncRunning = true;
1409                         }
1410                 }
1411
1412                 public virtual Task<bool> ReadAsync ()
1413                 {
1414                         StartAsync ();
1415                         return Task.Run (() => {
1416                                 try {
1417                                         return Read ();
1418                                 } finally {
1419                                         asyncRunning = false;
1420                                 }
1421                         });
1422                 }
1423
1424                 public virtual Task<string> GetValueAsync ()
1425                 {
1426                         StartAsync ();
1427                         return Task.Run (() => {
1428                                 try {
1429                                         return Value;
1430                                 } finally {
1431                                         asyncRunning = false;
1432                                 }
1433                         });
1434                 }
1435
1436                 public virtual Task<string> ReadInnerXmlAsync ()
1437                 {
1438                         StartAsync ();
1439                         return Task.Run (() => {
1440                                 try {
1441                                         return ReadInnerXml ();
1442                                 } finally {
1443                                         asyncRunning = false;
1444                                 }
1445                         });
1446                 }
1447
1448                 public virtual Task<string> ReadOuterXmlAsync ()
1449                 {
1450                         StartAsync ();
1451                         return Task.Run (() => {
1452                                 try {
1453                                         return ReadOuterXml ();
1454                                 } finally {
1455                                         asyncRunning = false;
1456                                 }
1457                         });
1458                 }
1459
1460                 public virtual Task<string> ReadContentAsStringAsync ()
1461                 {
1462                         StartAsync ();
1463                         return Task.Run (() => {
1464                                 try {
1465                                         return ReadContentAsString ();
1466                                 } finally {
1467                                         asyncRunning = false;
1468                                 }
1469                         });
1470                 }
1471
1472                 public virtual Task<int> ReadContentAsBase64Async (byte[] buffer, int index, int count)
1473                 {
1474                         StartAsync ();
1475                         return Task.Run (() => {
1476                                 try {
1477                                         return ReadContentAsBase64 (buffer, index, count);
1478                                 } finally {
1479                                         asyncRunning = false;
1480                                 }
1481                         });
1482                 }
1483
1484                 public virtual Task<int> ReadContentAsBinHexAsync (byte[] buffer, int index, int count)
1485                 {
1486                         StartAsync ();
1487                         return Task.Run (() => {
1488                                 try {
1489                                         return ReadContentAsBinHex (buffer, index, count);
1490                                 } finally {
1491                                         asyncRunning = false;
1492                                 }
1493                         });
1494                 }
1495
1496                 public virtual Task<int> ReadElementContentAsBase64Async (byte[] buffer, int index, int count)
1497                 {
1498                         StartAsync ();
1499                         return Task.Run (() => {
1500                                 try {
1501                                         return ReadElementContentAsBase64 (buffer, index, count);
1502                                 } finally {
1503                                         asyncRunning = false;
1504                                 }
1505                         });
1506                 }
1507
1508                 public virtual Task<int> ReadElementContentAsBinHexAsync (byte[] buffer, int index, int count)
1509                 {
1510                         StartAsync ();
1511                         return Task.Run (() => {
1512                                 try {
1513                                         return ReadElementContentAsBinHex (buffer, index, count);
1514                                 } finally {
1515                                         asyncRunning = false;
1516                                 }
1517                         });
1518                 }
1519
1520                 public virtual Task<int> ReadValueChunkAsync (char[] buffer, int index, int count)
1521                 {
1522                         StartAsync ();
1523                         return Task.Run (() => {
1524                                 try {
1525                                         return ReadValueChunk (buffer, index, count);
1526                                 } finally {
1527                                         asyncRunning = false;
1528                                 }
1529                         });
1530                 }
1531
1532                 public virtual Task<object> ReadContentAsAsync (Type returnType, IXmlNamespaceResolver namespaceResolver)
1533                 {
1534                         StartAsync ();
1535                         return Task.Run (() => {
1536                                 try {
1537                                         return ReadContentAs (returnType, namespaceResolver);
1538                                 } finally {
1539                                         asyncRunning = false;
1540                                 }
1541                         });
1542                 }
1543
1544                 public virtual Task<object> ReadContentAsObjectAsync ()
1545                 {
1546                         StartAsync ();
1547                         return Task.Run (() => {
1548                                 try {
1549                                         return ReadContentAsObject ();
1550                                 } finally {
1551                                         asyncRunning = false;
1552                                 }
1553                         });
1554                 }
1555
1556                 public virtual Task<object> ReadElementContentAsAsync (Type returnType, IXmlNamespaceResolver namespaceResolver)
1557                 {
1558                         StartAsync ();
1559                         return Task.Run (() => {
1560                                 try {
1561                                         return ReadElementContentAs (returnType, namespaceResolver);
1562                                 } finally {
1563                                         asyncRunning = false;
1564                                 }
1565                         });
1566                 }
1567
1568                 public virtual Task<object> ReadElementContentAsObjectAsync ()
1569                 {
1570                         StartAsync ();
1571                         return Task.Run (() => {
1572                                 try {
1573                                         return ReadElementContentAsObject ();
1574                                 } finally {
1575                                         asyncRunning = false;
1576                                 }
1577                         });
1578                 }
1579
1580                 public virtual Task<string> ReadElementContentAsStringAsync ()
1581                 {
1582                         StartAsync ();
1583                         return Task.Run (() => {
1584                                 try {
1585                                         return ReadElementContentAsString ();
1586                                 } finally {
1587                                         asyncRunning = false;
1588                                 }
1589                         });
1590                 }
1591
1592                 public virtual Task<XmlNodeType> MoveToContentAsync ()
1593                 {
1594                         StartAsync ();
1595                         return Task.Run (() => {
1596                                 try {
1597                                         return MoveToContent ();
1598                                 } finally {
1599                                         asyncRunning = false;
1600                                 }
1601                         });
1602                 }
1603
1604                 public virtual Task SkipAsync ()
1605                 {
1606                         StartAsync ();
1607                         return Task.Run (() => {
1608                                 try {
1609                                         Skip ();
1610                                 } finally {
1611                                         asyncRunning = false;
1612                                 }
1613                         });
1614                 }
1615
1616                 #endregion
1617 #endif
1618         }
1619 }