public override void LoadData (XmlNode node)
		{
			if (node == null)
				throw new ArgumentNullException ("node");

			if (node.Name != "parameter")
				throw new ArgumentException ("Expecting <parameter>");

			name = node.Attributes["name"].Value;
			type = node.Attributes["type"].Value;
			attrib = node.Attributes["attrib"].Value;
			if (node.Attributes ["direction"] != null)
				direction = node.Attributes["direction"].Value;
			if (node.Attributes["unsafe"] != null)
				isUnsafe = bool.Parse (node.Attributes["unsafe"].Value);
			if (node.Attributes["optional"] != null)
				isOptional = bool.Parse (node.Attributes["optional"].Value);
			if (node.Attributes["defaultValue"] != null)
				defaultValue = node.Attributes["defaultValue"].Value;

			XmlNode child = node.FirstChild;
			if (child == null)
				return;

			if (child.Name == "attributes") {
				attributes = new XMLAttributes ();
				attributes.LoadData (child);
				child = child.NextSibling;
			}
		}
		public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
		{
			this.document = doc;

			XMLParameter oparm = (XMLParameter) other;

			if (name != oparm.name)
				AddWarning (parent, "Parameter name is wrong: {0} != {1}", name, oparm.name);

			if (type != oparm.type)
				AddWarning (parent, "Parameter type is wrong: {0} != {1}", type, oparm.type);
			
			if (attrib != oparm.attrib)
				AddWarning (parent, "Parameter attributes wrong: {0} != {1}", attrib, oparm.attrib);

			if (direction != oparm.direction)
				AddWarning (parent, "Parameter direction wrong: {0} != {1}", direction, oparm.direction);

			if (isUnsafe != oparm.isUnsafe)
				AddWarning (parent, "Parameter unsafe wrong: {0} != {1}", isUnsafe, oparm.isUnsafe);

			if (isOptional != oparm.isOptional)
				AddWarning (parent, "Parameter optional wrong: {0} != {1}", isOptional, oparm.isOptional);

			if (defaultValue != oparm.defaultValue)
				AddWarning (parent, "Parameter default value wrong: {0} != {1}", (defaultValue == null) ? "(no default value)" : defaultValue, (oparm.defaultValue == null) ? "(no default value)" : oparm.defaultValue);

			if (attributes != null || oparm.attributes != null) {
				if (attributes == null)
					attributes = new XMLAttributes ();

				attributes.CompareTo (doc, parent, oparm.attributes);
				counters.AddPartialToPartial (attributes.Counters);
				if (oparm.attributes != null && oparm.attributes.IsTodo) {
					counters.Todo++;
					counters.TodoTotal++;
					counters.ErrorTotal++;
					AddAttribute (parent, "error", "todo");
					if (oparm.attributes.Comment != null)
						AddAttribute (parent, "comment", oparm.attributes.Comment);
				}
			}
		}
		public override void CompareTo (XmlDocument doc, XmlNode parent, object other)
		{
			this.document = doc;
			XMLClass oclass = (XMLClass) other;

			if (attributes != null || oclass.attributes != null) {
				if (attributes == null)
					attributes = new XMLAttributes ();

				attributes.CompareTo (doc, parent, oclass.attributes);
				counters.AddPartialToPartial (attributes.Counters);
				if (oclass.attributes != null && oclass.attributes.IsTodo) {
					counters.Todo++;
					counters.TodoTotal++;
					counters.ErrorTotal++;
					AddAttribute (parent, "error", "todo");
					if (oclass.attributes.Comment != null)
						AddAttribute (parent, "comment", oclass.attributes.Comment);
				}
			}

			if (type != oclass.type)
				AddWarning (parent, "Class type is wrong: {0} != {1}", type, oclass.type);

			if (baseName != oclass.baseName)
				AddWarning (parent, "Base class is wrong: {0} != {1}", baseName, oclass.baseName);

			if (isAbstract != oclass.isAbstract || isSealed != oclass.isSealed) {
				if ((isAbstract && isSealed) || (oclass.isAbstract && oclass.isSealed))
					AddWarning (parent, "Should {0}be static", (isAbstract && isSealed) ? "" : "not ");
				else if (isAbstract != oclass.isAbstract)
					AddWarning (parent, "Should {0}be abstract", isAbstract ? "" : "not ");
				else if (isSealed != oclass.isSealed)
					AddWarning (parent, "Should {0}be sealed", isSealed ? "" : "not ");
			}

			if (isSerializable != oclass.isSerializable)
				AddWarning (parent, "Should {0}be serializable", isSerializable ? "" : "not ");

			if (charSet != oclass.charSet)
				AddWarning (parent, "CharSet is wrong: {0} != {1}", charSet, oclass.charSet);

			if (layout != oclass.layout)
				AddWarning (parent, "Layout is wrong: {0} != {1}", layout, oclass.layout);

			if (interfaces != null || oclass.interfaces != null) {
				if (interfaces == null)
					interfaces = new XMLInterfaces ();

				interfaces.CompareTo (doc, parent, oclass.interfaces);
				counters.AddPartialToPartial (interfaces.Counters);
			}

			if (genericConstraints != null || oclass.genericConstraints != null) {
				if (genericConstraints == null)
					genericConstraints = new XMLGenericTypeConstraints ();

				genericConstraints.CompareTo (doc, parent, oclass.genericConstraints);
				counters.AddPartialToPartial (genericConstraints.Counters);
			}

			if (fields != null || oclass.fields != null) {
				if (fields == null)
					fields = new XMLFields ();

				fields.CompareTo (doc, parent, oclass.fields);
				counters.AddPartialToPartial (fields.Counters);
			}

			if (constructors != null || oclass.constructors != null) {
				if (constructors == null)
					constructors = new XMLConstructors ();

				constructors.CompareTo (doc, parent, oclass.constructors);
				counters.AddPartialToPartial (constructors.Counters);
			}

			if (properties != null || oclass.properties != null) {
				if (properties == null)
					properties = new XMLProperties ();

				properties.CompareTo (doc, parent, oclass.properties);
				counters.AddPartialToPartial (properties.Counters);
			}

			if (events != null || oclass.events != null) {
				if (events == null)
					events = new XMLEvents ();

				events.CompareTo (doc, parent, oclass.events);
				counters.AddPartialToPartial (events.Counters);
			}

			if (methods != null || oclass.methods != null) {
				if (methods == null)
					methods = new XMLMethods ();

				methods.CompareTo (doc, parent, oclass.methods);
				counters.AddPartialToPartial (methods.Counters);
			}

			if (nested != null || oclass.nested != null) {
				XmlNode n = doc.CreateElement ("classes", null);
				parent.AppendChild (n);
				CompareTypes (n, oclass.nested);
			}

			AddCountersAttributes (parent);
		}
		public override void LoadData (XmlNode node)
		{
			if (node == null)
				throw new ArgumentNullException ("node");

			name = node.Attributes ["name"].Value;
			type = node.Attributes  ["type"].Value;
			XmlAttribute xatt = node.Attributes ["base"];
			if (xatt != null)
				baseName = xatt.Value;

			xatt = node.Attributes ["sealed"];
			isSealed = (xatt != null && xatt.Value == "true");

			xatt = node.Attributes ["abstract"];
			isAbstract = (xatt != null && xatt.Value == "true");

			xatt = node.Attributes["serializable"];
			isSerializable = (xatt != null && xatt.Value == "true");

			xatt = node.Attributes["charset"];
			if (xatt != null)
				charSet = xatt.Value;

			xatt = node.Attributes["layout"];
			if (xatt != null)
				layout = xatt.Value;

			XmlNode child = node.FirstChild;
			if (child == null) {
				// Console.Error.WriteLine ("Empty class {0} {1}", name, type);
				return;
			}
				
			if (child.Name == "attributes") {
				attributes = new XMLAttributes ();
				attributes.LoadData (child);
				child = child.NextSibling;
			}

			if (child != null && child.Name == "interfaces") {
				interfaces = new XMLInterfaces ();
				interfaces.LoadData (child);
				child = child.NextSibling;
			}

			if (child != null && child.Name == "generic-type-constraints") {
				genericConstraints = new XMLGenericTypeConstraints ();
				genericConstraints.LoadData (child);
				child = child.NextSibling;
			}

			if (child != null && child.Name == "fields") {
				fields = new XMLFields ();
				fields.LoadData (child);
				child = child.NextSibling;
			}

			if (child != null && child.Name == "constructors") {
				constructors = new XMLConstructors ();
				constructors.LoadData (child);
				child = child.NextSibling;
			}

			if (child != null && child.Name == "properties") {
				properties = new XMLProperties ();
				properties.LoadData (child);
				child = child.NextSibling;
			}

			if (child != null && child.Name == "events") {
				events = new XMLEvents ();
				events.LoadData (child);
				child = child.NextSibling;
			}

			if (child != null && child.Name == "methods") {
				methods = new XMLMethods ();
				methods.LoadData (child);
				child = child.NextSibling;
			}

			if (child != null && child.Name == "generic-parameters") {
				// HACK: ignore this tag as it doesn't seem to
				// add any value when checking for differences
				return;
			}

			if (child == null)
				return;

			if (child.Name != "classes") {
				Console.WriteLine ("name: {0} type: {1} {2}", name, type, child.NodeType);
				throw new FormatException ("Expecting <classes>. Got <" + child.Name + ">");
			}

			nested = (XMLClass []) LoadRecursive (child.ChildNodes, typeof (XMLClass));
		}
		public override void LoadData (XmlNode node)
		{
			if (node == null)
				throw new ArgumentNullException ("node");

			name = node.Attributes ["name"].Value;
			version = node.Attributes  ["version"].Value;
			XmlNode atts = node.FirstChild;
			attributes = new XMLAttributes ();
			if (atts.Name == "attributes") {
				attributes.LoadData (atts);
				atts = atts.NextSibling;
			}

			if (atts == null || atts.Name != "namespaces") {
				Console.Error.WriteLine ("Warning: no namespaces found!");
				return;
			}

			namespaces = (XMLNamespace []) LoadRecursive (atts.ChildNodes, typeof (XMLNamespace));
		}
		protected override void CompareToInner (string name, XmlNode parent, XMLNameGroup other)
		{
			base.CompareToInner (name, parent, other);
			XMLMember mb = other as XMLMember;
			XMLAttributes att = null;
			XMLAttributes oatt = null;
			if (attributeMap != null)
				att = attributeMap [name] as XMLAttributes;

			if (mb != null && mb.attributeMap != null)
				oatt = mb.attributeMap [name] as XMLAttributes;

			if (att != null || oatt != null) {
				if (att == null)
					att = new XMLAttributes ();

				att.CompareTo (document, parent, oatt);
				counters.AddPartialToPartial(att.Counters);
				if (oatt != null && oatt.IsTodo) {
					counters.Todo++;
					counters.ErrorTotal++;
					AddAttribute (parent, "error", "todo");
					if (oatt.Comment != null)
						AddAttribute (parent, "comment", oatt.Comment);
				}
			}

			XMLMember member = (XMLMember) other;
			string acc = access [name] as string;
			if (acc == null)
				return;

			string oacc = null;
			if (member.access != null)
				oacc = member.access [name] as string;

			string accName = ConvertToString (Int32.Parse (acc));
			string oaccName = "";
			if (oacc != null)
				oaccName = ConvertToString (Int32.Parse (oacc));

			if (accName != oaccName)
				AddWarning (parent, "Incorrect attributes: '{0}' != '{1}'", accName, oaccName);
		}
		protected override void LoadExtraData (string name, XmlNode node)
		{
			XmlAttribute xatt = node.Attributes ["attrib"];
			if (xatt != null)
				access [name] = xatt.Value;
			
			XmlNode orig = node;

			node = node.FirstChild;
			while (node != null) {
				if (node != null && node.Name == "attributes") {
					XMLAttributes a = new XMLAttributes ();
					a.LoadData (node);
					if (attributeMap == null)
						attributeMap = new Hashtable ();

					attributeMap [name] = a;
					break;
				}
				node = node.NextSibling;
			}

			base.LoadExtraData (name, orig);
		}