Added missing members to XmlParserContext and started using it from XmlTextReader.
[mono.git] / mcs / class / System.XML / System.Xml / XmlTextReader.cs
index cc736ed587036736571722c1214e2015de179640..f49090793fda12c7f819c229a3e532921910c429 100644 (file)
-// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-\r
-//\r
-// System.Xml.XmlTextReader.cs\r
-//\r
-// Author:\r
-//   Jason Diamond (jason@injektilo.org)\r
-//\r
-// (C) 2001 Jason Diamond  http://injektilo.org/\r
-//\r
-\r
-// FIXME:\r
-//   This can only parse basic XML: elements, attributes, processing\r
-//   instructions, and comments are OK but there's no support for\r
-//   entity/character references or namespaces yet.\r
-//\r
-//   It barfs on DOCTYPE declarations and CDATA sections.\r
-//\r
-//   There's also no checking being done for either well-formedness\r
-//   or validity.\r
-//\r
-//   ParserContext and NameTables aren't being used yet.\r
-//\r
-//   The XmlTextReader-specific properties and methods have yet to\r
-//   be added or implemented.\r
-//\r
-//   Some thought needs to be given to performance. There's too many\r
-//   strings and string builders being allocated.\r
-//\r
-//   None of the MoveTo methods have been implemented yet.\r
-//\r
-//   LineNumber and LinePosition aren't being tracked.\r
-//\r
-//   xml:space, xml:lang, and xml:base aren't being tracked.\r
-//\r
-//   Depth isn't being tracked.\r
-\r
-using System;\r
-using System.Collections;\r
-using System.IO;\r
-using System.Net;\r
-using System.Text;\r
-\r
-namespace System.Xml\r
-{\r
-       public class XmlTextReader : XmlReader\r
-       {\r
-               // constructors\r
-\r
-               protected XmlTextReader()\r
-               {\r
-                       Init();\r
-               }\r
-\r
-               public XmlTextReader(Stream input)\r
-               {\r
-                       Init();\r
-                       reader = new StreamReader(\r
-                               input,\r
-                               Encoding.UTF8,\r
-                               true);\r
-               }\r
-\r
-               public XmlTextReader(string url)\r
-               {\r
-                       Init();\r
-                       WebClient client = new WebClient();\r
-                       reader = new StreamReader(\r
-                               client.OpenRead(url),\r
-                               Encoding.UTF8,\r
-                               true);\r
-               }\r
-\r
-               public XmlTextReader(TextReader input)\r
-               {\r
-                       Init();\r
-                       reader = input;\r
-               }\r
-\r
-               public XmlTextReader(Stream input, XmlNameTable nameTable)\r
-               {\r
-                       // TODO: implement me.\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               public XmlTextReader(string baseURI, Stream input)\r
-               {\r
-                       // TODO: implement me.\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               public XmlTextReader(string baseURI, TextReader input)\r
-               {\r
-                       // TODO: implement me.\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               public XmlTextReader(string url, XmlNameTable nameTable)\r
-               {\r
-                       // TODO: implement me.\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               public XmlTextReader(\r
-                       TextReader input,\r
-                       XmlNameTable nameTable)\r
-               {\r
-                       // TODO: implement me.\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               public XmlTextReader(\r
-                       Stream inputFragment,\r
-                       XmlNodeType fragmentType,\r
-                       XmlParserContext context)\r
-               {\r
-                       // TODO: implement me.\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               public XmlTextReader(\r
-                       string baseURI,\r
-                       Stream input,\r
-                       XmlNameTable nameTable)\r
-               {\r
-                       // TODO: implement me.\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               public XmlTextReader(\r
-                       string baseURI,\r
-                       TextReader input,\r
-                       XmlNameTable nameTable)\r
-               {\r
-                       // TODO: implement me.\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               public XmlTextReader(\r
-                       string fragment,\r
-                       XmlNodeType fragmentType,\r
-                       XmlParserContext context)\r
-               {\r
-                       // TODO: implement me.\r
-                       throw new NotImplementedException();\r
-               }\r
-\r
-               // properties\r
-\r
-               public override int AttributeCount\r
-               {\r
-                       get\r
-                       {\r
-                               return attributes.Count;\r
-                       }\r
-               }\r
-\r
-               public override string BaseURI\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO: implement me.\r
-                               return null;\r
-                       }\r
-               }\r
-\r
-               public override bool CanResolveEntity\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO: implement me.\r
-                               return false;\r
-                       }\r
-               }\r
-\r
-               public override int Depth\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO: implement me.\r
-                               return 0;\r
-                       }\r
-               }\r
-\r
-               public override bool EOF\r
-               {\r
-                       get\r
-                       {\r
-                               return\r
-                                       readState == ReadState.EndOfFile ||\r
-                                       readState == ReadState.Closed;\r
-                       }\r
-               }\r
-\r
-               public override bool HasValue\r
-               {\r
-                       get\r
-                       {\r
-                               return value != String.Empty;\r
-                       }\r
-               }\r
-\r
-               public override bool IsDefault\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO: implement me.\r
-                               return false;\r
-                       }\r
-               }\r
-\r
-               public override bool IsEmptyElement\r
-               {\r
-                       get\r
-                       {\r
-                               return isEmptyElement;\r
-                       }\r
-               }\r
-\r
-               public override string this[int i]\r
-               {\r
-                       get\r
-                       {\r
-                               return GetAttribute(i);\r
-                       }\r
-               }\r
-\r
-               public override string this[string name]\r
-               {\r
-                       get\r
-                       {\r
-                               return GetAttribute(name);\r
-                       }\r
-               }\r
-\r
-               public override string this[\r
-                       string localName,\r
-                       string namespaceName]\r
-               {\r
-                       get\r
-                       {\r
-                               return GetAttribute(localName, namespaceName);\r
-                       }\r
-               }\r
-\r
-               public override string LocalName\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO: implement me.\r
-                               return null;\r
-                       }\r
-               }\r
-\r
-               public override string Name\r
-               {\r
-                       get\r
-                       {\r
-                               return name;\r
-                       }\r
-               }\r
-\r
-               public override string NamespaceURI\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO: implement me.\r
-                               return null;\r
-                       }\r
-               }\r
-\r
-               public override XmlNameTable NameTable\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO: implement me.\r
-                               return null;\r
-                       }\r
-               }\r
-\r
-               public override XmlNodeType NodeType\r
-               {\r
-                       get\r
-                       {\r
-                               return nodeType;\r
-                       }\r
-               }\r
-\r
-               public override string Prefix\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO: implement me.\r
-                               return null;\r
-                       }\r
-               }\r
-\r
-               public override char QuoteChar\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO: implement me.\r
-                               return '"';\r
-                       }\r
-               }\r
-\r
-               public override ReadState ReadState\r
-               {\r
-                       get\r
-                       {\r
-                               return readState;\r
-                       }\r
-               }\r
-\r
-               public override string Value\r
-               {\r
-                       get\r
-                       {\r
-                               return value;\r
-                       }\r
-               }\r
-\r
-               public override string XmlLang\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO: implement me.\r
-                               return null;\r
-                       }\r
-               }\r
-\r
-               public override XmlSpace XmlSpace\r
-               {\r
-                       get\r
-                       {\r
-                               // TODO: implement me.\r
-                               return XmlSpace.Default;\r
-                       }\r
-               }\r
-\r
-               // methods\r
-\r
-               public override void Close()\r
-               {\r
-                       readState = ReadState.Closed;\r
-               }\r
-\r
-               public override string GetAttribute(int i)\r
-               {\r
-                       // TODO: implement me.\r
-                       return null;\r
-               }\r
-\r
-               public override string GetAttribute(string name)\r
-               {\r
-                       return (string)attributes[name];\r
-               }\r
-\r
-               public override string GetAttribute(\r
-                       string localName,\r
-                       string namespaceName)\r
-               {\r
-                       // TODO: implement me.\r
-                       return null;\r
-               }\r
-\r
-               public override string LookupNamespace(string prefix)\r
-               {\r
-                       // TODO: implement me.\r
-                       return null;\r
-               }\r
-\r
-               public override void MoveToAttribute(int i)\r
-               {\r
-                       // TODO: implement me.\r
-               }\r
-\r
-               public override bool MoveToAttribute(string name)\r
-               {\r
-                       // TODO: implement me.\r
-                       return false;\r
-               }\r
-\r
-               public override bool MoveToAttribute(\r
-                       string localName,\r
-                       string namespaceName)\r
-               {\r
-                       // TODO: implement me.\r
-                       return false;\r
-               }\r
-\r
-               public override bool MoveToElement()\r
-               {\r
-                       // TODO: implement me.\r
-                       return false;\r
-               }\r
-\r
-               public override bool MoveToFirstAttribute()\r
-               {\r
-                       // TODO: implement me.\r
-                       return false;\r
-               }\r
-\r
-               public override bool MoveToNextAttribute()\r
-               {\r
-                       // TODO: implement me.\r
-                       return false;\r
-               }\r
-\r
-               public override bool Read()\r
-               {\r
-                       bool more = false;\r
-\r
-                       readState = ReadState.Interactive;\r
-\r
-                       more = ReadContent();\r
-\r
-                       return more;\r
-               }\r
-\r
-               public override bool ReadAttributeValue()\r
-               {\r
-                       // TODO: implement me.\r
-                       return false;\r
-               }\r
-\r
-               public override string ReadInnerXml()\r
-               {\r
-                       // TODO: implement me.\r
-                       return null;\r
-               }\r
-\r
-               public override string ReadOuterXml()\r
-               {\r
-                       // TODO: implement me.\r
-                       return null;\r
-               }\r
-\r
-               public override string ReadString()\r
-               {\r
-                       // TODO: implement me.\r
-                       return null;\r
-               }\r
-\r
-               public override void ResolveEntity()\r
-               {\r
-                       // TODO: implement me.\r
-               }\r
-\r
-               // privates\r
-\r
-               private TextReader reader;\r
-               private ReadState readState;\r
-\r
-               private XmlNodeType nodeType;\r
-               private string name;\r
-               private bool isEmptyElement;\r
-               private string value;\r
-               private Hashtable attributes;\r
-\r
-               private void Init()\r
-               {\r
-                       readState = ReadState.Initial;\r
-\r
-                       nodeType = XmlNodeType.None;\r
-                       name = String.Empty;\r
-                       isEmptyElement = false;\r
-                       value = String.Empty;\r
-                       attributes = new Hashtable();\r
-               }\r
-\r
-               // Use this method rather than setting the properties\r
-               // directly so that all the necessary properties can\r
-               // be changed in harmony with each other. Maybe the\r
-               // fields should be in a seperate class to help enforce\r
-               // this.\r
-               private void SetProperties(\r
-                       XmlNodeType nodeType,\r
-                       string name,\r
-                       bool isEmptyElement,\r
-                       string value,\r
-                       bool clearAttributes)\r
-               {\r
-                       this.nodeType = nodeType;\r
-                       this.name = name;\r
-                       this.isEmptyElement = isEmptyElement;\r
-                       this.value = value;\r
-\r
-                       if (clearAttributes)\r
-                       {\r
-                               ClearAttributes();\r
-                       }\r
-               }\r
-\r
-               private void AddAttribute(string name, string value)\r
-               {\r
-                       attributes.Add(name, value);\r
-               }\r
-\r
-               private void ClearAttributes()\r
-               {\r
-                       attributes.Clear();\r
-               }\r
-\r
-               // This should really keep track of some state so\r
-               // that it's not possible to have more than one document\r
-               // element or text outside of the document element.\r
-               private bool ReadContent()\r
-               {\r
-                       bool more = false;\r
-\r
-                       switch (reader.Peek())\r
-                       {\r
-                       case '<':\r
-                               reader.Read();\r
-                               ReadTag();\r
-                               more = true;\r
-                               break;\r
-                       case -1:\r
-                               readState = ReadState.EndOfFile;\r
-                               SetProperties(\r
-                                       XmlNodeType.None, // nodeType\r
-                                       String.Empty, // name\r
-                                       false, // isEmptyElement\r
-                                       String.Empty, // value\r
-                                       true // clearAttributes\r
-                               );\r
-                               more = false;\r
-                               break;\r
-                       default:\r
-                               ReadText();\r
-                               more = true;\r
-                               break;\r
-                       }\r
-\r
-                       return more;\r
-               }\r
-\r
-               // The leading '<' has already been consumed.\r
-               private void ReadTag()\r
-               {\r
-                       switch (reader.Peek())\r
-                       {\r
-                       case '/':\r
-                               reader.Read();\r
-                               ReadEndTag();\r
-                               break;\r
-                       case '?':\r
-                               reader.Read();\r
-                               ReadProcessingInstruction();\r
-                               break;\r
-                       case '!':\r
-                               reader.Read();\r
-                               ReadComment();\r
-                               break;\r
-                       default:\r
-                               ReadStartTag();\r
-                               break;\r
-                       }\r
-               }\r
-\r
-               // The leading '<' has already been consumed.\r
-               private void ReadStartTag()\r
-               {\r
-                       string name = ReadName();\r
-                       SkipWhitespace();\r
-\r
-                       bool isEmptyElement = false;\r
-\r
-                       ClearAttributes();\r
-\r
-                       if (XmlChar.IsFirstNameChar(reader.Peek()))\r
-                       {\r
-                               ReadAttributes();\r
-                       }\r
-\r
-                       if (reader.Peek() == '/')\r
-                       {\r
-                               reader.Read();\r
-                               isEmptyElement = true;\r
-                       }\r
-\r
-                       Expect('>');\r
-\r
-                       SetProperties(\r
-                               XmlNodeType.Element, // nodeType\r
-                               name, // name\r
-                               isEmptyElement, // isEmptyElement\r
-                               String.Empty, // value\r
-                               false // clearAttributes\r
-                       );\r
-               }\r
-\r
-               // The reader is positioned on the first character\r
-               // of the element's name.\r
-               private void ReadEndTag()\r
-               {\r
-                       string name = ReadName();\r
-                       SkipWhitespace();\r
-                       Expect('>');\r
-\r
-                       SetProperties(\r
-                               XmlNodeType.EndElement, // nodeType\r
-                               name, // name\r
-                               false, // isEmptyElement\r
-                               String.Empty, // value\r
-                               true // clearAttributes\r
-                       );\r
-               }\r
-\r
-               // The reader is positioned on the first character\r
-               // of the text.\r
-               private void ReadText()\r
-               {\r
-                       StringBuilder text = new StringBuilder();\r
-                       text.Append((char)reader.Read());\r
-\r
-                       while (reader.Peek() != '<' && reader.Peek() != -1)\r
-                       {\r
-                               text.Append((char)reader.Read());\r
-                       }\r
-\r
-                       SetProperties(\r
-                               XmlNodeType.Text, // nodeType\r
-                               String.Empty, // name\r
-                               false, // isEmptyElement\r
-                               text.ToString(), // value\r
-                               true // clearAttributes\r
-                       );\r
-               }\r
-\r
-               // The reader is positioned on the first character of\r
-               // the attribute name.\r
-               private void ReadAttributes()\r
-               {\r
-                       do\r
-                       {\r
-                               string name = ReadName();\r
-                               SkipWhitespace();\r
-                               Expect('=');\r
-                               SkipWhitespace();\r
-                               string value = ReadAttribute();\r
-                               SkipWhitespace();\r
-\r
-                               AddAttribute(name, value);\r
-                       }\r
-                       while (reader.Peek() != '/' && reader.Peek() != '>' && reader.Peek() != -1);\r
-               }\r
-\r
-               // The reader is positioned on the quote character.\r
-               private string ReadAttribute()\r
-               {\r
-                       int quoteChar = reader.Read();\r
-\r
-                       if (quoteChar != '\'' && quoteChar != '\"')\r
-                       {\r
-                               throw new Exception("an attribute value was not quoted");\r
-                       }\r
-\r
-                       StringBuilder valueBuilder = new StringBuilder();\r
-\r
-                       while (reader.Peek() != quoteChar)\r
-                       {\r
-                               int ch = reader.Read();\r
-\r
-                               switch (ch)\r
-                               {\r
-                               case '<':\r
-                                       throw new Exception("attribute values cannot contain '<'");\r
-                               case -1:\r
-                                       throw new Exception("unexpected end of file in an attribute value");\r
-                               }\r
-\r
-                               valueBuilder.Append((char)ch);\r
-                       }\r
-\r
-                       reader.Read();\r
-\r
-                       return valueBuilder.ToString();\r
-               }\r
-\r
-               // The reader is positioned on the first character\r
-               // of the target.\r
-               private void ReadProcessingInstruction()\r
-               {\r
-                       string target = ReadName();\r
-                       SkipWhitespace();\r
-\r
-                       StringBuilder valueBuilder = new StringBuilder();\r
-\r
-                       while (reader.Peek() != -1)\r
-                       {\r
-                               int ch = reader.Read();\r
-\r
-                               if (ch == '?' && reader.Peek() == '>')\r
-                               {\r
-                                       reader.Read();\r
-                                       break;\r
-                               }\r
-\r
-                               valueBuilder.Append((char)ch);\r
-                       }\r
-\r
-                       SetProperties(\r
-                               XmlNodeType.ProcessingInstruction, // nodeType\r
-                               target, // name\r
-                               false, // isEmptyElement\r
-                               valueBuilder.ToString(), // value\r
-                               true // clearAttributes\r
-                       );\r
-               }\r
-\r
-               // The reader is positioned on the first character after\r
-               // the leading '<!'.\r
-               private void ReadComment()\r
-               {\r
-                       Expect('-');\r
-                       Expect('-');\r
-\r
-                       StringBuilder valueBuilder = new StringBuilder();\r
-\r
-                       while (reader.Peek() != -1)\r
-                       {\r
-                               int ch = reader.Read();\r
-\r
-                               if (ch == '-' && reader.Peek() == '-')\r
-                               {\r
-                                       reader.Read();\r
-\r
-                                       if (reader.Peek() != '>')\r
-                                       {\r
-                                               throw new Exception("comments cannot contain '--'");\r
-                                       }\r
-\r
-                                       reader.Read();\r
-                                       break;\r
-                               }\r
-\r
-                               valueBuilder.Append((char)ch);\r
-                       }\r
-\r
-                       SetProperties(\r
-                               XmlNodeType.Comment, // nodeType\r
-                               String.Empty, // name\r
-                               false, // isEmptyElement\r
-                               valueBuilder.ToString(), // value\r
-                               true // clearAttributes\r
-                       );\r
-               }\r
-\r
-               // The reader is positioned on the first character\r
-               // of the name.\r
-               private string ReadName()\r
-               {\r
-                       if (!XmlChar.IsFirstNameChar(reader.Peek()))\r
-                       {\r
-                               throw new Exception("a name did not start with a legal character");\r
-                       }\r
-\r
-                       StringBuilder nameBuilder = new StringBuilder();\r
-\r
-                       nameBuilder.Append((char)reader.Read());\r
-\r
-                       while (XmlChar.IsNameChar(reader.Peek()))\r
-                       {\r
-                               nameBuilder.Append((char)reader.Read());\r
-                       }\r
-\r
-                       return nameBuilder.ToString();\r
-               }\r
-\r
-               // Read the next character and compare it against the\r
-               // specified character.\r
-               private void Expect(int expected)\r
-               {\r
-                       int ch = reader.Read();\r
-\r
-                       if (ch != expected)\r
-                       {\r
-                               throw new Exception(String.Format(\r
-                                       "expected '{0}' ({1:X}) but found '{2}' ({3:X})",\r
-                                       (char)expected,\r
-                                       expected,\r
-                                       (char)ch,\r
-                                       ch));\r
-                       }\r
-               }\r
-\r
-               // Does not consume the first non-whitespace character.\r
-               private void SkipWhitespace()\r
-               {\r
-                       while (XmlChar.IsWhitespace(reader.Peek()))\r
-                       {\r
-                               reader.Read();\r
-                       }\r
-               }\r
-       }\r
-}\r
+//
+// System.Xml.XmlTextReader
+//
+// Author:
+//   Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001, 2002 Jason Diamond  http://injektilo.org/
+//
+
+// FIXME:
+//   This can only parse basic XML: elements, attributes, processing
+//   instructions, and comments are OK.
+//
+//   It barfs on DOCTYPE declarations.
+//
+//   There's also no checking being done for either well-formedness
+//   or validity.
+//
+//   NameTables aren't being used everywhere yet.
+//
+//   Some thought needs to be given to performance. There's too many
+//   strings being allocated.
+//
+//   Some of the MoveTo methods haven't been implemented yet.
+//
+//   LineNumber and LinePosition aren't being tracked.
+//
+//   xml:space, xml:lang, and xml:base aren't being tracked.
+//
+
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+namespace System.Xml
+{
+       public class XmlTextReader : XmlReader, IXmlLineInfo
+       {
+               #region Constructors
+
+               [MonoTODO]
+               protected XmlTextReader ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public XmlTextReader (Stream input)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public XmlTextReader (string url)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public XmlTextReader (TextReader input)
+               {
+                       XmlNameTable nt = new NameTable ();
+                       XmlNamespaceManager nsMgr = new XmlNamespaceManager (nt);
+                       parserContext = new XmlParserContext (null, nsMgr, null, XmlSpace.None);
+                       Init ();
+                       reader = input;
+               }
+
+               [MonoTODO]
+               protected XmlTextReader (XmlNameTable nt)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public XmlTextReader (Stream input, XmlNameTable nt)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public XmlTextReader (string url, Stream input)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public XmlTextReader (string url, TextReader input)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public XmlTextReader (string url, XmlNameTable nt)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public XmlTextReader (TextReader input, XmlNameTable nt)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public XmlTextReader (Stream xmlFragment, XmlNodeType fragType, XmlParserContext context)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public XmlTextReader (string url, Stream input, XmlNameTable nt)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public XmlTextReader (string url, TextReader input, XmlNameTable nt)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public XmlTextReader (string xmlFragment, XmlNodeType fragType, XmlParserContext context)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               #endregion
+
+               #region Properties
+
+               public override int AttributeCount
+               {
+                       get { return attributes.Count; }
+               }
+
+               [MonoTODO]
+               public override string BaseURI
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public override int Depth
+               {
+                       get { return depth > 0 ? depth : 0; }
+               }
+
+               [MonoTODO]
+               public Encoding Encoding
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public override bool EOF
+               {
+                       get
+                       {
+                               return
+                                       readState == ReadState.EndOfFile ||
+                                       readState == ReadState.Closed;
+                       }
+               }
+
+               public override bool HasValue
+               {
+                       get { return value != String.Empty;     }
+               }
+
+               public override bool IsDefault
+               {
+                       get
+                       {
+                               // XmlTextReader does not expand default attributes.
+                               return false;
+                       }
+               }
+
+               public override bool IsEmptyElement
+               {
+                       get { return isEmptyElement; }
+               }
+
+               public override string this [int i]
+               {
+                       get { return GetAttribute (i); }
+               }
+
+               public override string this [string name]
+               {
+                       get { return GetAttribute (name); }
+               }
+
+               public override string this [string localName, string namespaceName]
+               {
+                       get { return GetAttribute (localName, namespaceName); }
+               }
+
+               [MonoTODO]
+               public int LineNumber
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public int LinePosition
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public override string LocalName
+               {
+                       get { return localName; }
+               }
+
+               public override string Name
+               {
+                       get { return name; }
+               }
+
+               [MonoTODO]
+               public bool Namespaces
+               {
+                       get { throw new NotImplementedException (); }
+                       set { throw new NotImplementedException (); }
+               }
+
+               public override string NamespaceURI
+               {
+                       get { return namespaceURI; }
+               }
+
+               public override XmlNameTable NameTable
+               {
+                       get { return parserContext.NameTable; }
+               }
+
+               public override XmlNodeType NodeType
+               {
+                       get { return nodeType; }
+               }
+
+               [MonoTODO]
+               public bool Normalization
+               {
+                       get { throw new NotImplementedException (); }
+                       set { throw new NotImplementedException (); }
+               }
+
+               public override string Prefix
+               {
+                       get { return prefix; }
+               }
+
+               [MonoTODO]
+               public override char QuoteChar
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public override ReadState ReadState
+               {
+                       get { return readState; }
+               }
+
+               public override string Value
+               {
+                       get { return value; }
+               }
+
+               [MonoTODO]
+               public WhitespaceHandling WhitespaceHandling
+               {
+                       get { throw new NotImplementedException (); }
+                       set { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public override string XmlLang
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public XmlResolver XmlResolver
+               {
+                       set { throw new NotImplementedException (); }
+               }
+
+               [MonoTODO]
+               public override XmlSpace XmlSpace
+               {
+                       get { throw new NotImplementedException (); }
+               }
+
+               #endregion
+
+               #region Methods
+
+               [MonoTODO]
+               public override void Close ()
+               {
+                       readState = ReadState.Closed;
+               }
+
+               [MonoTODO]
+               public override string GetAttribute (int i)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public override string GetAttribute (string name)
+               {
+                       return attributes [name] as string;
+               }
+
+               public override string GetAttribute (string localName, string namespaceURI)
+               {
+                       foreach (DictionaryEntry entry in attributes)
+                       {
+                               string thisName = entry.Key as string;
+
+                               int indexOfColon = thisName.IndexOf (':');
+
+                               if (indexOfColon != -1) {
+                                       string thisLocalName = thisName.Substring (indexOfColon + 1);
+
+                                       if (localName == thisLocalName) {
+                                               string thisPrefix = thisName.Substring (0, indexOfColon);
+                                               string thisNamespaceURI = LookupNamespace (thisPrefix);
+
+                                               if (namespaceURI == thisNamespaceURI)
+                                                       return attributes [thisName] as string;
+                                       }
+                               } else if (localName == "xmlns" && namespaceURI == "http://www.w3.org/2000/xmlns/" && thisName == "xmlns")
+                                       return attributes [thisName] as string;
+                       }
+
+                       return String.Empty;
+               }
+
+               [MonoTODO]
+               public TextReader GetRemainder ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               bool IXmlLineInfo.HasLineInfo ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public override string LookupNamespace (string prefix)
+               {
+                       return parserContext.NamespaceManager.LookupNamespace (prefix);
+               }
+
+               [MonoTODO]
+               public override void MoveToAttribute (int i)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public override bool MoveToAttribute (string name)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public override bool MoveToAttribute (string localName, string namespaceName)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public override bool MoveToElement ()
+               {
+                       if (nodeType == XmlNodeType.Attribute) {
+                               RestoreProperties ();
+                               return true;
+                       }
+
+                       return false;
+               }
+
+               public override bool MoveToFirstAttribute ()
+               {
+                       MoveToElement ();
+                       return MoveToNextAttribute ();
+               }
+
+               public override bool MoveToNextAttribute ()
+               {
+                       if (attributes == null)
+                               return false;
+
+                       if (attributeEnumerator == null) {
+                               SaveProperties ();
+                               attributeEnumerator = attributes.GetEnumerator ();
+                       }
+
+                       if (attributeEnumerator.MoveNext ()) {
+                               string name = attributeEnumerator.Key as string;
+                               string value = attributeEnumerator.Value as string;
+                               SetProperties (
+                                       XmlNodeType.Attribute, // nodeType
+                                       name, // name
+                                       false, // isEmptyElement
+                                       value, // value
+                                       false // clearAttributes
+                               );
+                               return true;
+                       }
+
+                       return false;
+               }
+
+               public override bool Read ()
+               {
+                       bool more = false;
+
+                       readState = ReadState.Interactive;
+
+                       more = ReadContent ();
+
+                       return more;
+               }
+
+               [MonoTODO]
+               public override bool ReadAttributeValue ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public int ReadBase64 (byte [] buffer, int offset, int length)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public int ReadBinHex (byte [] buffer, int offset, int length)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public int ReadChars (char [] buffer, int offset, int length)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public override string ReadInnerXml ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public override string ReadOuterXml ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public override string ReadString ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public void ResetState ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public override void ResolveEntity ()
+               {
+                       // XmlTextReaders don't resolve entities.
+                       throw new InvalidOperationException ("XmlTextReaders don't resolve entities.");
+               }
+
+               #endregion
+
+               // privates
+
+               private XmlParserContext parserContext;
+
+               private TextReader reader;
+               private ReadState readState;
+
+               private int depth;
+               private bool depthDown;
+
+               private bool popScope;
+
+               private XmlNodeType nodeType;
+               private string name;
+               private string prefix;
+               private string localName;
+               private string namespaceURI;
+               private bool isEmptyElement;
+               private string value;
+
+               private XmlNodeType saveNodeType;
+               private string saveName;
+               private string savePrefix;
+               private string saveLocalName;
+               private string saveNamespaceURI;
+               private bool saveIsEmptyElement;
+       
+               private Hashtable attributes;
+               private IDictionaryEnumerator attributeEnumerator;
+
+               private bool returnEntityReference;
+               private string entityReferenceName;
+
+               private char [] nameBuffer;
+               private int nameLength;
+               private int nameCapacity;
+               private const int initialNameCapacity = 256;
+
+               private char [] valueBuffer;
+               private int valueLength;
+               private int valueCapacity;
+               private const int initialValueCapacity = 8192;
+
+               private void Init ()
+               {
+                       readState = ReadState.Initial;
+
+                       depth = -1;
+                       depthDown = false;
+
+                       popScope = false;
+
+                       nodeType = XmlNodeType.None;
+                       name = String.Empty;
+                       prefix = String.Empty;
+                       localName = string.Empty;
+                       isEmptyElement = false;
+                       value = String.Empty;
+
+                       attributes = new Hashtable ();
+                       attributeEnumerator = null;
+
+                       returnEntityReference = false;
+                       entityReferenceName = String.Empty;
+
+                       nameBuffer = new char [initialNameCapacity];
+                       nameLength = 0;
+                       nameCapacity = initialNameCapacity;
+
+                       valueBuffer = new char [initialValueCapacity];
+                       valueLength = 0;
+                       valueCapacity = initialValueCapacity;
+               }
+
+               // Use this method rather than setting the properties
+               // directly so that all the necessary properties can
+               // be changed in harmony with each other. Maybe the
+               // fields should be in a seperate class to help enforce
+               // this.
+               private void SetProperties (
+                       XmlNodeType nodeType,
+                       string name,
+                       bool isEmptyElement,
+                       string value,
+                       bool clearAttributes)
+               {
+                       this.nodeType = nodeType;
+                       this.name = name;
+                       this.isEmptyElement = isEmptyElement;
+                       this.value = value;
+
+                       if (clearAttributes)
+                               ClearAttributes ();
+
+                       int indexOfColon = name.IndexOf (':');
+
+                       if (indexOfColon == -1) {
+                               prefix = String.Empty;
+                               localName = name;
+                       } else {
+                               prefix = name.Substring (0, indexOfColon);
+                               localName = name.Substring (indexOfColon + 1);
+                       }
+
+                       namespaceURI = LookupNamespace (prefix);
+               }
+
+               private void SaveProperties ()
+               {
+                       saveNodeType = nodeType;
+                       saveName = name;
+                       savePrefix = prefix;
+                       saveLocalName = localName;
+                       saveNamespaceURI = namespaceURI;
+                       saveIsEmptyElement = isEmptyElement;
+                       // An element's value is always String.Empty.
+               }
+
+               private void RestoreProperties ()
+               {
+                       nodeType = saveNodeType;
+                       name = saveName;
+                       prefix = savePrefix;
+                       localName = saveLocalName;
+                       namespaceURI = saveNamespaceURI;
+                       isEmptyElement = saveIsEmptyElement;
+                       value = String.Empty;
+               }
+
+               private void AddAttribute (string name, string value)
+               {
+                       attributes.Add (name, value);
+               }
+
+               private void ClearAttributes ()
+               {
+                       if (attributes.Count > 0)
+                               attributes.Clear ();
+
+                       attributeEnumerator = null;
+               }
+
+               private int PeekChar ()
+               {
+                       return reader.Peek ();
+               }
+
+               private int ReadChar ()
+               {
+                       return reader.Read ();
+               }
+
+               // This should really keep track of some state so
+               // that it's not possible to have more than one document
+               // element or text outside of the document element.
+               private bool ReadContent ()
+               {
+                       bool more = false;
+
+                       if (popScope) {
+                               parserContext.NamespaceManager.PopScope ();
+                               popScope = false;
+                       }
+
+                       if (depthDown)
+                               --depth;
+
+                       if (returnEntityReference) {
+                               ++depth;
+                               SetEntityReferenceProperties ();
+                               more = true;
+                       } else {
+                               switch (PeekChar ())
+                               {
+                               case '<':
+                                       ReadChar ();
+                                       ReadTag ();
+                                       more = true;
+                                       break;
+                               case -1:
+                                       readState = ReadState.EndOfFile;
+                                       SetProperties (
+                                               XmlNodeType.None, // nodeType
+                                               String.Empty, // name
+                                               false, // isEmptyElement
+                                               String.Empty, // value
+                                               true // clearAttributes
+                                       );
+                                       more = false;
+                                       break;
+                               default:
+                                       ReadText ();
+                                       more = true;
+                                       break;
+                               }
+                       }
+
+                       return more;
+               }
+
+               private void SetEntityReferenceProperties ()
+               {
+                       SetProperties (
+                               XmlNodeType.EntityReference, // nodeType
+                               entityReferenceName, // name
+                               false, // isEmptyElement
+                               String.Empty, // value
+                               true // clearAttributes
+                       );
+
+                       returnEntityReference = false;
+                       entityReferenceName = String.Empty;
+               }
+
+               // The leading '<' has already been consumed.
+               private void ReadTag ()
+               {
+                       switch (PeekChar ())
+                       {
+                       case '/':
+                               ReadChar ();
+                               ReadEndTag ();
+                               break;
+                       case '?':
+                               ReadChar ();
+                               ReadProcessingInstruction ();
+                               break;
+                       case '!':
+                               ReadChar ();
+                               ReadDeclaration ();
+                               break;
+                       default:
+                               ReadStartTag ();
+                               break;
+                       }
+               }
+
+               // The leading '<' has already been consumed.
+               private void ReadStartTag ()
+               {
+                       parserContext.NamespaceManager.PushScope ();
+
+                       string name = ReadName ();
+                       SkipWhitespace ();
+
+                       bool isEmptyElement = false;
+
+                       ClearAttributes ();
+
+                       if (XmlChar.IsFirstNameChar (PeekChar ()))
+                               ReadAttributes ();
+
+                       if (PeekChar () == '/') {
+                               ReadChar ();
+                               isEmptyElement = true;
+                               depthDown = true;
+                               popScope = true;
+                       }
+
+                       Expect ('>');
+
+                       ++depth;
+
+                       SetProperties (
+                               XmlNodeType.Element, // nodeType
+                               name, // name
+                               isEmptyElement, // isEmptyElement
+                               String.Empty, // value
+                               false // clearAttributes
+                       );
+               }
+
+               // The reader is positioned on the first character
+               // of the element's name.
+               private void ReadEndTag ()
+               {
+                       string name = ReadName ();
+                       SkipWhitespace ();
+                       Expect ('>');
+
+                       --depth;
+
+                       SetProperties (
+                               XmlNodeType.EndElement, // nodeType
+                               name, // name
+                               false, // isEmptyElement
+                               String.Empty, // value
+                               true // clearAttributes
+                       );
+
+                       popScope = true;
+               }
+
+               private void AppendNameChar (int ch)
+               {
+                       CheckNameCapacity ();
+                       nameBuffer [nameLength++] = (char)ch;
+               }
+
+               private void CheckNameCapacity ()
+               {
+                       if (nameLength == nameCapacity) {
+                               nameCapacity = nameCapacity * 2;
+                               char [] oldNameBuffer = nameBuffer;
+                               nameBuffer = new char [nameCapacity];
+                               Array.Copy (oldNameBuffer, nameBuffer, nameLength);
+                       }
+               }
+
+               private string CreateNameString ()
+               {
+                       return new String (nameBuffer, 0, nameLength);
+               }
+
+               private void AppendValueChar (int ch)
+               {
+                       CheckValueCapacity ();
+                       valueBuffer [valueLength++] = (char)ch;
+               }
+
+               private void CheckValueCapacity ()
+               {
+                       if (valueLength == valueCapacity) {
+                               valueCapacity = valueCapacity * 2;
+                               char [] oldValueBuffer = valueBuffer;
+                               valueBuffer = new char [valueCapacity];
+                               Array.Copy (oldValueBuffer, valueBuffer, valueLength);
+                       }
+               }
+
+               private string CreateValueString ()
+               {
+                       return new String (valueBuffer, 0, valueLength);
+               }
+
+               // The reader is positioned on the first character
+               // of the text.
+               private void ReadText ()
+               {
+                       valueLength = 0;
+
+                       int ch = PeekChar ();
+
+                       while (ch != '<' && ch != -1) {
+                               if (ch == '&') {
+                                       ReadChar ();
+                                       if (ReadReference (false))
+                                               break;
+                               } else
+                                       AppendValueChar (ReadChar ());
+
+                               ch = PeekChar ();
+                       }
+
+                       if (returnEntityReference && valueLength == 0) {
+                               ++depth;
+                               SetEntityReferenceProperties ();
+                       } else {
+                               if (depth >= 0) {
+                                       ++depth;
+                                       depthDown = true;
+                               }
+
+                               SetProperties (
+                                       XmlNodeType.Text, // nodeType
+                                       String.Empty, // name
+                                       false, // isEmptyElement
+                                       CreateValueString (), // value
+                                       true // clearAttributes
+                               );
+                       }
+               }
+
+               // The leading '&' has already been consumed.
+               // Returns true if the entity reference isn't a simple
+               // character reference or one of the predefined entities.
+               // This allows the ReadText method to break so that the
+               // next call to Read will return the EntityReference node.
+               private bool ReadReference (bool ignoreEntityReferences)
+               {
+                       if (PeekChar () == '#') {
+                               ReadChar ();
+                               ReadCharacterReference ();
+                       } else
+                               ReadEntityReference (ignoreEntityReferences);
+
+                       return returnEntityReference;
+               }
+
+               private void ReadCharacterReference ()
+               {
+                       int value = 0;
+
+                       if (PeekChar () == 'x') {
+                               ReadChar ();
+
+                               while (PeekChar () != ';' && PeekChar () != -1) {
+                                       int ch = ReadChar ();
+
+                                       if (ch >= '0' && ch <= '9')
+                                               value = (value << 4) + ch - '0';
+                                       else if (ch >= 'A' && ch <= 'F')
+                                               value = (value << 4) + ch - 'A' + 10;
+                                       else if (ch >= 'a' && ch <= 'f')
+                                               value = (value << 4) + ch - 'a' + 10;
+                                       else
+                                               throw new XmlException (
+                                                       String.Format (
+                                                               "invalid hexadecimal digit: {0} (#x{1:X})",
+                                                               (char)ch,
+                                                               ch));
+                               }
+                       } else {
+                               while (PeekChar () != ';' && PeekChar () != -1) {
+                                       int ch = ReadChar ();
+
+                                       if (ch >= '0' && ch <= '9')
+                                               value = value * 10 + ch - '0';
+                                       else
+                                               throw new XmlException (
+                                                       String.Format (
+                                                               "invalid decimal digit: {0} (#x{1:X})",
+                                                               (char)ch,
+                                                               ch));
+                               }
+                       }
+
+                       ReadChar (); // ';'
+
+                       AppendValueChar (value);
+               }
+
+               private void ReadEntityReference (bool ignoreEntityReferences)
+               {
+                       nameLength = 0;
+
+                       int ch = PeekChar ();
+
+                       while (ch != ';' && ch != -1) {
+                               AppendNameChar (ReadChar ());
+                               ch = PeekChar ();
+                       }
+
+                       Expect (';');
+
+                       string name = CreateNameString ();
+
+                       switch (name)
+                       {
+                               case "lt":
+                                       AppendValueChar ('<');
+                                       break;
+                               case "gt":
+                                       AppendValueChar ('>');
+                                       break;
+                               case "amp":
+                                       AppendValueChar ('&');
+                                       break;
+                               case "apos":
+                                       AppendValueChar ('\'');
+                                       break;
+                               case "quot":
+                                       AppendValueChar ('"');
+                                       break;
+                               default:
+                                       if (ignoreEntityReferences) {
+                                               AppendValueChar ('&');
+
+                                               foreach (char ch2 in name) {
+                                                       AppendValueChar (ch2);
+                                               }
+
+                                               AppendValueChar (';');
+                                       } else {
+                                               returnEntityReference = true;
+                                               entityReferenceName = name;
+                                       }
+                                       break;
+                       }
+               }
+
+               // The reader is positioned on the first character of
+               // the attribute name.
+               private void ReadAttributes ()
+               {
+                       do {
+                               string name = ReadName ();
+                               SkipWhitespace ();
+                               Expect ('=');
+                               SkipWhitespace ();
+                               string value = ReadAttribute ();
+                               SkipWhitespace ();
+
+                               if (name == "xmlns")
+                                       parserContext.NamespaceManager.AddNamespace (String.Empty, value);
+                               else if (name.StartsWith ("xmlns:"))
+                                       parserContext.NamespaceManager.AddNamespace (name.Substring (6), value);
+
+                               AddAttribute (name, value);
+                       } while (PeekChar () != '/' && PeekChar () != '>' && PeekChar () != -1);
+               }
+
+               // The reader is positioned on the quote character.
+               private string ReadAttribute ()
+               {
+                       int quoteChar = ReadChar ();
+
+                       if (quoteChar != '\'' && quoteChar != '\"')
+                               throw new XmlException ("an attribute value was not quoted");
+
+                       valueLength = 0;
+
+                       while (PeekChar () != quoteChar) {
+                               int ch = ReadChar ();
+
+                               switch (ch)
+                               {
+                               case '<':
+                                       throw new XmlException ("attribute values cannot contain '<'");
+                               case '&':
+                                       ReadReference (true);
+                                       break;
+                               case -1:
+                                       throw new XmlException ("unexpected end of file in an attribute value");
+                               default:
+                                       AppendValueChar (ch);
+                                       break;
+                               }
+                       }
+
+                       ReadChar (); // quoteChar
+
+                       return CreateValueString ();
+               }
+
+               // The reader is positioned on the first character
+               // of the target.
+               private void ReadProcessingInstruction ()
+               {
+                       string target = ReadName ();
+                       SkipWhitespace ();
+
+                       valueLength = 0;
+
+                       while (PeekChar () != -1) {
+                               int ch = ReadChar ();
+
+                               if (ch == '?' && PeekChar () == '>') {
+                                       ReadChar ();
+                                       break;
+                               }
+
+                               AppendValueChar ((char)ch);
+                       }
+
+                       SetProperties (
+                               XmlNodeType.ProcessingInstruction, // nodeType
+                               target, // name
+                               false, // isEmptyElement
+                               CreateValueString (), // value
+                               true // clearAttributes
+                       );
+               }
+
+               // The reader is positioned on the first character after
+               // the leading '<!'.
+               private void ReadDeclaration ()
+               {
+                       int ch = PeekChar ();
+
+                       switch (ch)
+                       {
+                       case '-':
+                               Expect ('-');
+                               Expect ('-');
+                               ReadComment ();
+                               break;
+                       case '[':
+                               ReadChar ();
+                               Expect ('C');
+                               Expect ('D');
+                               Expect ('A');
+                               Expect ('T');
+                               Expect ('A');
+                               Expect ('[');
+                               ReadCDATA ();
+                               break;
+                       }
+               }
+
+               // The reader is positioned on the first character after
+               // the leading '<!--'.
+               private void ReadComment ()
+               {
+                       valueLength = 0;
+
+                       while (PeekChar () != -1) {
+                               int ch = ReadChar ();
+
+                               if (ch == '-' && PeekChar () == '-') {
+                                       ReadChar ();
+
+                                       if (PeekChar () != '>')
+                                               throw new XmlException ("comments cannot contain '--'");
+
+                                       ReadChar ();
+                                       break;
+                               }
+
+                               AppendValueChar ((char)ch);
+                       }
+
+                       SetProperties (
+                               XmlNodeType.Comment, // nodeType
+                               String.Empty, // name
+                               false, // isEmptyElement
+                               CreateValueString (), // value
+                               true // clearAttributes
+                       );
+               }
+
+               // The reader is positioned on the first character after
+               // the leading '<![CDATA['.
+               private void ReadCDATA ()
+               {
+                       valueLength = 0;
+
+                       while (PeekChar () != -1) {
+                               int ch = ReadChar ();
+
+                               if (ch == ']' && PeekChar () == ']') {
+                                       ch = ReadChar (); // ']'
+
+                                       if (PeekChar () == '>') {
+                                               ReadChar (); // '>'
+                                               break;
+                                       } else {
+                                               AppendValueChar (']');
+                                               AppendValueChar (']');
+                                               ch = ReadChar ();
+                                       }
+                               }
+
+                               AppendValueChar ((char)ch);
+                       }
+
+                       ++depth;
+
+                       SetProperties (
+                               XmlNodeType.CDATA, // nodeType
+                               String.Empty, // name
+                               false, // isEmptyElement
+                               CreateValueString (), // value
+                               true // clearAttributes
+                       );
+               }
+
+               // The reader is positioned on the first character
+               // of the name.
+               private string ReadName ()
+               {
+                       if (!XmlChar.IsFirstNameChar (PeekChar ()))
+                               throw new XmlException ("a name did not start with a legal character");
+
+                       nameLength = 0;
+
+                       AppendNameChar (ReadChar ());
+
+                       while (XmlChar.IsNameChar (PeekChar ())) {
+                               AppendNameChar (ReadChar ());
+                       }
+
+                       return CreateNameString ();
+               }
+
+               // Read the next character and compare it against the
+               // specified character.
+               private void Expect (int expected)
+               {
+                       int ch = ReadChar ();
+
+                       if (ch != expected) {
+                               throw new XmlException (
+                                       String.Format (
+                                               "expected '{0}' ({1:X}) but found '{2}' ({3:X})",
+                                               (char)expected,
+                                               expected,
+                                               (char)ch,
+                                               ch));
+                       }
+               }
+
+               // Does not consume the first non-whitespace character.
+               private void SkipWhitespace ()
+               {
+                       while (XmlChar.IsWhitespace (PeekChar ()))
+                               ReadChar ();
+               }
+       }
+}