2010-07-12 Astushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml.Serialization / SerializationCodeGenerator.cs
index c4fe8d29a4f672d315aaea750ef2e5f342dabb6c..4e43a4f2a87f1ad0eeefbc2dc07c7af05621897c 100644 (file)
@@ -1,10 +1,12 @@
 //
 // System.Xml.Serialization.SerializationCodeGenerator.cs: 
 //
-// Author:
+// Authors:
 //   Lluis Sanchez Gual (lluis@ximian.com)
+//   Atsushi Enomoto (atsushi@ximian.com)
 //
 // (C) 2002, 2003 Ximian, Inc.  http://www.ximian.com
+// Copyright (C) 2006 Novell, Inc.
 //
 
 //
@@ -33,6 +35,9 @@ using System.Reflection;
 using System.Xml.Serialization;
 using System.Collections;
 using System.Globalization;
+using System.Text;
+
+using HookDir = System.Xml.Serialization.XmlMappingAccess;
 
 namespace System.Xml.Serialization
 {
@@ -148,6 +153,7 @@ namespace System.Xml.Serialization
                        _writer = writer;
                        _results = new GenerationResult [_xmlMaps.Length];
                        
+                       WriteLine ("// It is automatically generated");
                        WriteLine ("using System;");
                        WriteLine ("using System.Xml;");
                        WriteLine ("using System.Xml.Schema;");
@@ -163,12 +169,16 @@ namespace System.Xml.Serialization
                        
                        string readerClassName = null;
                        string writerClassName = null;
+                       string baseClassName = null;
+                       string implClassName = null;
                        string namspace = null;
                        
                        if (_config != null)
                        {
                                readerClassName = _config.ReaderClassName;
                                writerClassName = _config.WriterClassName;
+                               baseClassName = _config.BaseSerializerClassName;
+                               implClassName = _config.ImplementationClassName;
                                namspace = _config.Namespace;
                        }
 
@@ -177,10 +187,14 @@ namespace System.Xml.Serialization
 
                        if (writerClassName == null || writerClassName.Length == 0)
                                writerClassName = "GeneratedWriter";
-                               
+                       if (baseClassName == null || baseClassName.Length == 0)
+                               baseClassName = "BaseXmlSerializer";
+                       if (implClassName == null || implClassName.Length == 0)
+                               implClassName = "XmlSerializerContract";
                        readerClassName = GetUniqueClassName (readerClassName);
                        writerClassName = GetUniqueClassName (writerClassName);
-                       
+                       baseClassName = GetUniqueClassName (baseClassName);
+                       implClassName = GetUniqueClassName (implClassName);
                        Hashtable mapsByNamespace = new Hashtable ();
                        Hashtable generatedMaps = new Hashtable ();
                        
@@ -201,11 +215,13 @@ namespace System.Xml.Serialization
                                generatedMaps [_typeMap] = _result;
                                
                                string typeName;
-                               if (_typeMap is XmlTypeMapping) typeName = ((XmlTypeMapping)_typeMap).TypeName;
+                               if (_typeMap is XmlTypeMapping) typeName = CodeIdentifier.MakeValid (((XmlTypeMapping)_typeMap).TypeData.CSharpName);
                                else typeName = ((XmlMembersMapping)_typeMap).ElementName;
                                
                                _result.ReaderClassName = readerClassName;
                                _result.WriterClassName = writerClassName;
+                               _result.BaseSerializerClassName = baseClassName;
+                               _result.ImplementationClassName = implClassName;
 
                                if (namspace == null || namspace.Length == 0)
                                        _result.Namespace = "Mono.GeneratedSerializers." + _typeMap.Format;
@@ -268,6 +284,11 @@ namespace System.Xml.Serialization
                        }
                }
 
+               static string ToCSharpFullName (Type type)
+               {
+                       return TypeData.ToCSharpName (type, true);
+               }
+
                #region Writer Generation
                
                //*******************************************************
@@ -283,10 +304,11 @@ namespace System.Xml.Serialization
                        
                        GenerationResult main = (GenerationResult) generatedMaps[0];
                        
-                       string baseSerializerName = GetUniqueClassName ("BaseXmlSerializer");
+                       string baseSerializerName = main.BaseSerializerClassName;
+                       string access_mod = (_config == null || !_config.GenerateAsInternal) ? "public" : "internal";
                        
                        WriteLine ("");
-                       WriteLine ("public class " + baseSerializerName + " : System.Xml.Serialization.XmlSerializer");
+                       WriteLine (access_mod + " class " + baseSerializerName + " : System.Xml.Serialization.XmlSerializer");
                        WriteLineInd ("{");
                        WriteLineInd ("protected override System.Xml.Serialization.XmlSerializationReader CreateReader () {");
                        WriteLine ("return new " + main.ReaderClassName + " ();");
@@ -311,7 +333,7 @@ namespace System.Xml.Serialization
                        {
                                res.SerializerClassName = GetUniqueClassName (res.Mapping.ElementName + "Serializer");
                                
-                               WriteLine ("public sealed class " + res.SerializerClassName + " : " + baseSerializerName);
+                               WriteLine (access_mod + " sealed class " + res.SerializerClassName + " : " + baseSerializerName);
                                WriteLineInd ("{");
                                WriteLineInd ("protected override void Serialize (object obj, System.Xml.Serialization.XmlSerializationWriter writer) {");
                                WriteLine ("((" + res.WriterClassName + ")writer)." + res.WriteMethodName + "(obj);");
@@ -326,7 +348,8 @@ namespace System.Xml.Serialization
                                WriteLine ("");
                        }
 
-                       WriteLine ("public class XmlSerializerContract : System.Xml.Serialization.IXmlSerializerImplementation");
+                       WriteLine ("#if !TARGET_JVM"); // does it make sense? ;-)
+                       WriteLine (access_mod + " class " + main.ImplementationClassName + " : System.Xml.Serialization.XmlSerializerImplementation");
                        WriteLineInd ("{");
                        
                        WriteLine ("System.Collections.Hashtable readMethods = null;");
@@ -334,23 +357,23 @@ namespace System.Xml.Serialization
                        WriteLine ("System.Collections.Hashtable typedSerializers = null;");
                        WriteLine ("");
                
-                       WriteLineInd ("public System.Xml.Serialization.XmlSerializationReader Reader {");
+                       WriteLineInd ("public override System.Xml.Serialization.XmlSerializationReader Reader {");
                        WriteLineInd ("get {");
                        WriteLine ("return new " + main.ReaderClassName + "();");
                        WriteLineUni ("}");
                        WriteLineUni ("}");
                        WriteLine ("");
                        
-                       WriteLineInd ("public System.Xml.Serialization.XmlSerializationWriter Writer {");
+                       WriteLineInd ("public override System.Xml.Serialization.XmlSerializationWriter Writer {");
                        WriteLineInd ("get {");
                        WriteLine ("return new " + main.WriterClassName + "();");
                        WriteLineUni ("}");
                        WriteLineUni ("}");
                        WriteLine ("");
                        
-                       WriteLineInd ("public System.Collections.Hashtable ReadMethods {");
+                       WriteLineInd ("public override System.Collections.Hashtable ReadMethods {");
                        WriteLineInd ("get {");
-                       WriteLineInd ("lock (System.Xml.Serialization.XmlSerializationGeneratedCode.InternalSyncObject) {");
+                       WriteLineInd ("lock (this) {");
                        WriteLineInd ("if (readMethods == null) {");
                        WriteLine ("readMethods = new System.Collections.Hashtable ();");
                        foreach (GenerationResult res in generatedMaps)
@@ -362,9 +385,9 @@ namespace System.Xml.Serialization
                        WriteLineUni ("}");
                        WriteLine ("");
                        
-                       WriteLineInd ("public System.Collections.Hashtable WriteMethods {");
+                       WriteLineInd ("public override System.Collections.Hashtable WriteMethods {");
                        WriteLineInd ("get {");
-                       WriteLineInd ("lock (System.Xml.Serialization.XmlSerializationGeneratedCode.InternalSyncObject) {");
+                       WriteLineInd ("lock (this) {");
                        WriteLineInd ("if (writeMethods == null) {");
                        WriteLine ("writeMethods = new System.Collections.Hashtable ();");
                        foreach (GenerationResult res in generatedMaps)
@@ -376,9 +399,9 @@ namespace System.Xml.Serialization
                        WriteLineUni ("}");
                        WriteLine ("");
                        
-                       WriteLineInd ("public System.Collections.Hashtable TypedSerializers {");
+                       WriteLineInd ("public override System.Collections.Hashtable TypedSerializers {");
                        WriteLineInd ("get {");
-                       WriteLineInd ("lock (System.Xml.Serialization.XmlSerializationGeneratedCode.InternalSyncObject) {");
+                       WriteLineInd ("lock (this) {");
                        WriteLineInd ("if (typedSerializers == null) {");
                        WriteLine ("typedSerializers = new System.Collections.Hashtable ();");
                        foreach (GenerationResult res in generatedMaps)
@@ -388,17 +411,34 @@ namespace System.Xml.Serialization
                        WriteLineUni ("}");
                        WriteLineUni ("}");
                        WriteLineUni ("}");
+                       WriteLine ("");
+
+                       WriteLine ("public override XmlSerializer GetSerializer (Type type)");
+                       WriteLineInd ("{");
+                       WriteLine ("switch (type.FullName) {");
+                       foreach (GenerationResult res in generatedMaps) {
+                               if (res.Mapping is XmlTypeMapping) {
+                                       WriteLineInd ("case \"" + ((XmlTypeMapping) res.Mapping).TypeData.CSharpFullName + "\":");
+                                       WriteLine ("return (XmlSerializer) TypedSerializers [\"" + res.Mapping.GetKey () + "\"];");
+                                       WriteLineUni ("");
+                               }
+                       }
+                       WriteLine ("}");
+                       WriteLine ("return base.GetSerializer (type);");
+                       WriteLineUni ("}");
+                       WriteLine ("");
                        
