private static void PopulateElement(XmlReader reader, MyXmlElement into)
        {
            into.Name = reader.Name;

            int attrCount = reader.AttributeCount;

            for (int i = 0; i < attrCount; i++)
            {
                reader.MoveToNextAttribute();

                into.Attributes.Add(new MyXmlAttribute()
                {
                    Name  = reader.Name,
                    Value = reader.Value
                });
            }
        }
        private static void AssertXmlElement(MyXmlElement expected, MyXmlElement actual)
        {
            // If both null, good, done
            if (expected == null && actual == null)
                return;

            // If one is null and other isn't, bad
            if (expected == null)
                Assert.Fail("Expected XML element was null, while actual was initialized");

            if (actual == null)
                Assert.Fail("Actual XML element was null, while expected was initialized");

            // If name doesn't match
            Assert.AreEqual(expected.Name, actual.Name, "Element names did not match.");

            // If attribute count doesn't match
            Assert.AreEqual(expected.Attributes.Count, actual.Attributes.Count, $"Different number of attributes on <{expected.Name}>\n\nExpected: " + AttributesToString(expected.Attributes) + "\nActual: " + AttributesToString(actual.Attributes));

            // Make sure attributes match (order does NOT matter)
            foreach (MyXmlAttribute expectedAttr in expected.Attributes)
            {
                var actualAttr = actual.Attributes.FirstOrDefault(i => i.Name.Equals(expectedAttr.Name));

                // If didn't find the attribute
                if (actualAttr == null)
                    Assert.Fail("Expected element to have attribute " + expectedAttr.Name + " but it didn't.");

                // Make sure value matches
                Assert.AreEqual(expectedAttr.Value, actualAttr.Value, $@"Attribute values for ""{expectedAttr.Name}"" didn't match.");
            }

            // Make sure children elements match (order DOES matter)

            // Obtain the child elements (ignore any comments, w
            MyXmlElement[] expectedChildren = expected.ChildNodes.ToArray();
            MyXmlElement[] actualChildren = actual.ChildNodes.ToArray();

            Assert.AreEqual(expectedChildren.Length, actualChildren.Length, "Number of child elements did not match.");

            // Compare elements
            for (int i = 0; i < expectedChildren.Length; i++)
            {
                AssertXmlElement(expectedChildren[i], actualChildren[i]);
            }
        }
        private static void ParseXml(XmlReader reader, MyXmlElement intoElement)
        {
            if (!reader.Read())
                return;

            while (true)
            {
                switch (reader.NodeType)
                {
                    // Found child
                    case XmlNodeType.Element:
                    case XmlNodeType.Text:
                        MyXmlElement child = new MyXmlElement();
                        PopulateElement(reader, child);
                        ParseXml(reader, child);
                        intoElement.ChildNodes.Add(child);
                        break;

                    // All done
                    case XmlNodeType.EndElement:
                        return;
                }

                if (!reader.Read())
                    return;
            }
        }
        private static void PopulateElement(XmlReader reader, MyXmlElement into)
        {
            into.Name = reader.Name;

            int attrCount = reader.AttributeCount;
            for (int i = 0; i < attrCount; i++)
            {
                reader.MoveToNextAttribute();

                into.Attributes.Add(new MyXmlAttribute()
                {
                    Name = reader.Name,
                    Value = reader.Value
                });
            }
        }
        private static MyXmlElement ParseXml(string xml)
        {
            XmlReader reader = XmlReader.Create(new StringReader(xml));

            MyXmlElement documentElement = new MyXmlElement();

            reader.Read();

            while (true)
            {
                if (reader.ReadState == ReadState.EndOfFile)
                    break;

                if (reader.ReadState == ReadState.Error)
                    throw new Exception("ReadState was Error");

                if (reader.NodeType == XmlNodeType.Element)
                {
                    PopulateElement(reader, documentElement);
                    ParseXml(reader, documentElement);
                    break;
                }

                reader.Read();
            }

            return documentElement;
        }