context: //
  // System.Xml.XmlReaderCommonTests
  //
  // Authors:
  //   Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
  //
  // (C) 2003 Atsushi Enomoto
  //  Note: Most of testcases are moved from XmlTextReaderTests.cs and
  //  XmlNodeReaderTests.cs.
  //
  
  using System;
  using System.IO;
  using System.Text;
  using System.Xml;
  using System.Xml.Schema;
  using System.Xml.XPath;
  #if NET_4_5
  using System.Threading;
  using System.Threading.Tasks;
  #endif
  
  using NUnit.Framework;
  
  namespace MonoTests.System.Xml
  {
  	[TestFixture]
  	public class XmlReaderTests
  	{
  		[SetUp]
  		public void GetReady ()
  		{
  			document = new XmlDocument ();
  			document.LoadXml (xml1);
  		}
  
  		XmlDocument document;
  		const string xml1 = "<root attr1='value1'><child /></root>";
  		const string xml2 = "<root><foo/><bar>test.</bar></root>";
  		const string xml3 = "<root>  test of <b>mixed</b> string.<![CDATA[ cdata string.]]></root>";
  		const string xml4 = "<root>test of <b>mixed</b> string.</root>";
  		XmlTextReader xtr;
  		XmlNodeReader xnr;
  
  		// copy from XmlTextReaderTests
  		private void AssertStartDocument (XmlReader xmlReader)
  		{
  			Assert.IsTrue (xmlReader.ReadState == ReadState.Initial);
  			Assert.IsTrue (xmlReader.NodeType == XmlNodeType.None);
  			Assert.IsTrue (xmlReader.Depth == 0);
  			Assert.IsTrue (!xmlReader.EOF);
  		}
  
  		private void AssertNode (
  			XmlReader xmlReader,
  			XmlNodeType nodeType,
  			int depth,
  			bool isEmptyElement,
  			string name,
  			string prefix,
  			string localName,
  			string namespaceURI,
  			string value,
  			int attributeCount)
  		{
  			AssertNode ("", xmlReader, nodeType, depth,
  				isEmptyElement, name, prefix, localName,
  				namespaceURI, value, attributeCount);
  		}
  
  		private void AssertNode (
  			string label,
  			XmlReader xmlReader,
  			XmlNodeType nodeType,
  			int depth,
  			bool isEmptyElement,
  			string name,
  			string prefix,
  			string localName,
  			string namespaceURI,
  			string value,
  			int attributeCount)
  		{
  			Assert.IsTrue (xmlReader.Read (), label + " Read() return value");
  			Assert.IsTrue (xmlReader.ReadState == ReadState.Interactive, label + " ReadState");
  			Assert.IsTrue (!xmlReader.EOF, label + " !EOF");
  			AssertNodeValues (label, xmlReader, nodeType, depth,
  				isEmptyElement, name, prefix, localName,
  				namespaceURI, value, value != String.Empty,
  				attributeCount, attributeCount > 0);
  		}
  
  		private void AssertNodeValues (
  			string label,
  			XmlReader xmlReader,
  			XmlNodeType nodeType,
  			int depth,
  			bool isEmptyElement,
  			string name,
  			string prefix,
  			string localName,
  			string namespaceURI,
  			string value,
  			int attributeCount)
  		{
  			AssertNodeValues (label, xmlReader, nodeType, depth,
  				isEmptyElement, name, prefix, localName,
  				namespaceURI, value, value != String.Empty,
  				attributeCount, attributeCount > 0);
  		}
  
  		private void AssertNodeValues (
  			string label,
  			XmlReader xmlReader,
  			XmlNodeType nodeType,
  			int depth,
  			bool isEmptyElement,
  			string name,
  			string prefix,
  			string localName,
  			string namespaceURI,
  			string value,
  			bool hasValue,
  			int attributeCount,
  			bool hasAttributes)
  		{
  			label = String.Concat (label, "(", xmlReader.GetType ().Name, ")");
  			Assert.AreEqual (nodeType, xmlReader.NodeType, label + ": NodeType");
  			Assert.AreEqual (isEmptyElement, xmlReader.IsEmptyElement, label + ": IsEmptyElement");
  
  			Assert.AreEqual (name, xmlReader.Name, label + ": name");
  
  			Assert.AreEqual (prefix, xmlReader.Prefix, label + ": prefix");
  
  			Assert.AreEqual (localName, xmlReader.LocalName, label + ": localName");
  
  			Assert.AreEqual (namespaceURI, xmlReader.NamespaceURI, label + ": namespaceURI");
  
  			Assert.AreEqual (depth, xmlReader.Depth, label + ": Depth");
  
  			Assert.AreEqual (hasValue, xmlReader.HasValue, label + ": hasValue");
  
  			Assert.AreEqual (value, xmlReader.Value, label + ": Value");
  
  			Assert.AreEqual (hasAttributes, xmlReader.HasAttributes, label + ": hasAttributes");
  
  			Assert.AreEqual (attributeCount, xmlReader.AttributeCount, label + ": attributeCount");
  		}
  
  		private void AssertAttribute (
  			XmlReader xmlReader,
  			string name,
  			string prefix,
  			string localName,
  			string namespaceURI,
  			string value)
  		{
  			Assert.AreEqual (value, xmlReader [name], "value");
  
  			Assert.IsTrue (xmlReader.GetAttribute (name) == value);
  
  			if (namespaceURI != String.Empty) {
  				Assert.IsTrue (xmlReader[localName, namespaceURI] == value);
  				Assert.IsTrue (xmlReader.GetAttribute (localName, namespaceURI) == value);
  			}
  		}
  
  		private void AssertEndDocument (XmlReader xmlReader)
  		{
  			Assert.IsTrue (!xmlReader.Read (), "could read");
  			Assert.AreEqual (XmlNodeType.None, xmlReader.NodeType, "NodeType is not XmlNodeType.None");
  			Assert.AreEqual (0, xmlReader.Depth, "Depth is not 0");
  			Assert.AreEqual (ReadState.EndOfFile, xmlReader.ReadState, "ReadState is not ReadState.EndOfFile");
  			Assert.IsTrue (xmlReader.EOF, "not EOF");
  
  			xmlReader.Close ();
  			Assert.AreEqual (ReadState.Closed, xmlReader.ReadState, "ReadState is not ReadState.Cosed");
  		}
  
  		private delegate void TestMethod (XmlReader reader);
  
  		private void RunTest (string xml, TestMethod method)
  		{
  			xtr = new XmlTextReader (new StringReader (xml));
  			method (xtr);
  
  			// DTD validation
  			xtr = new XmlTextReader (new StringReader (xml));
  			XmlValidatingReader xvr = new XmlValidatingReader (xtr);
  			xvr.ValidationType = ValidationType.DTD;
  			xvr.EntityHandling = EntityHandling.ExpandCharEntities;
  			method (xvr);
  
  			// XSD validation
  			xtr = new XmlTextReader (new StringReader (xml));
  			xvr = new XmlValidatingReader (xtr);
  			xvr.EntityHandling = EntityHandling.ExpandCharEntities;
  			method (xvr);
  
  			document.XmlResolver = null;
  			document.LoadXml (xml);
  			xnr = new XmlNodeReader (document);
  			method (xnr);
  /*
  			// XPathNavigatorReader tests
  			System.Xml.XPath.XPathDocument doc = new System.Xml.XPath.XPathDocument (new StringReader (xml));
  			XmlReader xpr = doc.CreateNavigator ().ReadSubtree ();
  			method (xpr);
  */
  		}
  
  
  
  
  
  		[Test]
  		public void InitialState ()
  		{
  			RunTest (xml1, new TestMethod (InitialState));
  		}
  
  		private void InitialState (XmlReader reader)
  		{
  			Assert.AreEqual (0, reader.Depth, "Depth");
  			Assert.AreEqual (false, reader.EOF, "EOF");
  			Assert.AreEqual (false, reader.HasValue, "HasValue");
  			Assert.AreEqual (false, reader.IsEmptyElement, "IsEmptyElement");
  			Assert.AreEqual (String.Empty, reader.LocalName, "LocalName");
  			Assert.AreEqual (XmlNodeType.None, reader.NodeType, "NodeType");
  			Assert.AreEqual (ReadState.Initial, reader.ReadState, "ReadState");
  		}
  
  		[Test]
  		public void Read ()
  		{
  			RunTest (xml1, new TestMethod (Read));
  		}
  
  		public void Read (XmlReader reader)
  		{
  			reader.Read ();
  			Assert.AreEqual (XmlNodeType.Element, reader.NodeType, "<root>.NodeType");
  			Assert.AreEqual ("root", reader.Name, "<root>.Name");
  			Assert.AreEqual (ReadState.Interactive, reader.ReadState, "<root>.ReadState");
  			Assert.AreEqual (0, reader.Depth, "<root>.Depth");
  
  			// move to 'child'
  			reader.Read ();
  			Assert.AreEqual (1, reader.Depth, "<child/>.Depth");
  			Assert.AreEqual (XmlNodeType.Element, reader.NodeType, "<child/>.NodeType");
  			Assert.AreEqual ("child", reader.Name, "<child/>.Name");
  
  			reader.Read ();
  			Assert.AreEqual (0, reader.Depth, "</root>.Depth");
  			Assert.AreEqual (XmlNodeType.EndElement, reader.NodeType, "</root>.NodeType");
  			Assert.AreEqual ("root", reader.Name, "</root>.Name");
  
  			reader.Read ();
  			Assert.AreEqual (true, reader.EOF, "end.EOF");
  			Assert.AreEqual (XmlNodeType.None, reader.NodeType, "end.NodeType");
  		}
  
  		[Test]
  		[Category ("NotDotNet")]
  		public void ReadAttributeValue ()
  		{
  			RunTest ("<root attr=''/>", new TestMethod (ReadAttributeValue));
  		}
  
  		public void ReadAttributeValue (XmlReader reader)
  		{
  			reader.Read ();	// root
  			Assert.IsTrue (reader.MoveToFirstAttribute ());
  			// It looks like that MS.NET shows AttributeCount and
  			// HasAttributes as the same as element node!
  			this.AssertNodeValues ("#1",
  				reader, XmlNodeType.Attribute,
  				1, false, "attr", "", "attr", "", "", true, 1, true);
  			Assert.IsTrue (reader.ReadAttributeValue ());
  			// MS.NET XmlTextReader fails. Its Prefix returns 
  			// null instead of "". It is fixed in MS.NET 2.0.
  			this.AssertNodeValues ("#2",
  				reader, XmlNodeType.Text,
  				2, false, "", "", "", "", "", true, 1, true);
  			Assert.IsTrue (reader.MoveToElement ());
  			this.AssertNodeValues ("#3",
  				reader, XmlNodeType.Element,
  				0, true, "root", "", "root", "", "", false, 1, true);
  		}
  
  		[Test]
  		public void ReadEmptyElement ()
  		{
  			RunTest (xml2, new TestMethod (ReadEmptyElement));
  		}
  
  		public void ReadEmptyElement (XmlReader reader)
  		{
  			reader.Read ();	// root
  			Assert.AreEqual (false, reader.IsEmptyElement);
  			reader.Read ();	// foo
  			Assert.AreEqual ("foo", reader.Name);
  			Assert.AreEqual (true, reader.IsEmptyElement);
  			reader.Read ();	// bar
  			Assert.AreEqual ("bar", reader.Name);
  			Assert.AreEqual (false, reader.IsEmptyElement);
  		}
  
  		[Test]
  		public void ReadStringFromElement ()
  		{
  			RunTest (xml3, new TestMethod (ReadStringFromElement));
  		}
  
  		public void ReadStringFromElement (XmlReader reader)
  		{
  			// Note: ReadString() test works only when the reader is
  			// positioned at the container element.
  			// In case the reader is positioned at the first 
  			// character node, XmlTextReader and XmlNodeReader works
  			// different!!
  
  			reader.Read ();
  			string s = reader.ReadString ();
  			Assert.AreEqual ("  test of ", s, "readString.1.ret_val");
  			Assert.AreEqual ("b", reader.Name, "readString.1.Name");
  			s = reader.ReadString ();
  			Assert.AreEqual ("mixed", s, "readString.2.ret_val");
  			Assert.AreEqual (XmlNodeType.EndElement, reader.NodeType, "readString.2.NodeType");
  			s = reader.ReadString ();	// never proceeds.
  			Assert.AreEqual (String.Empty, s, "readString.3.ret_val");
  			Assert.AreEqual (XmlNodeType.EndElement, reader.NodeType, "readString.3.NodeType");
  			reader.Read ();
  			Assert.AreEqual (XmlNodeType.Text, reader.NodeType, "readString.4.NodeType");
  			Assert.AreEqual (" string.", reader.Value, "readString.4.Value");
  			s = reader.ReadString ();	// reads the same Text node.
  			Assert.AreEqual (" string. cdata string.", s, "readString.5.ret_val");
  			Assert.AreEqual (XmlNodeType.EndElement, reader.NodeType, "readString.5.NodeType");
  		}
  
  		[Test]
  		public void ReadInnerXml ()
  		{
  			const string xml = "<root><foo>test of <b>mixed</b> string.</foo><bar /></root>";
  			RunTest (xml, new TestMethod (ReadInnerXml));
  		}
  
  		public void ReadInnerXml (XmlReader reader)
  		{
  			reader.Read ();
  			reader.Read ();
  			Assert.AreEqual (ReadState.Interactive, reader.ReadState, "initial.ReadState");
  			Assert.AreEqual (false, reader.EOF, "initial.EOF");
  			Assert.AreEqual (XmlNodeType.Element, reader.NodeType, "initial.NodeType");
  			string s = reader.ReadInnerXml ();
  			Assert.AreEqual ("test of <b>mixed</b> string.", s, "read_all");
  			Assert.AreEqual ("bar", reader.Name, "after.Name");
  			Assert.AreEqual (XmlNodeType.Element, reader.NodeType, "after.NodeType");
  		}
  
  
  		[Test]
  		public void EmptyElement ()
  		{
  			RunTest ("<foo/>", new TestMethod (EmptyElement));
  		}
  		
  		public void EmptyElement (XmlReader xmlReader)
  		{
  
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, // depth
  				true, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void NestedEmptyTag ()
  		{
  			string xml = "<foo><bar/></foo>";
  			RunTest (xml, new TestMethod (NestedEmptyTag));
  		}
  
  		public void NestedEmptyTag (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				"#1",
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, //depth
  				false, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertNode (
  				"#2",
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				1, //depth
  				true, // isEmptyElement
  				"bar", // name
  				String.Empty, // prefix
  				"bar", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertNode (
  				"#3",
  				xmlReader, // xmlReader
  				XmlNodeType.EndElement, // nodeType
  				0, //depth
  				false, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void NestedText ()
  		{
  			string xml = "<foo>bar</foo>";
  			RunTest (xml, new TestMethod (NestedText));
  		}
  
  		public void NestedText (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, //depth
  				false, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Text, // nodeType
  				1, //depth
  				false, // isEmptyElement
  				String.Empty, // name
  				String.Empty, // prefix
  				String.Empty, // localName
  				String.Empty, // namespaceURI
  				"bar", // value
  				0 // attributeCount
  			);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.EndElement, // nodeType
  				0, //depth
  				false, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void EmptyElementWithAttributes ()
  		{
  			string xml = @"<foo bar=""baz"" quux='quuux' x:foo='x-foo' xmlns:x = 'urn:xfoo' />";
  			RunTest (xml, new TestMethod (EmptyElementWithAttributes ));
  		}
  
  		public void EmptyElementWithAttributes (XmlReader xmlReader)
  		{
  
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, //depth
  				true, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				4 // attributeCount
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"bar", // name
  				String.Empty, // prefix
  				"bar", // localName
  				String.Empty, // namespaceURI
  				"baz" // value
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"quux", // name
  				String.Empty, // prefix
  				"quux", // localName
  				String.Empty, // namespaceURI
  				"quuux" // value
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"notexist", // name
  				String.Empty, // prefix
  				"notexist", // localName
  				String.Empty, // namespaceURI
  				null // value
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"x:foo", // name
  				"x", // prefix
  				"foo", // localName
  				"urn:xfoo", // namespaceURI
  				"x-foo" // value
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"x:bar", // name
  				"x", // prefix
  				"bar", // localName
  				"urn:xfoo", // namespaceURI
  				null // value
  			);
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void ProcessingInstructionBeforeDocumentElement ()
  		{
  			string xml = "<?foo bar?><baz/>";
  			RunTest (xml, new TestMethod (ProcessingInstructionBeforeDocumentElement));
  		}
  
  		public void ProcessingInstructionBeforeDocumentElement (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.ProcessingInstruction, // nodeType
  				0, //depth
  				false, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				"bar", // value
  				0 // attributeCount
  			);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, //depth
  				true, // isEmptyElement
  				"baz", // name
  				String.Empty, // prefix
  				"baz", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void CommentBeforeDocumentElement ()
  		{
  			string xml = "<!--foo--><bar/>";
  			RunTest (xml, new TestMethod (CommentBeforeDocumentElement));
  		}
  
  		public void CommentBeforeDocumentElement (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Comment, // nodeType
  				0, //depth
  				false, // isEmptyElement
  				String.Empty, // name
  				String.Empty, // prefix
  				String.Empty, // localName
  				String.Empty, // namespaceURI
  				"foo", // value
  				0 // attributeCount
  			);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, //depth
  				true, // isEmptyElement
  				"bar", // name
  				String.Empty, // prefix
  				"bar", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void PredefinedEntities ()
  		{
  			string xml = "<foo>&lt;&gt;&amp;&apos;&quot;</foo>";
  			RunTest (xml, new TestMethod (PredefinedEntities));
  		}
  
  		public void PredefinedEntities (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, //depth
  				false, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Text, // nodeType
  				1, //depth
  				false, // isEmptyElement
  				String.Empty, // name
  				String.Empty, // prefix
  				String.Empty, // localName
  				String.Empty, // namespaceURI
  				"<>&'\"", // value
  				0 // attributeCount
  			);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.EndElement, // nodeType
  				0, //depth
  				false, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void CharacterReferences ()
  		{
  			string xml = "<foo>&#70;&#x4F;&#x4f;</foo>";
  			RunTest (xml, new TestMethod (CharacterReferences));
  		}
  
  		public void CharacterReferences (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, //depth
  				false, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Text, // nodeType
  				1, //depth
  				false, // isEmptyElement
  				String.Empty, // name
  				String.Empty, // prefix
  				String.Empty, // localName
  				String.Empty, // namespaceURI
  				"FOO", // value
  				0 // attributeCount
  			);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.EndElement, // nodeType
  				0, //depth
  				false, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void PredefinedEntitiesInAttribute ()
  		{
  			string xml = "<foo bar='&lt;&gt;&amp;&apos;&quot;'/>";
  			RunTest (xml, new TestMethod (PredefinedEntitiesInAttribute ));
  		}
  
  		public void PredefinedEntitiesInAttribute (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, //depth
  				true, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				1 // attributeCount
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"bar", // name
  				String.Empty, // prefix
  				"bar", // localName
  				String.Empty, // namespaceURI
  				"<>&'\"" // value
  			);
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void CharacterReferencesInAttribute ()
  		{
  			string xml = "<foo bar='&#70;&#x4F;&#x4f;'/>";
  			RunTest (xml, new TestMethod (CharacterReferencesInAttribute));
  		}
  
  		public void CharacterReferencesInAttribute (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, //depth
  				true, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				1 // attributeCount
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"bar", // name
  				String.Empty, // prefix
  				"bar", // localName
  				String.Empty, // namespaceURI
  				"FOO" // value
  			);
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void CDATA ()
  		{
  			string xml = "<foo><![CDATA[<>&]]></foo>";
  			RunTest (xml, new TestMethod (CDATA));
  		}
  
  		public void CDATA (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, //depth
  				false, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.CDATA, // nodeType
  				1, //depth
  				false, // isEmptyElement
  				String.Empty, // name
  				String.Empty, // prefix
  				String.Empty, // localName
  				String.Empty, // namespaceURI
  				"<>&", // value
  				0 // attributeCount
  			);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.EndElement, // nodeType
  				0, //depth
  				false, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void EmptyElementInDefaultNamespace ()
  		{
  			string xml = @"<foo xmlns='http://foo/' />";
  			RunTest (xml, new TestMethod (EmptyElementInDefaultNamespace));
  		}
  
  		public void EmptyElementInDefaultNamespace (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, // depth
  				true, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				"http://foo/", // namespaceURI
  				String.Empty, // value
  				1 // attributeCount
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"xmlns", // name
  				String.Empty, // prefix
  				"xmlns", // localName
  				"http://www.w3.org/2000/xmlns/", // namespaceURI
  				"http://foo/" // value
  			);
  
  			Assert.AreEqual ("http://foo/", xmlReader.LookupNamespace (String.Empty));
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void ChildElementInNamespace ()
  		{
  			string xml = @"<foo:bar xmlns:foo='http://foo/'><baz:quux xmlns:baz='http://baz/' /></foo:bar>";
  			RunTest (xml, new TestMethod (ChildElementInNamespace));
  		}
  
  		public void ChildElementInNamespace (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, // depth
  				false, // isEmptyElement
  				"foo:bar", // name
  				"foo", // prefix
  				"bar", // localName
  				"http://foo/", // namespaceURI
  				String.Empty, // value
  				1 // attributeCount
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"xmlns:foo", // name
  				"xmlns", // prefix
  				"foo", // localName
  				"http://www.w3.org/2000/xmlns/", // namespaceURI
  				"http://foo/" // value
  			);
  
  			Assert.AreEqual ("http://foo/", xmlReader.LookupNamespace ("foo"));
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				1, // depth
  				true, // isEmptyElement
  				"baz:quux", // name
  				"baz", // prefix
  				"quux", // localName
  				"http://baz/", // namespaceURI
  				String.Empty, // value
  				1 // attributeCount
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"xmlns:baz", // name
  				"xmlns", // prefix
  				"baz", // localName
  				"http://www.w3.org/2000/xmlns/", // namespaceURI
  				"http://baz/" // value
  			);
  
  			Assert.AreEqual ("http://foo/", xmlReader.LookupNamespace ("foo"));
  			Assert.AreEqual ("http://baz/", xmlReader.LookupNamespace ("baz"));
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.EndElement, // nodeType
  				0, // depth
  				false, // isEmptyElement
  				"foo:bar", // name
  				"foo", // prefix
  				"bar", // localName
  				"http://foo/", // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			Assert.AreEqual ("http://foo/", xmlReader.LookupNamespace ("foo"));
  			Assert.IsNull (xmlReader.LookupNamespace ("baz"));
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void ChildElementInDefaultNamespace ()
  		{
  			string xml = @"<foo:bar xmlns:foo='http://foo/'><baz xmlns='http://baz/' /></foo:bar>";
  			RunTest (xml, new TestMethod (ChildElementInDefaultNamespace));
  		}
  
  		public void ChildElementInDefaultNamespace (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, // depth
  				false, // isEmptyElement
  				"foo:bar", // name
  				"foo", // prefix
  				"bar", // localName
  				"http://foo/", // namespaceURI
  				String.Empty, // value
  				1 // attributeCount
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"xmlns:foo", // name
  				"xmlns", // prefix
  				"foo", // localName
  				"http://www.w3.org/2000/xmlns/", // namespaceURI
  				"http://foo/" // value
  			);
  
  			Assert.AreEqual ("http://foo/", xmlReader.LookupNamespace ("foo"));
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				1, // depth
  				true, // isEmptyElement
  				"baz", // name
  				String.Empty, // prefix
  				"baz", // localName
  				"http://baz/", // namespaceURI
  				String.Empty, // value
  				1 // attributeCount
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"xmlns", // name
  				String.Empty, // prefix
  				"xmlns", // localName
  				"http://www.w3.org/2000/xmlns/", // namespaceURI
  				"http://baz/" // value
  			);
  
  			Assert.AreEqual ("http://foo/", xmlReader.LookupNamespace ("foo"));
  			Assert.AreEqual ("http://baz/", xmlReader.LookupNamespace (String.Empty));
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.EndElement, // nodeType
  				0, // depth
  				false, // isEmptyElement
  				"foo:bar", // name
  				"foo", // prefix
  				"bar", // localName
  				"http://foo/", // namespaceURI
  				String.Empty, // value
  				0 // attributeCount
  			);
  
  			Assert.AreEqual ("http://foo/", xmlReader.LookupNamespace ("foo"));
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void AttributeInNamespace ()
  		{
  			string xml = @"<foo bar:baz='quux' xmlns:bar='http://bar/' />";
  			RunTest (xml, new TestMethod (AttributeInNamespace));
  		}
  
  		public void AttributeInNamespace (XmlReader xmlReader)
  		{
  			AssertStartDocument (xmlReader);
  
  			AssertNode (
  				xmlReader, // xmlReader
  				XmlNodeType.Element, // nodeType
  				0, // depth
  				true, // isEmptyElement
  				"foo", // name
  				String.Empty, // prefix
  				"foo", // localName
  				String.Empty, // namespaceURI
  				String.Empty, // value
  				2 // attributeCount
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"bar:baz", // name
  				"bar", // prefix
  				"baz", // localName
  				"http://bar/", // namespaceURI
  				"quux" // value
  			);
  
  			AssertAttribute (
  				xmlReader, // xmlReader
  				"xmlns:bar", // name
  				"xmlns", // prefix
  				"bar", // localName
  				"http://www.w3.org/2000/xmlns/", // namespaceURI
  				"http://bar/" // value
  			);
  
  			Assert.AreEqual ("http://bar/", xmlReader.LookupNamespace ("bar"));
  
  			AssertEndDocument (xmlReader);
  		}
  
  		[Test]
  		public void MoveToElementFromAttribute ()
  		{
  			string xml = @"<foo bar=""baz"" />";
  			RunTest (xml, new TestMethod (MoveToElementFromAttribute));
  		}
  
  		public void MoveToElementFromAttribute (XmlReader xmlReader)
  		{
  			Assert.IsTrue (xmlReader.Read ());
  			Assert.AreEqual (XmlNodeType.Element, xmlReader.NodeType);
  
gt: 			Assert.IsTrue (xmlReader.MoveToFirstAttribute ());