-                       WriteLineInd ("public bool CanSerialize (System.Type type) {");
+                       WriteLineInd ("public override bool CanSerialize (System.Type type) {");
                        foreach (GenerationResult res in generatedMaps) {
                                if (res.Mapping is XmlTypeMapping)
-                                       WriteLine ("if (type == typeof(" + (res.Mapping as XmlTypeMapping).TypeData.FullTypeName +  ")) return true;");
+                                       WriteLine ("if (type == typeof(" + (res.Mapping as XmlTypeMapping).TypeData.CSharpFullName +  ")) return true;");
                        }
                        WriteLine ("return false;");
                        WriteLineUni ("}");
                        
                        WriteLineUni ("}");
                        WriteLine ("");
+                       WriteLine ("#endif");
                }
 #endif
 
@@ -419,6 +459,12 @@ namespace System.Xml.Serialization
                                WriteLine ("internal class " + writerClassName + " : XmlSerializationWriter");
                        WriteLineInd ("{");
                        WriteLine ("const string xmlNamespace = \"http://www.w3.org/2000/xmlns/\";");
+                       // ToBinHexString() is not public, so use reflection here.
+                       WriteLine ("static readonly System.Reflection.MethodInfo toBinHexStringMethod = typeof (XmlConvert).GetMethod (\"ToBinHexString\", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, new Type [] {typeof (byte [])}, null);");
+                       WriteLine ("static string ToBinHexString (byte [] input)");
+                       WriteLineInd ("{");
+                       WriteLine ("return input == null ? null : (string) toBinHexStringMethod.Invoke (null, new object [] {input});");
+                       WriteLineUni ("}");
                        
                        for (int n=0; n<maps.Count; n++)
                        {
@@ -534,13 +580,13 @@ namespace System.Xml.Serialization
                                WriteLine (string.Empty);
                        }
 
-                       WriteLine ("string " + GetGetEnumValueName (map) + " (" + map.TypeFullName + " val)");
+                       WriteLine ("string " + GetGetEnumValueName (map) + " (" + map.TypeData.CSharpFullName + " val)");
                        WriteLineInd ("{");
 
 
                        WriteLineInd ("switch (val) {");
                        for (int i = 0; i < emap.EnumNames.Length; i++)
-                               WriteLine ("case " + map.TypeFullName + "." + emap.EnumNames[i] + ": return " + GetLiteral (emap.XmlNames[i]) + ";");
+                               WriteLine ("case " + map.TypeData.CSharpFullName + ".@" + emap.EnumNames[i] + ": return " + GetLiteral (emap.XmlNames[i]) + ";");
 
                        if (emap.IsFlags) {
                                WriteLineInd ("default:");
@@ -549,14 +595,14 @@ namespace System.Xml.Serialization
                                Write ("return FromEnum ((long) val, " + xmlNamesArray + ", " + valuesArray);
 #if NET_2_0
                                _writer.Write (", typeof (");
-                               _writer.Write (map.TypeFullName);
+                               _writer.Write (map.TypeData.CSharpFullName);
                                _writer.Write (").FullName");
 #endif
                                _writer.Write (')'); // close FromEnum method call
                                WriteUni (";"); // end statement
                        } else {
 #if NET_2_0
-                               WriteLine ("default: throw CreateInvalidEnumValueException ((long) val, typeof (" + map.TypeFullName + ").FullName);");
+                               WriteLine ("default: throw CreateInvalidEnumValueException ((long) val, typeof (" + map.TypeData.CSharpFullName + ").FullName);");
 #else
                                WriteLine ("default: return ((long)val).ToString(CultureInfo.InvariantCulture);");
 #endif
@@ -570,16 +616,14 @@ namespace System.Xml.Serialization
                
                void GenerateWriteObject (XmlTypeMapping typeMap)
                {
-                       WriteLine ("void " + GetWriteObjectName (typeMap) + " (" + typeMap.TypeFullName + " ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)");
+                       WriteLine ("void " + GetWriteObjectName (typeMap) + " (" + typeMap.TypeData.CSharpFullName + " ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem)");
                        WriteLineInd ("{");
                        
                        PushHookContext ();
                        
-                       SetHookVar ("$TYPE", typeMap.TypeName);
-                       SetHookVar ("$FULLTYPE", typeMap.TypeFullName);
+                       SetHookVar ("$TYPE", typeMap.TypeData.CSharpName);
+                       SetHookVar ("$FULLTYPE", typeMap.TypeData.CSharpFullName);
                        SetHookVar ("$OBJECT", "ob");
-                       SetHookVar ("$ELEMENT", "element");
-                       SetHookVar ("$NAMESPACE", "namesp");
                        SetHookVar ("$NULLABLE", "isNullable");
 
                        if (GenerateWriteHook (HookType.type, typeMap.TypeData.Type))
@@ -634,22 +678,29 @@ namespace System.Xml.Serialization
                        ArrayList types = typeMap.DerivedTypes;
                        
                        WriteLine ("System.Type type = ob.GetType ();");
-                       WriteLine ("if (type == typeof(" + typeMap.TypeFullName + "))");
+                       WriteLine ("if (type == typeof(" + typeMap.TypeData.CSharpFullName + "))");
                        WriteLine ("{ }");
                                
                        for (int n=0; n<types.Count; n++)
                        {
                                XmlTypeMapping map = (XmlTypeMapping)types[n];
                                
-                               WriteLineInd ("else if (type == typeof(" + map.TypeFullName + ")) { ");
-                               WriteLine (GetWriteObjectName (map) + "((" + map.TypeFullName + ")ob, element, namesp, isNullable, true, writeWrappingElem);");
+                               WriteLineInd ("else if (type == typeof(" + map.TypeData.CSharpFullName + ")) { ");
+                               WriteLine (GetWriteObjectName (map) + "((" + map.TypeData.CSharpFullName + ")ob, element, namesp, isNullable, true, writeWrappingElem);");
                                WriteLine ("return;");
                                WriteLineUni ("}");
                        }
                        
                        if (typeMap.TypeData.Type == typeof (object)) {
                                WriteLineInd ("else {");
-                               WriteLine ("WriteTypedPrimitive (element, namesp, ob, true);");
+                               WriteLineInd ("if (ob.GetType().IsArray && typeof(XmlNode).IsAssignableFrom(ob.GetType().GetElementType())) {");
+                               WriteLine ("Writer.WriteStartElement (" + GetLiteral (typeMap.ElementName) + ", " + GetLiteral (typeMap.Namespace) + ");");
+                               WriteLineInd ("foreach (XmlNode node in (System.Collections.IEnumerable) ob)");
+                               WriteLineUni ("node.WriteTo (Writer);");
+                               WriteLineUni ("Writer.WriteEndElement ();");
+                               WriteLine ("}");
+                               WriteLineInd ("else");
+                               WriteLineUni ("WriteTypedPrimitive (element, namesp, ob, true);");
                                WriteLine ("return;");
                                WriteLineUni ("}");
                        }
@@ -737,7 +788,7 @@ namespace System.Xml.Serialization
                                                
                                                if (cond != null) WriteLineInd ("if (" + cond + ") {");
                                                
-                                               string strVal = GenerateGetStringValue (attr.MappedType, attr.TypeData, val);
+                                               string strVal = GenerateGetStringValue (attr.MappedType, attr.TypeData, val, false);
                                                WriteLine ("WriteAttribute (" + GetLiteral(attr.AttributeName) + ", " + GetLiteral(attr.Namespace) + ", " + strVal + ");");
        
                                                if (cond != null) WriteLineUni ("}");
@@ -812,7 +863,7 @@ namespace System.Xml.Serialization
                                                                bool first = true;
                                                                foreach (XmlTypeMapElementInfo elem in member.ElementInfo)
                                                                {
-                                                                       WriteLineInd ((first?"":"else ") + "if (" + memberValue + " is " + elem.TypeData.FullTypeName + ") {");
+                                                                       WriteLineInd ((first?"":"else ") + "if (" + memberValue + " is " + elem.TypeData.CSharpFullName + ") {");
                                                                        GenerateWriteMemberElement (elem, GetCast(elem.TypeData, member.TypeData, memberValue));
                                                                        WriteLineUni ("}");
                                                                        first = false;
@@ -890,7 +941,7 @@ namespace System.Xml.Serialization
                                        break;
 
                                case SchemaTypes.XmlSerializable:
-                                       WriteMetCall ("WriteSerializable", memberValue, GetLiteral(elem.ElementName), GetLiteral(elem.Namespace), GetLiteral(elem.IsNullable));
+                                       WriteMetCall ("WriteSerializable",  "(" + ToCSharpFullName (elem.MappedType.TypeData.Type) + ") " + memberValue, GetLiteral(elem.ElementName), GetLiteral(elem.Namespace), GetLiteral(elem.IsNullable));
                                        break;
 
                                default:
@@ -920,15 +971,19 @@ namespace System.Xml.Serialization
                void GenerateWriteAnyElementContent (XmlTypeMapMemberAnyElement member, string memberValue)
                {
                        bool singleElement = (member.TypeData.Type == typeof (XmlElement));
-                       string var;
+                       string var, var2;
                        
+                       var2 = GetObTempVar ();
                        if (singleElement)
                                var = memberValue;
                        else {
                                var = GetObTempVar ();
-                               WriteLineInd ("foreach (XmlNode " + var + " in " + memberValue + ") {");
+                               WriteLineInd ("foreach (object " + var2 + " in " + memberValue + ") {");
                        }
-                       
+                       WriteLine ("XmlNode " + var + " = " + var2 + " as XmlNode;");
+                       WriteLine ("if (" + var + " == null && " + var2 + "!= null) throw new InvalidOperationException (\"A member with XmlAnyElementAttribute can only serialize and deserialize certain XmlNode types.");
+                       WriteLineUni ("}");
+
                        string elem = GetObTempVar ();
                        WriteLine ("XmlNode " + elem + " = " + var + ";");
                        WriteLine ("if (" + elem + " is XmlElement) {");
@@ -936,7 +991,7 @@ namespace System.Xml.Serialization
                        if (!member.IsDefaultAny) {
                                for (int n=0; n<member.ElementInfo.Count; n++) {
                                        XmlTypeMapElementInfo info = (XmlTypeMapElementInfo)member.ElementInfo[n];
-                                       string txt = "(" + elem + ".Name == " + GetLiteral(info.ElementName) + " && " + elem + ".NamespaceURI == " + GetLiteral(info.Namespace) + ")";
+                                       string txt = "(" + elem + ".LocalName == " + GetLiteral(info.ElementName) + " && " + elem + ".NamespaceURI == " + GetLiteral(info.Namespace) + ")";
                                        if (n == member.ElementInfo.Count-1) txt += ") {";
                                        if (n == 0) WriteLineInd ("if (" + txt);
                                        else WriteLine ("|| " + txt);
@@ -963,7 +1018,7 @@ namespace System.Xml.Serialization
 
                void GenerateWritePrimitiveElement (XmlTypeMapping typeMap, string ob)
                {
-                       string strVal = GenerateGetStringValue (typeMap, typeMap.TypeData, ob);
+                       string strVal = GenerateGetStringValue (typeMap, typeMap.TypeData, ob, false);
                        WriteLine ("Writer.WriteString (" + strVal + ");");
                }
 
@@ -973,7 +1028,7 @@ namespace System.Xml.Serialization
                        WriteLine ("Writer.WriteString (" + strVal + ");");
                }
 
-               string GenerateGetStringValue (XmlTypeMapping typeMap, TypeData type, string value)
+               string GenerateGetStringValue (XmlTypeMapping typeMap, TypeData type, string value, bool isNullable)
                {
                        if (type.SchemaType == SchemaTypes.Array) {
                                string str = GetStrTempVar ();
@@ -985,7 +1040,10 @@ namespace System.Xml.Serialization
                                return str;
                        }
                        else if (type.SchemaType == SchemaTypes.Enum) {
-                               return GenerateGetEnumXmlValue (typeMap, value);
+                               if (isNullable)
+                                       return "(" + value + ").HasValue ? " + GenerateGetEnumXmlValue (typeMap, "(" + value + ").Value") + " : null";
+                               else
+                                       return GenerateGetEnumXmlValue (typeMap, value);
                        }
                        else if (type.Type == typeof (XmlQualifiedName))
                                return "FromXmlQualifiedName (" + value + ")";
@@ -1067,7 +1125,7 @@ namespace System.Xml.Serialization
                        else if (typeof(IEnumerable).IsAssignableFrom (listType.Type))
                        {
                                string itemVar = GetObTempVar ();
-                               WriteLineInd ("foreach (" + listType.ListItemTypeData.FullTypeName + " " + itemVar + " in " + ob + ") {");
+                               WriteLineInd ("foreach (" + listType.ListItemTypeData.CSharpFullName + " " + itemVar + " in " + ob + ") {");
                                GenerateListLoop (container, map, itemVar, null, listType.ListItemTypeData, targetString);
                                WriteLineUni ("}");
                        }
@@ -1095,13 +1153,13 @@ namespace System.Xml.Serialization
                                if (map.ChoiceMember != null && multichoice)
                                        WriteLineInd ("else if (" + container + ".@" + map.ChoiceMember + "[" + index + "] == " + GetLiteral (info.ChoiceValue) + ") {");
                                else if (multichoice)
-                                       WriteLineInd ("else if (" + item + ".GetType() == typeof(" + info.TypeData.FullTypeName + ")) {");
+                                       WriteLineInd ("else if (" + item + ".GetType() == typeof(" + info.TypeData.CSharpFullName + ")) {");
                                
                                if (targetString == null) 
                                        GenerateWriteMemberElement (info, GetCast (info.TypeData, itemTypeData, item));
                                else
                                {
-                                       string strVal = GenerateGetStringValue (info.MappedType, info.TypeData, GetCast (info.TypeData, itemTypeData, item));
+                                       string strVal = GenerateGetStringValue (info.MappedType, info.TypeData, GetCast (info.TypeData, itemTypeData, item), false);
                                        WriteLine (targetString + ".Append (" + strVal + ").Append (\" \");");
                                }
 
@@ -1116,14 +1174,14 @@ namespace System.Xml.Serialization
                void GenerateWritePrimitiveValueLiteral (string memberValue, string name, string ns, XmlTypeMapping mappedType, TypeData typeData, bool wrapped, bool isNullable)
                {
                        if (!wrapped) {
-                               string strVal = GenerateGetStringValue (mappedType, typeData, memberValue);
+                               string strVal = GenerateGetStringValue (mappedType, typeData, memberValue, false);
                                WriteMetCall ("WriteValue", strVal);
                        }
                        else if (isNullable) {
                                if (typeData.Type == typeof(XmlQualifiedName)) 
                                        WriteMetCall ("WriteNullableQualifiedNameLiteral", GetLiteral(name), GetLiteral(ns), memberValue);
                                else  {
-                                       string strVal = GenerateGetStringValue (mappedType, typeData, memberValue);
+                                       string strVal = GenerateGetStringValue (mappedType, typeData, memberValue, true);
                                        WriteMetCall ("WriteNullableStringLiteral", GetLiteral(name), GetLiteral(ns), strVal);
                                }
                        }
@@ -1131,7 +1189,7 @@ namespace System.Xml.Serialization
                                if (typeData.Type == typeof(XmlQualifiedName))
                                        WriteMetCall ("WriteElementQualifiedName", GetLiteral(name), GetLiteral(ns), memberValue);
                                else {
-                                       string strVal = GenerateGetStringValue (mappedType, typeData, memberValue);
+                                       string strVal = GenerateGetStringValue (mappedType, typeData, memberValue, false);
                                        WriteMetCall ("WriteElementString", GetLiteral(name),GetLiteral(ns), strVal);
                                }
                        }
@@ -1140,14 +1198,14 @@ namespace System.Xml.Serialization
                void GenerateWritePrimitiveValueEncoded (string memberValue, string name, string ns, XmlQualifiedName xsiType, XmlTypeMapping mappedType, TypeData typeData, bool wrapped, bool isNullable)
                {
                        if (!wrapped) {
-                               string strVal = GenerateGetStringValue (mappedType, typeData, memberValue);
+                               string strVal = GenerateGetStringValue (mappedType, typeData, memberValue, false);
                                WriteMetCall ("WriteValue", strVal);
                        }
                        else if (isNullable) {
                                if (typeData.Type == typeof(XmlQualifiedName)) 
                                        WriteMetCall ("WriteNullableQualifiedNameEncoded", GetLiteral(name), GetLiteral(ns), memberValue, GetLiteral(xsiType));
                                else  {
-                                       string strVal = GenerateGetStringValue (mappedType, typeData, memberValue);
+                                       string strVal = GenerateGetStringValue (mappedType, typeData, memberValue, true);
                                        WriteMetCall ("WriteNullableStringEncoded", GetLiteral(name), GetLiteral(ns), strVal, GetLiteral(xsiType));
                                }
                        }
@@ -1155,7 +1213,7 @@ namespace System.Xml.Serialization
                                if (typeData.Type == typeof(XmlQualifiedName))
                                        WriteMetCall ("WriteElementQualifiedName", GetLiteral(name), GetLiteral(ns), memberValue, GetLiteral(xsiType));
                                else {
-                                       string strVal = GenerateGetStringValue (mappedType, typeData, memberValue);
+                                       string strVal = GenerateGetStringValue (mappedType, typeData, memberValue, false);
                                        WriteMetCall ("WriteElementString", GetLiteral(name),GetLiteral(ns), strVal, GetLiteral(xsiType));
                                }
                        }
@@ -1163,14 +1221,14 @@ namespace System.Xml.Serialization
 
                string GenerateGetMemberValue (XmlTypeMapMember member, string ob, bool isValueList)
                {
-                       if (isValueList) return GetCast (member.TypeData, TypeTranslator.GetTypeData (typeof(object)), ob + "[" + member.Index + "]");
+                       if (isValueList) return GetCast (member.TypeData, TypeTranslator.GetTypeData (typeof(object)), ob + "[" + member.GlobalIndex + "]");
                        else return ob + ".@" + member.Name;
                }
                
                string GenerateMemberHasValueCondition (XmlTypeMapMember member, string ob, bool isValueList)
                {
                        if (isValueList) {
-                               return ob + ".Length > " + member.Index;
+                               return ob + ".Length > " + member.GlobalIndex;
                        }
                        else if (member.DefaultValue != System.DBNull.Value) {
                                string mem = ob + ".@" + member.Name;
@@ -1249,6 +1307,12 @@ namespace System.Xml.Serialization
                        else
                                WriteLine ("internal class " + readerClassName + " : XmlSerializationReader");
                        WriteLineInd ("{");
+                       // FromBinHexString() is not public, so use reflection here.
+                       WriteLine ("static readonly System.Reflection.MethodInfo fromBinHexStringMethod = typeof (XmlConvert).GetMethod (\"FromBinHexString\", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, new Type [] {typeof (string)}, null);");
+                       WriteLine ("static byte [] FromBinHexString (string input)");
+                       WriteLineInd ("{");
+                       WriteLine ("return input == null ? null : (byte []) fromBinHexStringMethod.Invoke (null, new object [] {input});");
+                       WriteLineUni ("}");
 
                        _mapsToGenerate = new ArrayList ();
                        _fixupCallbacks = new ArrayList ();
@@ -1271,7 +1335,7 @@ namespace System.Xml.Serialization
                                
                                GenerateReadObject (map);
                                if (map.TypeData.SchemaType == SchemaTypes.Enum)
-                                       GenerateGetEnumValue (map);
+                                       GenerateGetEnumValueMethod (map);
                        }
                        
                        GenerateReadInitCallbacks ();
@@ -1298,14 +1362,18 @@ namespace System.Xml.Serialization
 
                                if (_format == SerializationFormat.Literal)
                                {
-                                       if (typeMap.TypeData.SchemaType == SchemaTypes.XmlNode)
-                                               throw new Exception ("Not supported for XmlNode types");
-                                               
-                                       WriteLineInd ("if (Reader.LocalName != " + GetLiteral (typeMap.ElementName) + " || Reader.NamespaceURI != " + GetLiteral (typeMap.Namespace) + ")");
-                                       WriteLine ("throw CreateUnknownNodeException();");
-                                       Unindent ();
+                                       if (typeMap.TypeData.SchemaType == SchemaTypes.XmlNode) {
+                                               if (typeMap.TypeData.Type == typeof (XmlDocument))
+                                                       WriteLine ("return ReadXmlDocument (false);");
+                                               else
+                                                       WriteLine ("return ReadXmlNode (false);");
+                                       } else {
+                                               WriteLineInd ("if (Reader.LocalName != " + GetLiteral (typeMap.ElementName) + " || Reader.NamespaceURI != " + GetLiteral (typeMap.Namespace) + ")");
+                                               WriteLine ("throw CreateUnknownNodeException();");
+                                               Unindent ();
 
-                                       WriteLine ("return " + GetReadObjectCall (typeMap, GetLiteral(typeMap.IsNullable), "true") + ";");
+                                               WriteLine ("return " + GetReadObjectCall (typeMap, GetLiteral(typeMap.IsNullable), "true") + ";");
+                                       }
                                }
                                else
                                {
@@ -1358,6 +1426,7 @@ namespace System.Xml.Serialization
                                        WriteLineInd ("{");
                                        WriteLineInd ("if (Reader.IsEmptyElement) {");
                                        WriteLine ("Reader.Skip();");
+                                       WriteLine ("Reader.MoveToContent();");
                                        WriteLineUni ("}");
                                        WriteLineInd ("else {");
                                        WriteLine ("Reader.ReadStartElement();");
@@ -1370,11 +1439,27 @@ namespace System.Xml.Serialization
                                }
                                else
                                {
-                                       WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement)");
+                                       // bug #79988: out parameters need to be initialized if 
+                                       // they are value types
+                                       ClassMap classMap = (ClassMap) typeMap.ObjectMap;
+                                       ArrayList members = classMap.AllMembers;
+                                       for (int n = 0; n < members.Count; n++) {
+                                               XmlTypeMapMember mem = (XmlTypeMapMember) members [n];
+                                               if (!mem.IsReturnValue && mem.TypeData.IsValueType)
+                                                       GenerateSetMemberValueFromAttr (mem, "parameters",
+                                                               String.Format ("({0}) Activator.CreateInstance(typeof({0}), true)", mem.TypeData.FullTypeName), true);
+                                       }
+
+                                       WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement && Reader.ReadState == ReadState.Interactive)");
                                        WriteLineInd ("{");
                                        WriteLine ("if (Reader.IsStartElement(" + GetLiteral(typeMap.ElementName) + ", " + GetLiteral(typeMap.Namespace) + "))");
                                        WriteLineInd ("{");
-                                       WriteLine ("if (Reader.IsEmptyElement) { Reader.Skip(); Reader.MoveToContent(); continue; }");
+                                       bool dummy = false;
+                                       GenerateReadAttributeMembers (typeMap, (ClassMap)typeMap.ObjectMap, "parameters", true, ref dummy);
+                                       WriteLine ("if (Reader.IsEmptyElement)");
+                                       WriteLineInd ("{");
+                                       WriteLine ("Reader.Skip(); Reader.MoveToContent(); continue;");
+                                       WriteLineUni ("}");
                                        WriteLine ("Reader.ReadStartElement();");
                                        GenerateReadMembers (typeMap, (ClassMap)typeMap.ObjectMap, "parameters", true, false);
                                        WriteLine ("ReadEndElement();");
@@ -1401,7 +1486,7 @@ namespace System.Xml.Serialization
                {
                        string isNullable;
                        if (_format == SerializationFormat.Literal) {
-                               WriteLine ("public " + typeMap.TypeFullName + " " + GetReadObjectName (typeMap) + " (bool isNullable, bool checkType)");
+                               WriteLine ("public " + typeMap.TypeData.CSharpFullName + " " + GetReadObjectName (typeMap) + " (bool isNullable, bool checkType)");
                                isNullable = "isNullable";
                        }
                        else {
@@ -1413,8 +1498,8 @@ namespace System.Xml.Serialization
 
                        PushHookContext ();
                        
-                       SetHookVar ("$TYPE", typeMap.TypeName);
-                       SetHookVar ("$FULLTYPE", typeMap.TypeFullName);
+                       SetHookVar ("$TYPE", typeMap.TypeData.CSharpName);
+                       SetHookVar ("$FULLTYPE", typeMap.TypeData.CSharpFullName);
                        SetHookVar ("$NULLABLE", "isNullable");
                        
                        switch (typeMap.TypeData.SchemaType)
@@ -1442,7 +1527,7 @@ namespace System.Xml.Serialization
                        SetHookVar ("$OBJECT", "ob");
                        if (!typeMap.TypeData.IsValueType)
                        {
-                               WriteLine (typeMap.TypeFullName + " ob = null;");
+                               WriteLine (typeMap.TypeData.CSharpFullName + " ob = null;");
                        
                                if (GenerateReadHook (HookType.type, typeMap.TypeData.Type)) {
                                        WriteLine ("return ob;");
@@ -1462,7 +1547,7 @@ namespace System.Xml.Serialization
                        }
                        else
                        {
-                               WriteLine (typeMap.TypeFullName + " ob = new " + typeMap.TypeFullName + " ();");
+                               WriteLine (typeMap.TypeData.CSharpFullName + String.Format (" ob = ({0}) Activator.CreateInstance(typeof({0}), true);", typeMap.TypeData.CSharpFullName));
                        
                                if (GenerateReadHook (HookType.type, typeMap.TypeData.Type)) {
                                        WriteLine ("return ob;");
@@ -1502,7 +1587,7 @@ namespace System.Xml.Serialization
                                }
        
                                WriteLine ("");
-                               WriteLine ("ob = new " + typeMap.TypeFullName + " ();");
+                               WriteLine (String.Format ("ob = ({0}) Activator.CreateInstance(typeof({0}), true);", typeMap.TypeData.CSharpFullName));
                        }
                        
                        WriteLine ("");
@@ -1523,100 +1608,9 @@ namespace System.Xml.Serialization
                        XmlTypeMapping typeMap = xmlMap as XmlTypeMapping;
                        Type xmlMapType = (typeMap != null) ? typeMap.TypeData.Type : typeof(object[]);
                        
-                       // Load the default value of members
-                       if (map.MembersWithDefault != null)
-                       {
-                               ArrayList members = map.MembersWithDefault;
-                               for (int n=0; n<members.Count; n++) {
-                                       XmlTypeMapMember mem = (XmlTypeMapMember) members[n];
-                                       GenerateSetMemberValueFromAttr (mem, ob, GetLiteral (mem.DefaultValue), isValueList);
-                               }
-                       }
-                       
-                       // A value list cannot have attributes
-
-                       bool first;
-                       if (!isValueList && !GenerateReadHook (HookType.attributes, xmlMapType))
-                       {
-                               // Reads attributes
-                               
-                               XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
-                               
-                               if (anyAttrMember != null)
-                               {
-                                       WriteLine ("int anyAttributeIndex = 0;");
-                                       WriteLine (anyAttrMember.TypeData.FullTypeName + " anyAttributeArray = null;");
-                               }
-                               
-                               WriteLine ("while (Reader.MoveToNextAttribute())");
-                               WriteLineInd ("{");
-                               first = true;
-                               if (map.AttributeMembers != null) {
-                                       foreach (XmlTypeMapMemberAttribute at in map.AttributeMembers)
-                                       {
-                                               WriteLineInd ((first?"":"else ") + "if (Reader.LocalName == " + GetLiteral (at.AttributeName) + " && Reader.NamespaceURI == " + GetLiteral (at.Namespace) + ") {");
-                                               if (!GenerateReadMemberHook (xmlMapType, at)) {
-                                                       GenerateSetMemberValue (at, ob, GenerateGetValueFromXmlString ("Reader.Value", at.TypeData, at.MappedType), isValueList);
-                                                       GenerateEndHook ();
-                                               }
-                                               WriteLineUni ("}");
-                                               first = false;
-                                       }
-                               }
-                               WriteLineInd ((first?"":"else ") + "if (IsXmlnsAttribute (Reader.Name)) {");
-
-                               // If the map has NamespaceDeclarations,
-                               // then store this xmlns to the given member.
-                               // If the instance doesn't exist, then create.
-                               
-                               if (map.NamespaceDeclarations != null) {
-                                       if (!GenerateReadMemberHook (xmlMapType, map.NamespaceDeclarations)) {
-                                               string nss = ob + ".@" + map.NamespaceDeclarations.Name;
-                                               WriteLine ("if (" + nss + " == null) " + nss + " = new XmlSerializerNamespaces ();");
-                                               WriteLineInd ("if (Reader.Prefix == \"xmlns\")");
-                                               WriteLine (nss + ".Add (Reader.LocalName, Reader.Value);");
-                                               Unindent ();
-                                               WriteLineInd ("else");
-                                               WriteLine (nss + ".Add (\"\", Reader.Value);");
-                                               Unindent ();
-                                               GenerateEndHook ();
-                                       }
-                               }
-                               
-                               WriteLineUni ("}");
-                               WriteLineInd ("else {");
-
-                               if (anyAttrMember != null) 
-                               {
-                                       if (!GenerateReadArrayMemberHook (xmlMapType, anyAttrMember, "anyAttributeIndex")) {
-                                               WriteLine ("System.Xml.XmlAttribute attr = (System.Xml.XmlAttribute) Document.ReadNode(Reader);");
-                                               if (typeof(System.Xml.Schema.XmlSchemaAnnotated).IsAssignableFrom (xmlMapType)) 
-                                                       WriteLine ("ParseWsdlArrayType (attr);");
-                                               GenerateAddListValue (anyAttrMember.TypeData, "anyAttributeArray", "anyAttributeIndex", GetCast (anyAttrMember.TypeData.ListItemTypeData, "attr"), true);
-                                               GenerateEndHook ();
-                                       }
-                                       WriteLine ("anyAttributeIndex++;");
-                               }
-                               else {
-                                       if (!GenerateReadHook (HookType.unknownAttribute, xmlMapType)) {
-                                               WriteLine ("UnknownNode (" + ob + ");");
-                                               GenerateEndHook ();
-                                       }
-                               }
-
-                               WriteLineUni ("}");
-                               WriteLineUni ("}");
-
-                               if (anyAttrMember != null && !MemberHasReadReplaceHook (xmlMapType, anyAttrMember))
-                               {
-                                       WriteLine ("");
-                                       WriteLine("anyAttributeArray = (" + anyAttrMember.TypeData.FullTypeName + ") ShrinkArray (anyAttributeArray, anyAttributeIndex, " + GetTypeOf(anyAttrMember.TypeData.Type.GetElementType()) + ", true);");
-                                       GenerateSetMemberValue (anyAttrMember, ob, "anyAttributeArray", isValueList);
-                               }
-                               WriteLine ("");
-       
-                               GenerateEndHook ();
-                       }
+                       bool first = false;
+                       // Read attributes
+                       GenerateReadAttributeMembers (xmlMap, map, ob, isValueList, ref first);
 
                        if (!isValueList)
                        {
@@ -1641,14 +1635,22 @@ namespace System.Xml.Serialization
                                string[] readFlag = null;
                                if (map.ElementMembers != null && !readByOrder)
                                {
-                                       string readFlagsVars = "bool ";
+                                       string readFlagsVars = string.Empty;
                                        readFlag = new string[map.ElementMembers.Count];
-                                       for (int n=0; n<map.ElementMembers.Count; n++) {
-                                               readFlag[n] = GetBoolTempVar ();
-                                               if (n > 0) readFlagsVars += ", ";
-                                               readFlagsVars += readFlag[n] + "=false";
+                                       int n=0;
+                                       foreach (XmlTypeMapMember mem in map.ElementMembers) {
+                                               // The text collector doesn't need a flag
+                                               if (!((mem is XmlTypeMapMemberElement) && ((XmlTypeMapMemberElement)mem).IsXmlTextCollector)) {
+                                                       readFlag[n] = GetBoolTempVar ();
+                                                       if (readFlagsVars.Length > 0) readFlagsVars += ", ";
+                                                       readFlagsVars += readFlag[n] + "=false";
+                                               }
+                                               n++;
+                                       }
+                                       if (readFlagsVars.Length > 0) {
+                                               readFlagsVars = "bool " + readFlagsVars;
+                                               WriteLine (readFlagsVars + ";");
                                        }
-                                       if (map.ElementMembers.Count > 0) WriteLine (readFlagsVars + ";");
                                        WriteLine ("");
                                }
                                
@@ -1671,7 +1673,7 @@ namespace System.Xml.Serialization
                                                if (!MemberHasReadReplaceHook (xmlMapType, mem)) {
                                                        flatLists[n] = GetObTempVar ();
                                                        string rval;
-                                                       WriteLine (mem.TypeData.FullTypeName + " " + flatLists[n] + ";");
+                                                       WriteLine (mem.TypeData.CSharpFullName + " " + flatLists[n] + ";");
                                                        if (IsReadOnly (typeMap, mem, mem.TypeData, isValueList)) {
                                                                rval = GenerateGetMemberValue (mem, ob, isValueList);
                                                                WriteLine (flatLists[n] + " = " + rval + ";");
@@ -1692,7 +1694,7 @@ namespace System.Xml.Serialization
                                                                flatListsChoices = new string [map.FlatLists.Count];
                                                        flatListsChoices[n] = GetObTempVar ();
                                                        string rval = GenerateInitializeList (mem.ChoiceTypeData);
-                                                       WriteLine (mem.ChoiceTypeData.FullTypeName + " " + flatListsChoices[n] + " = " + rval + ";");
+                                                       WriteLine (mem.ChoiceTypeData.CSharpFullName + " " + flatListsChoices[n] + " = " + rval + ";");
                                                }
                                        }
                                        WriteLine (code + ";");
@@ -1755,7 +1757,7 @@ namespace System.Xml.Serialization
 
                                                        WriteLineInd ("if (fixup.Ids[" + info.Member.Index + "] == null) {");   // Already read
                                                        if (IsReadOnly (typeMap, info.Member, info.TypeData, isValueList)) 
-                                                               WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral(info.TypeData.FullTypeName) + ");");
+                                                               WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral(info.TypeData.CSharpFullName) + ");");
                                                        else 
                                                                GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,list), isValueList);
                                                        WriteLineUni ("}");
@@ -1784,14 +1786,14 @@ namespace System.Xml.Serialization
                                                                                GenerateSetMemberValue (info.Member, ob, GenerateReadListElement (info.MappedType, null, GetLiteral(info.IsNullable), true), isValueList);
                                                                        else {
                                                                                string list = GetObTempVar ();
-                                                                               WriteLine (info.MappedType.TypeFullName + " " + list + " = " + GenerateReadListElement (info.MappedType, null, GetLiteral(info.IsNullable), true) + ";");
+                                                                               WriteLine (info.MappedType.TypeData.CSharpFullName + " " + list + " = " + GenerateReadListElement (info.MappedType, null, GetLiteral(info.IsNullable), true) + ";");
                                                                                WriteLineInd ("if (((object)" + list + ") != null) {");
                                                                                GenerateSetMemberValue (info.Member, ob, list, isValueList);
                                                                                WriteLineUni ("}");
                                                                        }
                                                                } else {
                                                                        string list = GetObTempVar ();
-                                                                       WriteLine (info.MappedType.TypeFullName + " " + list + " = " + GenerateGetMemberValue (info.Member, ob, isValueList) + ";");
+                                                                       WriteLine (info.MappedType.TypeData.CSharpFullName + " " + list + " = " + GenerateGetMemberValue (info.Member, ob, isValueList) + ";");
                                                                        WriteLineInd ("if (((object)" + list + ") == null) {");
                                                                        WriteLine (list + " = " + GenerateCreateList (info.MappedType.TypeData.Type) + ";");
                                                                        GenerateSetMemberValue (info.Member, ob, list, isValueList);
@@ -1906,7 +1908,7 @@ namespace System.Xml.Serialization
                                        
                                        if (map.XmlTextCollector != null)
                                        {
-                                               WriteLine ("else if (Reader.NodeType == System.Xml.XmlNodeType.Text)");
+                                               WriteLine ("else if (Reader.NodeType == System.Xml.XmlNodeType.Text || Reader.NodeType == System.Xml.XmlNodeType.CDATA)");
                                                WriteLineInd ("{");
                
                                                if (map.XmlTextCollector is XmlTypeMapMemberExpandable)
@@ -1928,8 +1930,13 @@ namespace System.Xml.Serialization
                                                        XmlTypeMapElementInfo info = (XmlTypeMapElementInfo) mem.ElementInfo [0];
                                                        if (info.TypeData.Type == typeof (string))
                                                                GenerateSetMemberValue (mem, ob, "ReadString (" + GenerateGetMemberValue (mem, ob, isValueList) + ")", isValueList);
-                                                       else
-                                                               GenerateSetMemberValue (mem, ob, GenerateGetValueFromXmlString ("Reader.ReadString()", info.TypeData, info.MappedType), isValueList);
+                                                       else {
+                                                               WriteLineInd ("{");
+                                                               string str = GetStrTempVar ();
+                                                               WriteLine ("string " + str + " = Reader.ReadString();");
+                                                               GenerateSetMemberValue (mem, ob, GenerateGetValueFromXmlString (str, info.TypeData, info.MappedType, info.IsNullable), isValueList);
+                                                               WriteLineUni ("}");
+                                                       }
                                                        GenerateEndHook ();
                                                }
                                                WriteLineUni ("}");
@@ -1953,7 +1960,7 @@ namespace System.Xml.Serialization
                                                
                                                string list = flatLists[mem.FlatArrayIndex];
                                                if (mem.TypeData.Type.IsArray)
-                                                       WriteLine (list + " = (" + mem.TypeData.FullTypeName + ") ShrinkArray (" + list + ", " + indexes[mem.FlatArrayIndex] + ", " + GetTypeOf(mem.TypeData.Type.GetElementType()) + ", true);");
+                                                       WriteLine (list + " = (" + mem.TypeData.CSharpFullName + ") ShrinkArray (" + list + ", " + indexes[mem.FlatArrayIndex] + ", " + GetTypeOf(mem.TypeData.Type.GetElementType()) + ", true);");
                                                if (!IsReadOnly (typeMap, mem, mem.TypeData, isValueList) && mem.TypeData.Type.IsArray)
                                                        GenerateSetMemberValue (mem, ob, list, isValueList);
                                        }
@@ -1968,7 +1975,7 @@ namespace System.Xml.Serialization
                                                if (mem.ChoiceMember == null) continue;
                                                
                                                string list = flatListsChoices[mem.FlatArrayIndex];
-                                               WriteLine (list + " = (" + mem.ChoiceTypeData.FullTypeName + ") ShrinkArray (" + list + ", " + indexes[mem.FlatArrayIndex] + ", " + GetTypeOf(mem.ChoiceTypeData.Type.GetElementType()) + ", true);");
+                                               WriteLine (list + " = (" + mem.ChoiceTypeData.CSharpFullName + ") ShrinkArray (" + list + ", " + indexes[mem.FlatArrayIndex] + ", " + GetTypeOf(mem.ChoiceTypeData.Type.GetElementType()) + ", true);");
                                                WriteLine (ob + ".@" + mem.ChoiceMember + " = " + list + ";");
                                        }
                                }
@@ -1984,6 +1991,93 @@ namespace System.Xml.Serialization
                                WriteLine ("ReadEndElement();");
                        }
                }
+
+               void GenerateReadAttributeMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isValueList, ref bool first)
+               {
+                       XmlTypeMapping typeMap = xmlMap as XmlTypeMapping;
+                       Type xmlMapType = (typeMap != null) ? typeMap.TypeData.Type : typeof(object[]);
+
+                       if (GenerateReadHook (HookType.attributes, xmlMapType))
+                               return;
+
+                       XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
+                       
+                       if (anyAttrMember != null)
+                       {
+                               WriteLine ("int anyAttributeIndex = 0;");
+                               WriteLine (anyAttrMember.TypeData.CSharpFullName + " anyAttributeArray = null;");
+                       }
+                       
+                       WriteLine ("while (Reader.MoveToNextAttribute())");
+                       WriteLineInd ("{");
+                       first = true;
+                       if (map.AttributeMembers != null) {
+                               foreach (XmlTypeMapMemberAttribute at in map.AttributeMembers)
+                               {
+                                       WriteLineInd ((first?"":"else ") + "if (Reader.LocalName == " + GetLiteral (at.AttributeName) + " && Reader.NamespaceURI == " + GetLiteral (at.Namespace) + ") {");
+                                       if (!GenerateReadMemberHook (xmlMapType, at)) {
+                                               GenerateSetMemberValue (at, ob, GenerateGetValueFromXmlString ("Reader.Value", at.TypeData, at.MappedType, false), isValueList);
+                                               GenerateEndHook ();
+                                       }
+                                       WriteLineUni ("}");
+                                       first = false;
+                               }
+                       }
+                       WriteLineInd ((first?"":"else ") + "if (IsXmlnsAttribute (Reader.Name)) {");
+
+                       // If the map has NamespaceDeclarations,
+                       // then store this xmlns to the given member.
+                       // If the instance doesn't exist, then create.
+                       
+                       if (map.NamespaceDeclarations != null) {
+                               if (!GenerateReadMemberHook (xmlMapType, map.NamespaceDeclarations)) {
+                                       string nss = ob + ".@" + map.NamespaceDeclarations.Name;
+                                       WriteLine ("if (" + nss + " == null) " + nss + " = new XmlSerializerNamespaces ();");
+                                       WriteLineInd ("if (Reader.Prefix == \"xmlns\")");
+                                       WriteLine (nss + ".Add (Reader.LocalName, Reader.Value);");
+                                       Unindent ();
+                                       WriteLineInd ("else");
+                                       WriteLine (nss + ".Add (\"\", Reader.Value);");
+                                       Unindent ();
+                                       GenerateEndHook ();
+                               }
+                       }
+                       
+                       WriteLineUni ("}");
+                       WriteLineInd ("else {");
+
+                       if (anyAttrMember != null) 
+                       {
+                               if (!GenerateReadArrayMemberHook (xmlMapType, anyAttrMember, "anyAttributeIndex")) {
+                                       WriteLine ("System.Xml.XmlAttribute attr = (System.Xml.XmlAttribute) Document.ReadNode(Reader);");
+                                       if (typeof(System.Xml.Schema.XmlSchemaAnnotated).IsAssignableFrom (xmlMapType)) 
+                                               WriteLine ("ParseWsdlArrayType (attr);");
+                                       GenerateAddListValue (anyAttrMember.TypeData, "anyAttributeArray", "anyAttributeIndex", GetCast (anyAttrMember.TypeData.ListItemTypeData, "attr"), true);
+                                       GenerateEndHook ();
+                               }
+                               WriteLine ("anyAttributeIndex++;");
+                       }
+                       else {
+                               if (!GenerateReadHook (HookType.unknownAttribute, xmlMapType)) {
+                                       WriteLine ("UnknownNode (" + ob + ");");
+                                       GenerateEndHook ();
+                               }
+                       }
+
+                       WriteLineUni ("}");
+                       WriteLineUni ("}");
+
+                       if (anyAttrMember != null && !MemberHasReadReplaceHook (xmlMapType, anyAttrMember))
+                       {
+                               WriteLine ("");
+                               WriteLine("anyAttributeArray = (" + anyAttrMember.TypeData.CSharpFullName + ") ShrinkArray (anyAttributeArray, anyAttributeIndex, " + GetTypeOf(anyAttrMember.TypeData.Type.GetElementType()) + ", true);");
+                               GenerateSetMemberValue (anyAttrMember, ob, "anyAttributeArray", isValueList);
+                       }
+                       WriteLine ("");
+                       WriteLine ("Reader.MoveToElement ();");
+
+                       GenerateEndHook ();
+               }
                
                void GenerateSetListMembersDefaults (XmlTypeMapping typeMap, ClassMap map, string ob, bool isValueList)
                {
@@ -2009,7 +2103,7 @@ namespace System.Xml.Serialization
 
                void GenerateSetMemberValue (XmlTypeMapMember member, string ob, string value, bool isValueList)
                {
-                       if (isValueList) WriteLine (ob + "[" + member.Index + "] = " + value + ";");
+                       if (isValueList) WriteLine (ob + "[" + member.GlobalIndex + "] = " + value + ";");
                        else {
                                WriteLine (ob + ".@" + member.Name + " = " + value + ";");
                                if (member.IsOptionalValueType)
@@ -2046,7 +2140,7 @@ namespace System.Xml.Serialization
                                        return GetReadObjectCall (elem.MappedType, GetLiteral(elem.IsNullable), "true");
 
                                case SchemaTypes.XmlSerializable:
-                                       return GetCast (elem.TypeData, "ReadSerializable (new " + elem.TypeData.FullTypeName + " ())");
+                                       return GetCast (elem.TypeData, String.Format ("({0}) ReadSerializable (({0}) Activator.CreateInstance(typeof({0}), true))", elem.TypeData.CSharpFullName));
 
                                default:
                                        throw new NotSupportedException ("Invalid value type");
@@ -2059,18 +2153,24 @@ namespace System.Xml.Serialization
                                if (elem.IsNullable) return "ReadNullableQualifiedName ()";
                                else return "ReadElementQualifiedName ()";
                        }
-                       else if (elem.IsNullable)
-                               return GenerateGetValueFromXmlString ("ReadNullableString ()", elem.TypeData, elem.MappedType);
-                       else
-                               return GenerateGetValueFromXmlString ("Reader.ReadElementString ()", elem.TypeData, elem.MappedType);
+                       else if (elem.IsNullable) {
+                               string str = GetStrTempVar ();
+                               WriteLine ("string " + str + " = ReadNullableString ();");
+                               return GenerateGetValueFromXmlString (str, elem.TypeData, elem.MappedType, true);
+                       }
+                       else {
+                               string str = GetStrTempVar ();
+                               WriteLine ("string " + str + " = Reader.ReadElementString ();");
+                               return GenerateGetValueFromXmlString (str, elem.TypeData, elem.MappedType, false);
+                       }
                }
                
-               string GenerateGetValueFromXmlString (string value, TypeData typeData, XmlTypeMapping typeMap)
+               string GenerateGetValueFromXmlString (string value, TypeData typeData, XmlTypeMapping typeMap, bool isNullable)
                {
                        if (typeData.SchemaType == SchemaTypes.Array)
                                return GenerateReadListString (typeMap, value);
                        else if (typeData.SchemaType == SchemaTypes.Enum)
-                               return GenerateGetEnumValue (typeMap, value);
+                               return GenerateGetEnumValue (typeMap, value, isNullable);
                        else if (typeData.Type == typeof (XmlQualifiedName))
                                return "ToXmlQualifiedName (" + value + ")";
                        else 
@@ -2087,7 +2187,7 @@ namespace System.Xml.Serialization
                        {
                                if (list == null) {
                                        list = GetObTempVar ();
-                                       WriteLine (typeMap.TypeFullName + " " + list + " = null;");
+                                       WriteLine (typeMap.TypeData.CSharpFullName + " " + list + " = null;");
                                        if (doNullCheck)
                                                WriteLineInd ("if (!ReadNull()) {");
                                        WriteLine (list + " = " + GenerateCreateList (listType) + ";");
@@ -2100,12 +2200,12 @@ namespace System.Xml.Serialization
                        {
                                if (list != null) {
                                        WriteLineInd ("if (((object)" + list + ") == null)");
-                                       WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral (typeMap.TypeFullName) + ");");
+                                       WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral (typeMap.TypeData.CSharpFullName) + ");");
                                        Unindent ();
                                        doNullCheck = false;
                                }
                                else {
-                                       WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral (typeMap.TypeFullName) + ");");
+                                       WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral (typeMap.TypeData.CSharpFullName) + ");");
                                        return list;
                                }
                        }
@@ -2113,7 +2213,7 @@ namespace System.Xml.Serialization
                        WriteLineInd ("if (Reader.IsEmptyElement) {");
                        WriteLine ("Reader.Skip();");
                        if (listType.IsArray)
-                               WriteLine (list + " = (" + typeMap.TypeFullName + ") ShrinkArray (" + list + ", 0, " + GetTypeOf(listType.GetElementType()) + ", false);");
+                               WriteLine (list + " = (" + typeMap.TypeData.CSharpFullName + ") ShrinkArray (" + list + ", 0, " + GetTypeOf(listType.GetElementType()) + ", false);");
 
                        Unindent ();
                        WriteLineInd ("} else {");
@@ -2150,7 +2250,7 @@ namespace System.Xml.Serialization
                        WriteLine ("ReadEndElement();");
 
                        if (listType.IsArray)
-                               WriteLine (list + " = (" + typeMap.TypeFullName + ") ShrinkArray (" + list + ", " + index + ", " + GetTypeOf(listType.GetElementType()) + ", false);");
+                               WriteLine (list + " = (" + typeMap.TypeData.CSharpFullName + ") ShrinkArray (" + list + ", " + index + ", " + GetTypeOf(listType.GetElementType()) + ", false);");
 
                        WriteLineUni ("}");
                        if (doNullCheck)
@@ -2163,7 +2263,7 @@ namespace System.Xml.Serialization
                {
                        Type listType = typeMap.TypeData.Type;
                        ListMap listMap = (ListMap)typeMap.ObjectMap;
-                       string itemType = listType.GetElementType().FullName;
+                       string itemType = ToCSharpFullName (listType.GetElementType());
                        
                        string list = GetObTempVar ();
                        WriteLine (itemType + "[] " + list + ";");
@@ -2175,36 +2275,49 @@ namespace System.Xml.Serialization
                        string valueArray = GetObTempVar ();
                        WriteLine ("string[] " + valueArray + " = " + var + ".Split (' ');");
                        
-                       WriteLine (list + " = new " + itemType + " [" + valueArray + ".Length];");
-
+                       WriteLine (list + " = new " + GetArrayDeclaration (listType, valueArray + ".Length") + ";");
+                       
                        XmlTypeMapElementInfo info = (XmlTypeMapElementInfo)listMap.ItemInfo[0];
 
                        string index = GetNumTempVar ();
                        WriteLineInd ("for (int " + index + " = 0; " + index + " < " + valueArray + ".Length; " + index + "++)");
-                       WriteLine (list + "[" + index + "] = " + GenerateGetValueFromXmlString (valueArray + "[" + index + "]", info.TypeData, info.MappedType) + ";");
+                       WriteLine (list + "[" + index + "] = " + GenerateGetValueFromXmlString (valueArray + "[" + index + "]", info.TypeData, info.MappedType, info.IsNullable) + ";");
                        Unindent ();
                        WriteLineUni ("}");
                        WriteLine ("else");
-                       WriteLine ("\t" + list + " = new " + itemType + " [0];");
+                       WriteLine ("\t" + list + " = new " + GetArrayDeclaration (listType, "0") + ";");
                        
                        return list;
                }
+               
+               string GetArrayDeclaration (Type type, string length)
+               {
+                       Type t = type.GetElementType();
+                       System.Text.StringBuilder sb = new System.Text.StringBuilder ();
+                       sb.Append ('[').Append (length).Append (']');
+                       while (t.IsArray) {
+                               sb.Append ("[]");
+                               t = t.GetElementType();
+                       }
+                       sb.Insert (0, ToCSharpFullName (t));
+                       return sb.ToString ();
+               }
 
                void GenerateAddListValue (TypeData listType, string list, string index, string value, bool canCreateInstance)
                {
                        Type type = listType.Type;
                        if (type.IsArray)
                        {
-                               WriteLine (list + " = (" + type.FullName + ") EnsureArrayIndex (" + list + ", " + index + ", " + GetTypeOf(type.GetElementType()) + ");");
+                               WriteLine (list + " = (" + ToCSharpFullName (type) + ") EnsureArrayIndex (" + list + ", " + index + ", " + GetTypeOf(type.GetElementType()) + ");");
                                WriteLine (list + "[" + index + "] = " + value + ";");
                        }
                        else    // Must be IEnumerable
                        {
                                WriteLine ("if (((object)" + list + ") == null)");
                                if (canCreateInstance) 
-                                       WriteLine ("\t" + list + " = new " + listType.FullTypeName + "();");
+                                       WriteLine ("\t" + list + String.Format (" = ({0}) Activator.CreateInstance(typeof({0}), true);", listType.CSharpFullName));
                                else 
-                                       WriteLine ("\tthrow CreateReadOnlyCollectionException (" + GetLiteral (listType.FullTypeName) + ");");
+                                       WriteLine ("\tthrow CreateReadOnlyCollectionException (" + GetLiteral (listType.CSharpFullName) + ");");
                                
                                WriteLine (list + ".Add (" + value + ");");
                        }
@@ -2213,9 +2326,9 @@ namespace System.Xml.Serialization
                string GenerateCreateList (Type listType)
                {
                        if (listType.IsArray)
-                               return "(" + listType.FullName + ") EnsureArrayIndex (null, 0, " + GetTypeOf(listType.GetElementType()) + ")";
+                               return "(" + ToCSharpFullName (listType) + ") EnsureArrayIndex (null, 0, " + GetTypeOf(listType.GetElementType()) + ")";
                        else
-                               return "new " + listType.FullName + "()";
+                               return "new " + ToCSharpFullName (listType) + "()";
                }
                
                string GenerateInitializeList (TypeData listType)
@@ -2223,7 +2336,7 @@ namespace System.Xml.Serialization
                        if (listType.Type.IsArray)
                                return "null";
                        else
-                               return "new " + listType.Type.FullName + "()";
+                               return "new " + listType.CSharpFullName + "()";
                }
                
                void GenerateFillerCallbacks ()
@@ -2233,10 +2346,10 @@ namespace System.Xml.Serialization
                                string metName = GetFillListName (td);
                                WriteLine ("void " + metName + " (object list, object source)");
                                WriteLineInd ("{");
-                               WriteLine ("if (((object)list) == null) throw CreateReadOnlyCollectionException (" + GetLiteral (td.FullTypeName) + ");");
+                               WriteLine ("if (((object)list) == null) throw CreateReadOnlyCollectionException (" + GetLiteral (td.CSharpFullName) + ");");
                                WriteLine ("");
 
-                               WriteLine (td.FullTypeName + " dest = (" + td.FullTypeName + ") list;");
+                               WriteLine (td.CSharpFullName + " dest = (" + td.CSharpFullName + ") list;");
                                WriteLine ("foreach (object ob in (IEnumerable)source)");
                                WriteLine ("\tdest.Add (" + GetCast (td.ListItemTypeData, "ob") + ");");
                                WriteLineUni ("}");
@@ -2259,18 +2372,21 @@ namespace System.Xml.Serialization
                void GenerateReadEnumElement (XmlTypeMapping typeMap, string isNullable)
                {
                        WriteLine ("Reader.ReadStartElement ();");
-                       WriteLine (typeMap.TypeFullName + " res = " + GenerateGetEnumValue (typeMap, "Reader.ReadString()") + ";");
+                       WriteLine (typeMap.TypeData.CSharpFullName + " res = " + GenerateGetEnumValue (typeMap, "Reader.ReadString()", false) + ";");
                        WriteLineInd ("if (Reader.NodeType != XmlNodeType.None)");
                        WriteLineUni ("Reader.ReadEndElement ();");
                        WriteLine ("return res;");
                }
 
-               string GenerateGetEnumValue (XmlTypeMapping typeMap, string val)
+               string GenerateGetEnumValue (XmlTypeMapping typeMap, string val, bool isNullable)
                {
-                       return GetGetEnumValueName (typeMap) + " (" + val + ")";
+                       if (isNullable)
+                               return "(" + val + ") != null ? " + GetGetEnumValueName (typeMap) + " (" + val + ") : (" + typeMap.TypeData.CSharpFullName + "?) null";
+                       else
+                               return GetGetEnumValueName (typeMap) + " (" + val + ")";
                }
                
-               void GenerateGetEnumValue (XmlTypeMapping typeMap)
+               void GenerateGetEnumValueMethod (XmlTypeMapping typeMap)
                {
                        string metName = GetGetEnumValueName (typeMap);
                        EnumMap map = (EnumMap) typeMap.ObjectMap;
@@ -2278,14 +2394,12 @@ namespace System.Xml.Serialization
                        if (map.IsFlags)
                        {
                                string switchMethod =  metName + "_Switch";
-                               WriteLine (typeMap.TypeFullName + " " + metName + " (string xmlName)");
+                               WriteLine (typeMap.TypeData.CSharpFullName + " " + metName + " (string xmlName)");
                                WriteLineInd ("{");
                                WriteLine ("xmlName = xmlName.Trim();");
-                               WriteLine ("if (xmlName.Length == 0) return (" + typeMap.TypeFullName + ")0;");
-                               WriteLine ("if (xmlName.IndexOf (' ') != -1)");
-                               WriteLineInd ("{");
-                               WriteLine (typeMap.TypeFullName + " sb = (" + typeMap.TypeFullName + ")0;");
-                               WriteLine ("string[] enumNames = xmlName.ToString().Split (' ');");
+                               WriteLine ("if (xmlName.Length == 0) return (" + typeMap.TypeData.CSharpFullName + ")0;");
+                               WriteLine (typeMap.TypeData.CSharpFullName + " sb = (" + typeMap.TypeData.CSharpFullName + ")0;");
+                               WriteLine ("string[] enumNames = xmlName.Split (null);");
                                WriteLine ("foreach (string name in enumNames)");
                                WriteLineInd ("{");
                                WriteLine ("if (name == string.Empty) continue;");
@@ -2293,14 +2407,11 @@ namespace System.Xml.Serialization
                                WriteLineUni ("}");
                                WriteLine ("return sb;");
                                WriteLineUni ("}");
-                               WriteLine ("else");
-                               WriteLine ("\treturn " + switchMethod + " (xmlName);");
-                               WriteLineUni ("}");
                                WriteLine ("");
                                metName = switchMethod;
                        }
 
-                       WriteLine (typeMap.TypeFullName + " " + metName + " (string xmlName)");
+                       WriteLine (typeMap.TypeData.CSharpFullName + " " + metName + " (string xmlName)");
                        WriteLineInd ("{");
                        GenerateGetSingleEnumValue (typeMap, "xmlName");
                        WriteLineUni ("}");
@@ -2314,10 +2425,10 @@ namespace System.Xml.Serialization
                        WriteLineInd ("{");
                        foreach (EnumMap.EnumMapMember mem in map.Members)
                        {
-                               WriteLine ("case " + GetLiteral (mem.XmlName) + ": return " + typeMap.TypeFullName + "." + mem.EnumName + ";");
+                               WriteLine ("case " + GetLiteral (mem.XmlName) + ": return " + typeMap.TypeData.CSharpFullName + ".@" + mem.EnumName + ";");
                        }
                        WriteLineInd ("default:");
-                       WriteLine ("throw CreateUnknownConstantException (" + val + ", typeof(" + typeMap.TypeFullName + "));");
+                       WriteLine ("throw CreateUnknownConstantException (" + val + ", typeof(" + typeMap.TypeData.CSharpFullName + "));");
                        Unindent ();
                        WriteLineUni ("}");
                }
@@ -2328,13 +2439,13 @@ namespace System.Xml.Serialization
                        WriteLine ("if (Reader.NodeType == XmlNodeType.Element)");
                        WriteLineInd ("{");
                        WriteLine ("if (Reader.LocalName == " + GetLiteral (typeMap.ElementName) + " && Reader.NamespaceURI == " + GetLiteral (typeMap.Namespace) + ")");
-                       WriteLine ("\treturn ReadSerializable (new " + typeMap.TypeData.FullTypeName + "());");
+                       WriteLine (String.Format ("\treturn ({0}) ReadSerializable (({0}) Activator.CreateInstance(typeof({0}), true));", typeMap.TypeData.CSharpFullName));
                        WriteLine ("else");
                        WriteLine ("\tthrow CreateUnknownNodeException ();");
                        WriteLineUni ("}");
                        WriteLine ("else UnknownNode (null);");
                        WriteLine ("");
-                       WriteLine ("return null;");
+                       WriteLine ("return default (" + typeMap.TypeData.CSharpFullName + ");");
                }
 
                void GenerateReadInitCallbacks ()
@@ -2367,7 +2478,7 @@ namespace System.Xml.Serialization
                        foreach (XmlMapping map in _fixupCallbacks)
                        {
                                bool isList = map is XmlMembersMapping;
-                               string tname = !isList ? ((XmlTypeMapping)map).TypeFullName : "object[]";
+                               string tname = !isList ? ((XmlTypeMapping)map).TypeData.CSharpFullName : "object[]";
                                WriteLine ("void " + GetFixupCallbackName (map) + " (object obfixup)");
                                WriteLineInd ("{");                                     
                                WriteLine ("Fixup fixup = (Fixup)obfixup;");
@@ -2520,7 +2631,7 @@ namespace System.Xml.Serialization
                
                string GetRootTypeName ()
                {
-                       if (_typeMap is XmlTypeMapping) return ((XmlTypeMapping)_typeMap).TypeFullName;
+                       if (_typeMap is XmlTypeMapping) return ((XmlTypeMapping)_typeMap).TypeData.CSharpFullName;
                        else return "object[]";
                }
 
@@ -2546,7 +2657,7 @@ namespace System.Xml.Serialization
                
                string GetUniqueName (string uniqueGroup, object ob, string name)
                {
-                       name = name.Replace ("[]","_array");
+                       name = CodeIdentifier.MakeValid (name.Replace ("[]","_array"));
                        Hashtable names = (Hashtable) _uniqueNames [uniqueGroup];
                        if (names == null) {
                                names = new Hashtable ();
@@ -2605,7 +2716,7 @@ namespace System.Xml.Serialization
                
                string GetUniqueClassName (string s)
                {
-                       return classNames.AddUnique (s, null);
+                       return classNames.AddUnique (CodeIdentifier.MakeValid (s), null);
                }
                
                string GetReadObjectCall (XmlTypeMapping typeMap, string isNullable, string checkType)
@@ -2619,45 +2730,71 @@ namespace System.Xml.Serialization
                string GetFillListName (TypeData td)
                {
                        if (!_listsToFill.Contains (td)) _listsToFill.Add (td);
-                       return GetUniqueName ("fl", td, "Fill_" + td.TypeName);
+                       return GetUniqueName ("fl", td, "Fill_" + CodeIdentifier.MakeValid (td.CSharpName));
                }
                
                string GetCast (TypeData td, TypeData tdval, string val)
                {
-                       if (td.FullTypeName == tdval.FullTypeName) return val;
+                       if (td.CSharpFullName == tdval.CSharpFullName) return val;
                        else return GetCast (td, val);
                }
 
                string GetCast (TypeData td, string val)
                {
-                       return "((" + td.FullTypeName + ") " + val + ")";
+                       return "((" + td.CSharpFullName + ") " + val + ")";
                }
 
                string GetCast (Type td, string val)
                {
-                       return "((" + td.FullName + ") " + val + ")";
+                       return "((" + ToCSharpFullName (td) + ") " + val + ")";
                }
 
                string GetTypeOf (TypeData td)
                {
-                       return "typeof(" + td.FullTypeName + ")";
+                       return "typeof(" + td.CSharpFullName + ")";
                }
                
                string GetTypeOf (Type td)
                {
-                       return "typeof(" + td.FullName.Replace ('+','.') + ")";
+                       return "typeof(" + ToCSharpFullName (td) + ")";
                }
                
                string GetLiteral (object ob)
                {
                        if (ob == null) return "null";
                        if (ob is string) return "\"" + ob.ToString().Replace("\"","\"\"") + "\"";
+                       if (ob is DateTime) return "new DateTime (" + ((DateTime) ob).Ticks + ")";
+#if NET_2_0
+                       if (ob is DateTimeOffset) return "new DateTimeOffset (" + ((DateTimeOffset) ob).Ticks + ")";
+#endif
+                       if (ob is TimeSpan) return "new TimeSpan (" + ((TimeSpan) ob).Ticks + ")";
                        if (ob is bool) return ((bool)ob) ? "true" : "false";
                        if (ob is XmlQualifiedName) {
                                XmlQualifiedName qn = (XmlQualifiedName)ob;
                                return "new XmlQualifiedName (" + GetLiteral(qn.Name) + "," + GetLiteral(qn.Namespace) + ")";
                        }
-                       if (ob is Enum) return ob.GetType () + "." + ob;
+                       if (ob is Enum) {
+                               string typeName = ToCSharpFullName (ob.GetType ());
+                               StringBuilder sb = new StringBuilder ();
+                               string namedValue = Enum.Format (ob.GetType (), ob, "g");
+                               string[] names = namedValue.Split (',');
+                               foreach (string name in names) {
+                                       // individual named constants can be seperated by a comma
+                                       // combined with some additional whitespace characters
+                                       string cleanName = name.Trim ();
+                                       if (cleanName.Length == 0)
+                                               continue;
+
+                                       if (sb.Length > 0)
+                                               sb.Append (" | ");
+
+                                       sb.Append (typeName);
+                                       sb.Append ('.');
+                                       sb.Append (cleanName);
+                               }
+                               return sb.ToString ();
+                       }
+
                        return (ob is IFormattable) ? ((IFormattable) ob).ToString (null, CultureInfo.InvariantCulture) : ob.ToString ();
                }
                
@@ -2738,7 +2875,11 @@ namespace System.Xml.Serialization
                public string WriterClassName;
                public string WriteMethodName;
                public string Namespace;
+#if NET_2_0            
                public string SerializerClassName;
+#endif         
+               public string BaseSerializerClassName;
+               public string ImplementationClassName;
        }
        
 }