2005-09-21 Lluis Sanchez Gual <lluis@novell.com>
[mono.git] / mcs / class / System.Runtime.Serialization.Formatters.Soap / System.Runtime.Serialization.Formatters.Soap / SoapReader.cs
old mode 100755 (executable)
new mode 100644 (file)
index e5a9088..d036174
-using System;
-using System.Xml;
-using System.Reflection;
-
-namespace System.Runtime.Serialization.Formatters.Soap
-{      
-
-       public enum ReferenceTypes {Array_Type, Object_Type, Interface_Type, Delegate_Type, String_Type};
-
-       internal class SoapReader
-       {
-               /******const section******/
-               const string xmlns_SOAP_ENC     = "http://schemas.xmlsoap.org/soap/encoding/";
-               const string xmlns_SOAP_ENV     = "http://schemas.xmlsoap.org/soap/envelope/";
-
-               const string cSoapRef           = "href";
-               const string cObjectRef         = "ref-";
-               const string cId                = "id";
-               const string cXsiNull           = "xsi:null";
-               const string basicassembly      = "mscorlib";
-               const string startxmlns         = "xmlns:a";            
-               const string Systemns           = "http://schemas.microsoft.com/clr/ns/System";         
-               const string cDefaultValue      = "_0x00_";
-               /******Array's serialization section******/
-               const string cItem           = "item";
-               const string cSoapEncArray   = "SOAP-ENC:Array";
-               const string cSoapArrayType  = "SOAP-ENC:arrayType"; 
-               const string cXsiType        = "xsi:type";
-               const string cNullObject     = "xsi:null=\"1\"/";
-               /******Delegate's serialization section******/
-               const string cDelegateSerClass  = "DelegateSerializationHolder";
-               const string cDelegateType      = "DelegateType";
-               const string cDelegateAssembly  = "DelegateAssembly";
-               /******fields's section******/          
-               public XmlDocument FXmlDoc;             
-               public XmlElement  DeepElement; //the current Xml Struct Element
-               //public Utils       FUtils;
-
-               public SoapReader()
-               {               
-                       //FUtils= new Utils();
-               }
-
-               /**Reference Types reader**/
-               public int ReadObjectIndexFromXml(string ObjectElemt)
-               {
-                       XmlNodeList ObjectElement= FXmlDoc.DocumentElement.GetElementsByTagName(ObjectElemt);
-                       XmlElement FCurrentElement= (XmlElement)ObjectElement.Item(0);
-                       string refid= (FCurrentElement).GetAttribute(cId);
-                       int startindex= refid.IndexOf("-");
-                       refid= refid.Substring(startindex + 1, refid.Length - startindex - 1);             
-                       return Convert.ToInt32(refid);
-               }               
-
-               private string ReadReferenceFullNameFromXmlNode(XmlNode ReferenceNode)
-               {
-                       int StartIndex= ReferenceNode.Name.IndexOf(":");
-                       string ClassName= ReferenceNode.Name.Substring(StartIndex + 1, ReferenceNode.Name.Length - StartIndex - 1);             
-                       string AttributeName= FXmlDoc.DocumentElement.Attributes.GetNamedItem("xmlns:" + ReferenceNode.Name.Substring(0, StartIndex)).Value;
-                       StartIndex= AttributeName.LastIndexOf("/");                     
-                       string TempStr= AttributeName.Substring(0, StartIndex);
-                       StartIndex= TempStr.LastIndexOf("/");
-                       string ReferenceFullName= TempStr.Substring(StartIndex + 1, TempStr.Length - StartIndex - 1);
-                       return ReferenceFullName + "." + ClassName;                     
-               }
-
-               public string ReadReferenceFullNameFromXml(string RefereneId)
-               {
-                       string RefId= cObjectRef + RefereneId;
-                       XmlNodeList NodeList = FXmlDoc.DocumentElement.GetElementsByTagName("Body", xmlns_SOAP_ENV).Item(0).ChildNodes;
-                       bool Continue= true;
-                       int index= 0;
-                       string Result= "";
-                       while((Continue)&&(index <= NodeList.Count - 1))
-                       {
-                               XmlElement ActElement= (XmlElement)NodeList.Item(index);
-                               if(ActElement.GetAttribute("id")== RefId)//the attributes match
-                               {
-                                       Result= ReadReferenceFullNameFromXmlNode(ActElement);
-                                       Continue= false;
-                               }
-                               else
-                                       index++;
-                       }
-                       return Result;
-               }
-
-               /**ReadReferenceIndexFromXml**/
-               public int ReadReferenceIndexFromXml(string FieldName, XmlElement ParentElement)
-               {
-                       XmlElement FieldElement= (XmlElement)ParentElement.GetElementsByTagName(FieldName).Item(0);               
-                       if(FieldElement.GetAttribute(cXsiNull)== "") //if it is not a null field
-                       {
-                               string hrefvalue= FieldElement.GetAttribute(cSoapRef);
-                               int StartIndex= hrefvalue.IndexOf("-");
-                               return Convert.ToInt32(hrefvalue.Substring(StartIndex + 1, hrefvalue.Length - 1 - StartIndex));
-                       }
-                       else
-                               return -1;
-               }
-
-               public int  ReadReferenceIndexFromXml(int ItemIndex, XmlElement ParentElement)
-               {
-                       XmlElement FieldElement= (XmlElement)ParentElement.ChildNodes.Item(ItemIndex);
-                       if(FieldElement.GetAttribute(cXsiNull)== "") //if it is not a null field
-                       {
-                               string hrefvalue= FieldElement.GetAttribute(cSoapRef);
-                               int StartIndex= hrefvalue.IndexOf("-");
-                               return Convert.ToInt32(hrefvalue.Substring(StartIndex + 1, hrefvalue.Length - 1 - StartIndex));
-                       }
-                       else
-                               return -1;
-               }
-
-
-
-               /**String reader**/
-               public int ReadStringIdFromXml(/*string XmlParentElement, */string FieldName,/* string XmlParentElementId, */XmlElement ParentElement)
+// created on 24/04/2003 at 15:35\r
+//\r
+//     System.Runtime.Serialization.Formatters.Soap.SoapReader\r
+//\r
+//     Authors:\r
+//             Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
+//\r
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+\r
+using System;\r
+using System.IO;\r
+using System.Xml;\r
+using System.Xml.Schema;\r
+using System.Reflection;\r
+using System.Collections;\r
+using System.Runtime.Remoting;\r
+using System.Runtime.Serialization;\r
+using System.Runtime.Remoting.Messaging;\r
+using System.Runtime.Remoting.Metadata;\r
+\r
+namespace System.Runtime.Serialization.Formatters.Soap {\r
+       internal sealed class SoapReader {\r
+\r
+               #region Fields\r
+\r
+               private SerializationBinder _binder;\r
+               private SoapTypeMapper mapper;\r
+               private ObjectManager objMgr;\r
+               private StreamingContext _context;\r
+               private long _nextAvailableId = long.MaxValue;\r
+               private ISurrogateSelector _surrogateSelector;\r
+               private XmlTextReader xmlReader;\r
+               private Hashtable _fieldIndices;\r
+               private long _topObjectId = 1;\r
+               \r
+               class TypeMetadata\r
+               {\r
+                       public MemberInfo[] MemberInfos;\r
+                       public Hashtable Indices;\r
+               }\r
+\r
+               #endregion\r
+\r
+               #region Properties\r
+\r
+               private long NextAvailableId\r
+               {\r
+                       get \r
+                       {\r
+                               _nextAvailableId--;\r
+                               return _nextAvailableId;\r
+                       }\r
+               }\r
+\r
+               #endregion\r
+\r
+               #region Constructors\r
+               \r
+               public SoapReader(SerializationBinder binder, ISurrogateSelector selector, StreamingContext context) \r
+               {\r
+                       _binder = binder;\r
+                       objMgr = new ObjectManager(selector, context);\r
+                       _context = context;\r
+                       _surrogateSelector = selector;\r
+                       _fieldIndices = new Hashtable();\r
+               }\r
+\r
+               #endregion\r
+\r
+               #region Public Methods\r
+\r
+               public object Deserialize(Stream inStream, ISoapMessage soapMessage) \r
                {
-                       XmlElement FieldElement= (XmlElement)ParentElement.GetElementsByTagName(FieldName).Item(0);//(XmlElement)GetCurrentElement(XmlParentElement, XmlParentElementId).GetElementsByTagName(FieldName).Item(0);
-                       if(FieldElement.GetAttribute(cId)== "")
-                               return ReadReferenceIndexFromXml(FieldName, ParentElement);
-                       else
-                               return ReadFieldIdValueFromXml(FieldName, ParentElement);
-               }
-
-               public int ReadStringIdFromXml(int ItemIndex, XmlElement ParentElement)
-               {
-                       XmlElement FieldElement= (XmlElement)ParentElement.ChildNodes.Item(ItemIndex);
-                       string StrId= FieldElement.GetAttribute(cId);
-                       if(StrId == "")
-                               return ReadReferenceIndexFromXml(ItemIndex, ParentElement);
-                       else
-                               return ReadFieldIdValueFromXml(ItemIndex, ParentElement);
-               }
-               
-               public string ReadStringTypeFromXml(string FieldName, XmlElement ParentElement)
-               {
-                       XmlNode XmlField= ParentElement.GetElementsByTagName(FieldName).Item(0);
-                       if(XmlField!= null)
-                               return XmlField.InnerXml;
-                       else
-                               return null;
-               }
-
-               public string ReadStringTypeFromXml(int ItemIndex, XmlElement ParentElement)
-               {
-                       XmlNode XmlField= ParentElement.ChildNodes.Item(ItemIndex);
-                       if(XmlField!= null)
-                               return XmlField.InnerXml;
-                       else
-                               return null;
-               }
-
-               /**Delegates reader**/
-               public string GetDelegateElementName(int DelegateId)
-               {                                       
-                       XmlAttributeCollection XmlAttrCollection= FXmlDoc.DocumentElement.Attributes;
-                       bool Continue= true;
-                       int i= 0;
-                       string ItemName= "";
-                       while((Continue)&&(i<= XmlAttrCollection.Count - 1))
-                       {
-                               string AttrValue= XmlAttrCollection.Item(i).Value;                              
-                               if(AttrValue == Systemns)
-                               {
-                                       ItemName= XmlAttrCollection.Item(i).Name;
-                                       ItemName= ItemName.Substring(ItemName.LastIndexOf(":") + 1, ItemName.Length - 1 - ItemName.LastIndexOf(":"));
-                                       Continue= false;
-                               }
-                               i++;
-                       }
-                       return ItemName + ":" + cDelegateSerClass;
-               }
-
-               public Type GetDelegateTypeFromXml(XmlElement ParentElement)
-               {
-                       string DelegateAssembly= ParentElement.GetElementsByTagName(cDelegateAssembly).Item(0).InnerXml;
-                       DelegateAssembly= DelegateAssembly.Substring(0, DelegateAssembly.IndexOf(","));
-                       string DelegateType= ParentElement.GetElementsByTagName(cDelegateType).Item(0).InnerXml;
-                       return Assembly.Load(DelegateAssembly).GetType(DelegateType);              
-               }
-        
-               /**Arrays reader**/
-               public string ReadArrayTypeFromXml(XmlElement ArrayElement, out string AssemblyName)
-               {          
-                       string ArrayTypeAttr= ArrayElement.GetAttribute(cSoapArrayType);
-                       int StartIndex= ArrayTypeAttr.LastIndexOf(":");
-                       string Result;
-                       if(ArrayTypeAttr.Substring(0, 4) == "xsd:")     
-                       {
-                               Result= "System";
-                               string CLRType= GetCLRTypeFromXsdType(ArrayTypeAttr.Substring(0, ArrayTypeAttr.IndexOf("[")));
-                               StartIndex= ArrayTypeAttr.IndexOf("[");
-                               Result= "System." + CLRType + ArrayTypeAttr.Substring(StartIndex, ArrayTypeAttr.Length - StartIndex);
-                               AssemblyName= basicassembly;
-                       }
-                       else
-                       {
-                               AssemblyName= ReadAssemblyNameFromXml(ArrayTypeAttr);                           
-                               string NsIndex= ArrayTypeAttr.Substring(1, StartIndex - 1);
-                               Result= ReadNamespaceFromXml(NsIndex);                          
-                               Result= Result +   "." + ArrayTypeAttr.Substring(StartIndex + 1, ArrayTypeAttr.Length - StartIndex - 1);
-                       }                 
-                       return Result;
-               } 
-                       
-
-               public bool IsArrayItemValueType(XmlElement ParentElement, int ItemIndex, ref bool IsNull, ref bool IsStruct)
-               {
-                       XmlElement ArrayItem= (XmlElement)ParentElement.ChildNodes.Item(ItemIndex);               
-                       bool Result= false;
-                       if(ArrayItem.GetAttribute(cXsiNull)== "")//is not null
-                       {
-                               IsNull= false;
-                               if((ArrayItem.InnerXml != "")&&(ArrayItem.GetAttribute(cId) == ""))
-                               {
-                                       Result= true; 
-                                       if(ArrayItem.InnerXml.Substring(0, 1)== "<") //is an atruct
-                                               IsStruct= true;
-                               }
-                       }
-                       else
-                               IsNull= true;                           
-                       return Result;
-               }
-
-               public ValueType ReadArrayItemSimpleTypeFromXml(XmlElement ParentElement, int ItemIndex, string ItemTypeName)
-               {
-                       XmlElement ArrayItem= (XmlElement)ParentElement.ChildNodes.Item(ItemIndex);//at this moment you know that this field is a value type
-                       string ItemValue= ArrayItem.InnerXml;
-                       string XsiType= ((XmlElement)ArrayItem).GetAttribute(cXsiType);
-                       if(XsiType != "")
-                               return GetValueTypeFromXsdType(XsiType, ItemValue);
-                       else
-                               return GetValueTypeFromString(ItemTypeName, ItemValue);
-               }
-
-               public ReferenceTypes GetReferenceType(string FieldName, XmlElement ParentElement, ref XmlElement RefElement)
-               {          
-                       XmlElement ArrayItem= (XmlElement)ParentElement.GetElementsByTagName(FieldName).Item(0);
-                       RefElement= ArrayItem;
-                       ReferenceTypes Result= ReferenceTypes.Object_Type;
-                       if(ArrayItem.GetAttribute(cId) != "") //is an string 
-                               Result= ReferenceTypes.String_Type;
-                       else
-                       {
-                               string RefIndex= ArrayItem.GetAttribute(cSoapRef);
-                               if(RefIndex != "") //is a other reference
-                               {               
-                                       int Id= RefIndex.IndexOf("-");
-                                       Id= Convert.ToInt32(RefIndex.Substring(Id + 1, RefIndex.Length - 1 - Id));
-                                       string RefName= GetReferenceNameFromId(Convert.ToInt32(Id), ref RefElement);                                    
-                                       if(RefName== cSoapEncArray) //is an array 
-                                               Result= ReferenceTypes.Array_Type;
-                                       else
-                                               if(RefName == "")
-                                               Result= ReferenceTypes.String_Type;
-                                       else
-                                       {
-                                               if((RefName.IndexOf(cDelegateSerClass) != -1)&&(RefElement.ChildNodes.Item(0).Name== cDelegateType)) //is a delegates
-                                                       Result= ReferenceTypes.Delegate_Type;
-                                               else
-                                                       Result= ReferenceTypes.Object_Type;
-                                       }
-                               }
-                       }        
-                       return Result;
-               }
-
-               public ReferenceTypes GetReferenceType(int index, XmlElement ParentElement, ref XmlElement RefElement)
-               {
-                       XmlElement ArrayItem= (XmlElement)ParentElement.ChildNodes.Item(index);
-                       RefElement= ArrayItem;
-                       ReferenceTypes Result= ReferenceTypes.Object_Type;
-                       if(ArrayItem.GetAttribute(cId) != "") //is an string 
-                               Result= ReferenceTypes.String_Type;
-                       else
-                       {
-                               string RefIndex= ArrayItem.GetAttribute(cSoapRef);
-                               if(RefIndex != "") //is a other reference
-                               {               
-                                       int Id= RefIndex.IndexOf("-");
-                                       Id= Convert.ToInt32(RefIndex.Substring(Id + 1, RefIndex.Length - 1 - Id));
-                                       string RefName= GetReferenceNameFromId(Convert.ToInt32(Id), ref RefElement);
-                                       if(RefName== cSoapEncArray) //is an array 
-                                               Result= ReferenceTypes.Array_Type;
-                                       else
-                                               if(RefName == "")
-                                               Result= ReferenceTypes.String_Type;
+                       ArrayList headers = null;\r
+                       xmlReader = new XmlTextReader(inStream);\r
+                       xmlReader.WhitespaceHandling = WhitespaceHandling.None;\r
+                       mapper = new SoapTypeMapper(_binder);\r
+\r
+                       try\r
+                       {\r
+                               // SOAP-ENV:Envelope\r
+                               xmlReader.MoveToContent();\r
+                               xmlReader.ReadStartElement ();
+                               xmlReader.MoveToContent();
+                               
+                               // Read headers
+                               while (!(xmlReader.NodeType == XmlNodeType.Element && xmlReader.LocalName == "Body" && xmlReader.NamespaceURI == SoapTypeMapper.SoapEnvelopeNamespace))
+                               {\r
+                                       if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.LocalName == "Header" && xmlReader.NamespaceURI == SoapTypeMapper.SoapEnvelopeNamespace)\r
+                                       {\r
+                                               if (headers == null) headers = new ArrayList ();\r
+                                               DeserializeHeaders (headers);\r
+                                       }\r
                                        else
-                                       {
-                                               if((RefName.IndexOf(cDelegateSerClass) != -1)&&(RefElement.ChildNodes.Item(0).Name== cDelegateType)) //is a delegates
-                                                       Result= ReferenceTypes.Delegate_Type;
-                                               else
-                                                       Result= ReferenceTypes.Object_Type;
-                                       }
+                                               xmlReader.Skip ();\r
+                                       xmlReader.MoveToContent();\r
                                }
-                       }        
-                       return Result;
-               }
-
-               public string GetFullObjectLocation(string XsdType, out string NsName)
-               {
-                       string AssemblyName= ReadAssemblyNameFromXml(XsdType);
-                       int StartIndex= XsdType.LastIndexOf(":");
-                       string NsIndex= XsdType.Substring(1, StartIndex - 1);
-                       NsName= ReadNamespaceFromXml(NsIndex);
-                       NsName= NsName +   "." + XsdType.Substring(StartIndex + 1, XsdType.Length - StartIndex - 1);
-                       return AssemblyName; 
-               }
-
-               private ValueType GetValueTypeFromNotSimpleType(string XsdType, string ItemValue)
-               {
-                       string NsName;
-                       string AssemblyName= GetFullObjectLocation(XsdType, out NsName);                    
-                       Type ItemType= Assembly.Load(AssemblyName).GetType(NsName);
-                       object Result;
-                       if(ItemType.IsEnum)//is an enum
-                               Result= Enum.Parse(ItemType, ItemValue);
-                       else //is a char
-                       {
-                               if(ItemValue == cDefaultValue)                          
-                                       Result=  new char();
-                               else                             
-                                       Result= Char.Parse(ItemValue);                          
-                       }
-                       return (ValueType)Result;             
-               }
-
-               private string GetCLRTypeFromXsdType(string XsdType)
-               {
-                       string Result= "";
-                       switch(XsdType)
-                       {                               
-                               case "xsd:int"          :Result= "Int32";
-                                       break;
-                               case "xsd:short"        :Result= "Int16";
-                                       break;
-                               case "xsd:long"         :Result= "Int64";
-                                       break;
-                               case "xsd:unsignedInt"  :Result= "UInt32";
-                                       break;
-                               case "xsd:unsignedShort":Result= "UInt16";
-                                       break;
-                               case "xsd:unsignedLong" :Result= "UInt64";
-                                       break;
-                               case "xsd:byte"         :Result= "Byte";
-                                       break;
-                               case "xsd:decimal"      :Result= "Decimal";
-                                       break;
-                               case "xsd:double"       :Result= "Double"; 
-                                       break;                          
-                               case "xsd:boolean"      :Result= "Boolean";
-                                       break;
-                               case "xsd:dateTime"     :Result= "DateTime";
-                                       break;
-                               case "xsd:string"       :Result= "String";
-                                       break;
-                       }
-                       return Result;
-               }
-
-               public ValueType GetValueTypeFromXsdType(string XsdType, string ItemValue)
-               {
-                       ValueType Result= null;
-                       switch(XsdType)
-                       {                               
-                               case "xsd:int"          : Result= Convert.ToInt32(ItemValue);
-                                       break;
-                               case "xsd:short"        :Result= Convert.ToInt16(ItemValue);
-                                       break;
-                               case "xsd:long"         :Result= Convert.ToInt64(ItemValue);
-                                       break;
-                               case "xsd:unsignedInt"  :Result= Convert.ToUInt32(ItemValue);
-                                       break;
-                               case "xsd:unsignedShort":Result= Convert.ToUInt16(ItemValue);
-                                       break;
-                               case "xsd:unsignedLong" :Result= Convert.ToUInt64(ItemValue);
-                                       break;
-                               case "xsd:byte"         :Result= Convert.ToByte(ItemValue);
-                                       break;
-                               case "xsd:decimal"      :Result= Convert.ToDecimal(ItemValue);
-                                       break;
-                               case "xsd:double"       :Result= Convert.ToDouble(ItemValue); 
-                                       break;                          
-                               case "xsd:boolean"      :Result= Convert.ToBoolean(ItemValue);
-                                       break;
-                               case "xsd:dateTime"     :Result= Convert.ToDateTime(ItemValue);
-                                       break;
-                               default                 :Result= GetValueTypeFromNotSimpleType(XsdType, ItemValue);
-                                       break;
-                       }
-                       return Result;
-               }
-
-               /**Value types reader**/
-               public string ReadValueTypeFromXml(string FieldName, XmlElement ParentElement/*string ParentElement, string ParentElementId*/)
-               {
-                       XmlNode XmlField= ParentElement.GetElementsByTagName(FieldName).Item(0);///*FCurrentElement*/GetCurrentElement(ParentElement, ParentElementId).GetElementsByTagName(FieldName).Item(0); 
-                       if(XmlField!= null)
-                               return XmlField.InnerXml;
-                       else
-                               return null;
-               }
+                               \r
+                               // SOAP-ENV:Body\r
+                               xmlReader.ReadStartElement();\r
+                               xmlReader.MoveToContent();\r
+\r
+                               // The root object\r
+                               if (soapMessage != null)\r
+                               {\r
+                                       if (DeserializeMessage (soapMessage)) {\r
+                                               _topObjectId = NextAvailableId;\r
+                                               RegisterObject (_topObjectId, soapMessage, null, 0, null, null);\r
+                                       }\r
+                                       xmlReader.MoveToContent();\r
+                                       \r
+                                       if (headers != null)\r
+                                               soapMessage.Headers = (Header[]) headers.ToArray (typeof(Header));\r
+                               }\r
+                               \r
+                               while (xmlReader.NodeType != XmlNodeType.EndElement)\r
+                                       Deserialize();\r
+                                       \r
+                               // SOAP-ENV:Body\r
+                               xmlReader.ReadEndElement ();\r
+                               xmlReader.MoveToContent();\r
+\r
+                               // SOAP-ENV:Envelope\r
+                               xmlReader.ReadEndElement ();\r
+                       }\r
+                       finally \r
+                       {\r
+                               if(xmlReader != null) xmlReader.Close();\r
+                       }\r
+\r
+                       return TopObject;\r
+               }\r
+               \r
+               #endregion
                
-               public ValueType GetValueTypeFromString(string fieldtype, string fieldvalue)
-               {
-                       ValueType result= null;
-                       switch(fieldtype)
-                       {
-                               case "Int32"    : result= Convert.ToInt32(fieldvalue);
-                                       break;
-                               case "Int16"    : result= Convert.ToInt16(fieldvalue);
-                                       break;
-                               case "Int64"    : result= Convert.ToInt64(fieldvalue);
-                                       break;
-                               case "UInt32"   : result= Convert.ToUInt32(fieldvalue);
-                                       break;
-                               case "UInt16"   : result= Convert.ToUInt16(fieldvalue);
-                                       break;
-                               case "UInt64"   : result= Convert.ToUInt64(fieldvalue);
-                                       break;
-                               case "Byte"     : result= Convert.ToByte(fieldvalue);
-                                       break;
-                               case "Decimal"  : result= Convert.ToDecimal(fieldvalue);
-                                       break;
-                               case "Double"   : result= Convert.ToDouble(fieldvalue);
-                                       break;                          
-                               case "Boolean"  : result= Convert.ToBoolean(fieldvalue);
-                                       break;
-                               case "DateTime" : result= Convert.ToDateTime(fieldvalue);
-                                       break;
-                               case "Char"     : result= Convert.ToChar(fieldvalue);
-                                       break;
-                       }
-                       return result;
-               }               
-
-               /**Structs reader**/
-               public string ReadStructValueFieldFromXml(/*string XmlParentElement, */string FieldName, XmlElement ParentElement/*string XmlParentElementId, */, string StructName, bool NestedStruct)
-               {
-                       XmlElement FieldElement;                
-                       FieldElement= (XmlElement)ParentElement.GetElementsByTagName(FieldName).Item(0);                        
-                       if(FieldElement != null)
-                               return FieldElement.InnerXml;
-                       else
-                               return null;
+               public SoapTypeMapper Mapper {
+                       get { return mapper; }
                }
-
-               public void ReadStructParentElementFromXml(string StructName, XmlElement ParentElement, bool NestedStruct)
-               {
-                       if(!NestedStruct)//is not a nested struct
-                               DeepElement= (XmlElement)ParentElement.GetElementsByTagName(StructName).Item(0);//GetCurrentElement(XmlParentElement, XmlParentElementId).GetElementsByTagName(StructName).Item(0);
-                       else                    
-                               DeepElement= (XmlElement)DeepElement.GetElementsByTagName(StructName).Item(0);
+               \r
+               public XmlTextReader XmlReader {
+                       get { return xmlReader; }
+               }\r
+\r
+               #region Private Methods\r
+\r
+               private object TopObject \r
+               {\r
+                       get \r
+                       {\r
+                               objMgr.DoFixups();\r
+                               objMgr.RaiseDeserializationEvent();\r
+                               return objMgr.GetObject(_topObjectId);\r
+                       }\r
+               }\r
+\r
+               private bool IsNull()\r
+               {\r
+                       string tmp = xmlReader["null", XmlSchema.InstanceNamespace];\r
+                       return (tmp == null || tmp == string.Empty)?false:true;\r
+               }\r
+\r
+               private long GetId()\r
+               {\r
+                       long id = 0;\r
+\r
+                       string strId = xmlReader["id"];\r
+                       if(strId == null || strId == String.Empty) return 0;\r
+                       id = Convert.ToInt64(strId.Substring(4));\r
+                       return id;\r
+               }\r
+\r
+               private long GetHref()\r
+               {\r
+                       long href = 0;\r
+                       \r
+                       string strHref = xmlReader["href"];\r
+                       if(strHref == null || strHref == string.Empty) return 0;\r
+                       href = Convert.ToInt64(strHref.Substring(5));\r
+                       return href;\r
+               }\r
+\r
+               private Type GetComponentType()\r
+               {\r
+                       string strValue = xmlReader["type", XmlSchema.InstanceNamespace];\r
+                       if(strValue == null) {\r
+                               if(GetId() != 0) return typeof(string);\r
+                               return null;\r
+                       }\r
+                       return GetTypeFromQName (strValue);\r
+               }\r
+\r
+               private bool DeserializeMessage(ISoapMessage message) \r
+               {\r
+                       string typeNamespace, assemblyName;\r
+\r
+                       if(xmlReader.Name == SoapTypeMapper.SoapEnvelopePrefix + ":Fault")\r
+                       {\r
+                               Deserialize();\r
+                               return false;\r
+                       }\r
+\r
+                       SoapServices.DecodeXmlNamespaceForClrTypeNamespace(\r
+                               xmlReader.NamespaceURI,\r
+                               out typeNamespace,\r
+                               out assemblyName);\r
+                       message.MethodName = xmlReader.LocalName;\r
+                       message.XmlNameSpace = xmlReader.NamespaceURI;\r
+\r
+                       ArrayList paramNames = new ArrayList();\r
+                       ArrayList paramValues = new ArrayList();\r
+                       long paramValuesId = NextAvailableId;\r
+                       int[] indices = new int[1];\r
+\r
+                       if (!xmlReader.IsEmptyElement)\r
+                       {\r
+                               int initialDepth = xmlReader.Depth;\r
+                               xmlReader.Read();\r
+                               int i = 0;\r
+                               while(xmlReader.Depth > initialDepth) \r
+                               {\r
+                                       long paramId, paramHref;\r
+                                       object objParam = null;\r
+                                       paramNames.Add (xmlReader.Name);\r
+                                       Type paramType = null;\r
+                                       \r
+                                       if (message.ParamTypes != null) {\r
+                                               if (i >= message.ParamTypes.Length)\r
+                                                       throw new SerializationException ("Not enough parameter types in SoapMessages");\r
+                                               paramType = message.ParamTypes [i];\r
+                                       }\r
+                                       \r
+                                       indices[0] = i;\r
+                                       objParam = DeserializeComponent(\r
+                                               paramType,\r
+                                               out paramId,\r
+                                               out paramHref,\r
+                                               paramValuesId,\r
+                                               null,\r
+                                               indices);\r
+                                       indices[0] = paramValues.Add(objParam);\r
+                                       if(paramHref != 0) \r
+                                       {\r
+                                               RecordFixup(paramValuesId, paramHref, paramValues.ToArray(), null, null, null, indices);\r
+                                       }\r
+                                       else if(paramId != 0) \r
+                                       {\r
+//                                             RegisterObject(paramId, objParam, null, paramValuesId, null, indices);\r
+                                       }\r
+                                       else \r
+                                       {\r
+                                       }\r
+                                       i++;\r
+                               }\r
+                               xmlReader.ReadEndElement();\r
+                       }\r
+                       else\r
+                       {\r
+                               xmlReader.Read();\r
+                       }\r
+                       \r
+                       message.ParamNames = (string[]) paramNames.ToArray(typeof(string));\r
+                       message.ParamValues = paramValues.ToArray();\r
+                       RegisterObject(paramValuesId, message.ParamValues, null, 0, null, null);\r
+                       return true;\r
                }
-
-               /**Assemblies reader**/
-               public string GetAssemblyNameFromId(int id)
-               {                 
-                       XmlNodeList ObjList= ((XmlElement)FXmlDoc.DocumentElement.GetElementsByTagName("Body", xmlns_SOAP_ENV).Item(0)).ChildNodes;
-                       bool Continue= true;
-                       int index= 0;
-                       string AssemblyName= "";
-                       while((Continue)&&(index<= ObjList.Count - 1))
-                       {
-                               string refid= ((XmlElement)ObjList.Item(index)).GetAttribute(cId);                        
-                               int StartIndex= refid.IndexOf("-");
-                               refid=  refid.Substring(StartIndex + 1, refid.Length - 1 - StartIndex);
-                               if(refid== id.ToString())
-                               {
-                                       Continue= false;                                  
-                                       AssemblyName= ReadAssemblyNameFromXml(((XmlElement)ObjList.Item(index)).Name);
-                               }
-                               else
-                                       index++;
-                       }
-                       return AssemblyName;
+\r
+               void DeserializeHeaders (ArrayList headers)\r
+               {\r
+                       xmlReader.ReadStartElement ();\r
+                       xmlReader.MoveToContent ();\r
+                       \r
+                       while (xmlReader.NodeType != XmlNodeType.EndElement) \r
+                       {\r
+                               if (xmlReader.NodeType != XmlNodeType.Element) { xmlReader.Skip(); continue; }\r
+                               \r
+                               if (xmlReader.GetAttribute ("root", SoapTypeMapper.SoapEncodingNamespace) == "1")\r
+                                       headers.Add (DeserializeHeader ());\r
+                               else\r
+                                       Deserialize ();\r
+\r
+                               xmlReader.MoveToContent ();\r
+                       }\r
+                       \r
+                       xmlReader.ReadEndElement ();\r
                }
-
-               private string GetReferenceNameFromId(int id, ref XmlElement RefElement)
+               \r               Header DeserializeHeader ()
                {
-                       XmlNodeList ObjList= ((XmlElement)FXmlDoc.DocumentElement.GetElementsByTagName("Body", xmlns_SOAP_ENV).Item(0)).ChildNodes;
-                       bool Continue= true;
-                       int index= 0;
-                       string Result= "";
-                       while((Continue)&&(index<= ObjList.Count - 1))
-                       {
-                               string refid= ((XmlElement)ObjList.Item(index)).GetAttribute(cId);                        
-                               int StartIndex= refid.IndexOf("-");
-                               refid=  refid.Substring(StartIndex + 1, refid.Length - 1 - StartIndex);
-                               if(refid== id.ToString())
-                               {
-                                       Continue= false;                                  
-                                       Result= ((XmlElement)ObjList.Item(index)).Name;
-                                       RefElement= (XmlElement)ObjList.Item(index);
-                               }
-                               else
-                                       index++;
-                       }
-                       return Result;
-               }
-
-               public string ReadAssemblyNameFromXml(string ParentElementName)
-               {
-                       string RefName= ParentElementName.Substring(1, ParentElementName.LastIndexOf(":") - 1);
-                       string XmlNamespaceName= startxmlns + RefName;
-                       string AttributeName= FXmlDoc.DocumentElement.Attributes.GetNamedItem(XmlNamespaceName).Value;
-                       int StartIndex= AttributeName.LastIndexOf("/");
-                       string AssemblyName= AttributeName.Substring(StartIndex + 1, AttributeName.Length - StartIndex - 1);
-                       if(AssemblyName == "System")
-                               AssemblyName= basicassembly;
-                       return AssemblyName;
-               }
-
-               /**Namespace reader**/
-               public string ReadNamespaceFromXml(string ReferenceName)
-               {
-                       string XmlNamespaceName= startxmlns + ReferenceName; 
-                       string AttributeName= FXmlDoc.DocumentElement.Attributes.GetNamedItem(XmlNamespaceName).Value;
-                       int StartIndex= AttributeName.LastIndexOf("/");
-                       string Result= "";
-                       string NsName= AttributeName.Substring(StartIndex + 1, AttributeName.Length - StartIndex - 1);
-                       if(NsName == "System")
-                               Result= NsName;
-                       else
-                       {
-                               string TmpStr= AttributeName.Substring(0, StartIndex);
-                               StartIndex= TmpStr.LastIndexOf("/");
-                               Result= TmpStr.Substring(StartIndex + 1, TmpStr.Length - StartIndex - 1);
-                       }
-                       return Result;
-                 
-               }
-
-               /**Utils**/
-               public XmlElement GetCurrentElement(string ElementName, string ElementId)
-               {
-                       string RefId= cObjectRef + ElementId;
-                       XmlNodeList NodeList = ((XmlElement)FXmlDoc.DocumentElement.GetElementsByTagName("Body", xmlns_SOAP_ENV).Item(0)).GetElementsByTagName(ElementName);
-                       bool Continue= true;
-                       int index= 0;
-                       string Result= "";
-                       XmlElement ActElement = null;
-                       while((Continue)&&(index <= NodeList.Count - 1))
-                       {
-                               ActElement= (XmlElement)NodeList.Item(index);
-                               if(ActElement.GetAttribute("id")== RefId)//the attributes match
-                                       Continue= false;                                
-                               else
-                                       index++;
-                       }
-                       if(!Continue)
-                               return ActElement;
-                       else
-                               return null;
+                       Header h = new Header (xmlReader.LocalName, null);
+                       h.HeaderNamespace = xmlReader.NamespaceURI;\r
+                       h.MustUnderstand = xmlReader.GetAttribute ("mustUnderstand", SoapTypeMapper.SoapEnvelopeNamespace) == "1";\r
+                       \r
+                       object value;\r
+                       long fieldId, fieldHref;\r
+                       long idHeader = NextAvailableId;\r
+                       FieldInfo fieldInfo = typeof(Header).GetField ("Value");\r
+\r
+                       value = DeserializeComponent (null, out fieldId, out fieldHref, idHeader, fieldInfo, null);\r
+                       h.Value = value;\r
+\r
+                       if(fieldHref != 0 && value == null)\r
+                       {\r
+                               RecordFixup (idHeader, fieldHref, h, null, null, fieldInfo, null);\r
+                       }\r
+                       else if(value != null && value.GetType().IsValueType && fieldId != 0)\r
+                       {\r
+                               RecordFixup (idHeader, fieldId, h, null, null, fieldInfo, null);\r
+                       }\r
+                       else if(fieldId != 0)\r
+                       {\r
+                               RegisterObject (fieldId, value, null, idHeader, fieldInfo, null);\r
+                       }\r
+                       \r
+                       RegisterObject (idHeader, h, null, 0, null, null);\r
+                       return h;\r
+               }\r
+\r
+               \r
+               private object DeserializeArray(long id)\r
+               {\r
+                       // Special case for base64 byte arrays\r
+                       if (GetComponentType () == typeof(byte[])) {\r
+                               byte[] data = Convert.FromBase64String (xmlReader.ReadElementString());\r
+                               RegisterObject(id, data, null, 0, null, null);\r
+                               return data;\r
+                       }\r
+                       \r
+                       // Get the array properties\r
+                       string strArrayType = xmlReader["arrayType", SoapTypeMapper.SoapEncodingNamespace];
+                       string[] arrayInfo = strArrayType.Split(':');
+                       int arraySuffixInfo = arrayInfo[1].LastIndexOf('[');
+                       String arrayElementType = arrayInfo[1].Substring(0, arraySuffixInfo);
+                       String arraySuffix = arrayInfo[1].Substring(arraySuffixInfo);
+                       string[] arrayDims = arraySuffix.Substring(1,arraySuffix.Length-2).Trim().Split(',');
+                       int numberOfDims = arrayDims.Length;
+                       int[] lengths = new int[numberOfDims];
+                       \r
+                       for (int i=0; i < numberOfDims; i++)\r
+                       {\r
+                               lengths[i] = Convert.ToInt32(arrayDims[i]);\r
+                       }\r
+\r
+                       int[] indices = new int[numberOfDims];\r
+\r
+                       // Create the array\r
+                       Type arrayType = mapper.GetType (arrayElementType, xmlReader.LookupNamespace(arrayInfo[0]));\r
+                       Array array = Array.CreateInstance(\r
+                               arrayType,\r
+                               lengths);
+\r
+                       for(int i = 0; i < numberOfDims; i++) \r
+                       {\r
+                               indices[i] = array.GetLowerBound(i);\r
+                       }\r
+\r
+                       // Deserialize the array items\r
+                       int arrayDepth = xmlReader.Depth;\r
+                       xmlReader.Read();\r
+                       while(xmlReader.Depth > arrayDepth)\r
+                       {\r
+                               Type itemType = GetComponentType();\r
+                               if(itemType == null) \r
+                                       itemType = array.GetType().GetElementType();\r
+                               long itemId, itemHref;\r
+\r
+                               object objItem = DeserializeComponent(itemType,\r
+                                       out itemId,\r
+                                       out itemHref,\r
+                                       id,\r
+                                       null,\r
+                                       indices);\r
+                               if(itemHref != 0)\r
+                               {\r
+                                       object obj = objMgr.GetObject(itemHref);\r
+                                       if(obj != null)\r
+                                               array.SetValue(obj, indices);\r
+                                       else\r
+                                               RecordFixup(id, itemHref, array, null, null, null, indices);\r
+                               }\r
+                               else if(objItem != null && objItem.GetType().IsValueType && itemId != 0)\r
+                               {\r
+                                       RecordFixup(id, itemId, array, null, null, null, indices);\r
+                               }\r
+                               else if(itemId != 0)\r
+                               {\r
+                                       RegisterObject(itemId, objItem, null, id, null, indices);\r
+                                       array.SetValue(objItem, indices);\r
+                               }\r
+                               else \r
+                               {\r
+                                       array.SetValue(objItem, indices);\r
+                               }\r
+\r
+                               // Get the next indice\r
+                               for(int dim = array.Rank - 1; dim >= 0; dim--)\r
+                               {\r
+                                       indices[dim]++;\r
+                                       if(indices[dim] > array.GetUpperBound(dim))\r
+                                       {\r
+                                               if(dim > 0)\r
+                                               {\r
+                                                       indices[dim] = array.GetLowerBound(dim);\r
+                                                       continue;\r
+                                               }\r
+                                               \r
+                                       }\r
+                                       break;\r
+                               }\r
+                       }\r
+\r
+                       RegisterObject(id, array, null, 0, null, null);\r
+                       xmlReader.ReadEndElement();\r
+                       return array;\r
+\r
+               }\r
+\r
+\r
+               private object Deserialize()\r
+               {\r
+                       object objReturn = null;\r
+                       Type type = mapper.GetType (xmlReader.LocalName, xmlReader.NamespaceURI);\r
+\r
+                       // Get the Id\r
+                       long id = GetId();\r
+                       id = (id == 0)?1:id;\r
+\r
+                       if(type == typeof(Array))\r
+                       {\r
+                               objReturn = DeserializeArray(id);\r
+                       }\r
+                       else\r
+                       {\r
+                               objReturn = DeserializeObject(type, id, 0, null, null);\r
+\r
+                       }\r
+\r
+                       return objReturn;\r
+               }\r
+\r
+\r
+               private object DeserializeObject(\r
+                       Type type, \r
+                       long id, \r
+                       long parentId, \r
+                       MemberInfo parentMemberInfo,\r
+                       int[] indices)\r
+               {\r
+                       SerializationInfo info = null;\r
+                       bool NeedsSerializationInfo = false;\r
+                       bool hasFixup;\r
+\r
+                       if(mapper.IsInternalSoapType (type)) \r
+                       {\r
+                               object obj = mapper.ReadInternalSoapValue (this, type);\r
+                               \r
+                               if(id != 0) \r
+                                       RegisterObject(id, obj, info, parentId, parentMemberInfo, indices);\r
+\r
+                               return obj;\r
+                       }\r
+                       object objReturn = \r
+                               FormatterServices.GetUninitializedObject(type);\r
+                       if(objReturn is ISerializable)\r
+                               NeedsSerializationInfo = true;\r
+\r
+                       if(_surrogateSelector != null && NeedsSerializationInfo == false)\r
+                       {\r
+                               ISurrogateSelector selector;\r
+                               ISerializationSurrogate surrogate = _surrogateSelector.GetSurrogate(\r
+                                       type,\r
+                                       _context,\r
+                                       out selector);\r
+                               NeedsSerializationInfo |= (surrogate != null);\r
+                       }\r
+\r
+                       if(NeedsSerializationInfo)\r
+                       {\r
+                               objReturn = \r
+                                       DeserializeISerializableObject(objReturn, id, out info, out hasFixup);\r
+                       }\r
+                       else\r
+                       {\r
+                               objReturn = \r
+                                       DeserializeSimpleObject(objReturn, id, out hasFixup);\r
+                               if(!hasFixup && objReturn is IObjectReference)\r
+                                       objReturn = ((IObjectReference)objReturn).GetRealObject(_context);\r
+                       }\r
+\r
+                       RegisterObject(id, objReturn, info, parentId, parentMemberInfo, indices);\r
+                       xmlReader.ReadEndElement();\r
+                       return objReturn;\r
+               }\r
+\r
+\r
+               private object DeserializeSimpleObject(\r
+                       object obj,\r
+                       long id,\r
+                       out bool hasFixup\r
+                       )\r
+               {\r
+                       hasFixup = false;\r
+                       Type currentType = obj.GetType();\r
+                       TypeMetadata tm = GetTypeMetadata (currentType);\r
+\r
+                       object[] data = new object[tm.MemberInfos.Length];\r
+                       xmlReader.Read();\r
+                       xmlReader.MoveToContent ();\r
+                       while (xmlReader.NodeType != XmlNodeType.EndElement)\r
+                       {\r
+                               if (xmlReader.NodeType != XmlNodeType.Element) {\r
+                                       xmlReader.Skip ();\r
+                                       continue;\r
+                               }\r
+                               \r
+                               object fieldObject;\r
+                               long fieldId, fieldHref;\r
+\r
+                               object indexob = tm.Indices [xmlReader.LocalName];\r
+                               if (indexob == null)\r
+                                       throw new SerializationException ("Field \"" + xmlReader.LocalName + "\" not found in class " + currentType.FullName);\r
+                               \r
+                               int index = (int) indexob;\r
+                               FieldInfo fieldInfo = (tm.MemberInfos[index]) as FieldInfo;\r
+\r
+                               fieldObject = \r
+                                       DeserializeComponent(fieldInfo.FieldType,\r
+                                       out fieldId,\r
+                                       out fieldHref,\r
+                                       id,\r
+                                       fieldInfo,\r
+                                       null);\r
+\r
+                               data[index] = fieldObject;\r
+\r
+                               if(fieldHref != 0 && fieldObject == null)\r
+                               {\r
+                                       RecordFixup(id, fieldHref, obj, null, null, fieldInfo, null);\r
+                                       hasFixup = true;\r
+                                       continue;\r
+                               }\r
+                               if(fieldObject != null && fieldObject.GetType().IsValueType && fieldId != 0)\r
+                               {\r
+                                       RecordFixup(id, fieldId, obj, null, null, fieldInfo, null);\r
+                                       hasFixup = true;\r
+                                       continue;\r
+                               }\r
+\r
+                               if(fieldId != 0)\r
+                               {\r
+                                       RegisterObject(fieldId, fieldObject, null, id, fieldInfo, null);\r
+                               }\r
+                       }\r
+\r
+                       FormatterServices.PopulateObjectMembers (obj, tm.MemberInfos, data);\r
+                       return obj;\r
+               }\r
+\r
+\r
+               private object DeserializeISerializableObject(\r
+                       object obj, \r
+                       long id, \r
+                       out SerializationInfo info,\r
+                       out bool hasFixup\r
+                       )\r
+               {\r
+                       long fieldId, fieldHref;\r
+                       info = new SerializationInfo(obj.GetType(), new FormatterConverter());\r
+                       hasFixup = false;\r
+                       \r
+                       int initialDepth = xmlReader.Depth;\r
+                       xmlReader.Read();\r
+                       while(xmlReader.Depth > initialDepth) \r
+                       {\r
+                               Type fieldType = GetComponentType();\r
+                               string fieldName = XmlConvert.DecodeName (xmlReader.LocalName);\r
+                               object objField = DeserializeComponent(\r
+                                       fieldType,\r
+                                       out fieldId,\r
+                                       out fieldHref,\r
+                                       id,\r
+                                       null,\r
+                                       null);\r
+                               if(fieldHref != 0 && objField == null) \r
+                               {\r
+                                       RecordFixup(id, fieldHref, obj, info, fieldName, null, null);\r
+                                       hasFixup = true;\r
+                                       continue;\r
+                               }\r
+                               else if(fieldId != 0 && objField.GetType().IsValueType)\r
+                               {\r
+                                       RecordFixup(id, fieldId, obj, info, fieldName, null, null);\r
+                                       hasFixup = true;\r
+                                       continue;\r
+                               }\r
+                               \r
+                               if(fieldId != 0) \r
+                               {\r
+                                       RegisterObject(fieldId, objField, null, id, null, null);\r
+                               }\r
+\r
+                               info.AddValue(fieldName, objField, (fieldType != null)?fieldType:typeof(object));\r
+                       }\r
+\r
+                       return obj;\r
+               }\r
+\r
+\r
+               private object DeserializeComponent(\r
+                       Type componentType, \r
+                       out long componentId,\r
+                       out long componentHref,\r
+                       long parentId,\r
+                       MemberInfo parentMemberInfo,\r
+                       int[] indices)\r
+               {\r
+                       object objReturn;\r
+                       componentId = 0;\r
+                       componentHref = 0;\r
+\r
+                       if(IsNull())\r
+                       {\r
+                               xmlReader.Read();\r
+                               return null;\r
+                       }\r
+\r
+                       Type xsiType = GetComponentType();\r
+                       if(xsiType != null) componentType = xsiType;\r
+\r
+                       if(xmlReader.HasAttributes)\r
+                       {\r
+                               componentId = GetId();\r
+                               componentHref = GetHref();\r
+                       }\r
+\r
+                       if(componentId != 0)\r
+                       {\r
+                               // It's a string\r
+                               return xmlReader.ReadElementString();\r
+                       }\r
+                       if(componentHref != 0)\r
+                       {\r
+                               // Move the cursor to the next node\r
+                               xmlReader.Read();\r
+                               return objMgr.GetObject(componentHref);\r
+                       }\r
+\r
+                       if(componentType == null)\r
+                               return xmlReader.ReadElementString();\r
+\r
+                       componentId = NextAvailableId;\r
+                       objReturn = DeserializeObject(\r
+                               componentType,\r
+                               componentId,\r
+                               parentId,\r
+                               parentMemberInfo,\r
+                               indices);\r
+                       return objReturn;\r
+               }\r
+\r
+               public void RecordFixup(\r
+                       long parentObjectId, \r
+                       long childObjectId,\r
+                       object parentObject,\r
+                       SerializationInfo info,\r
+                       string fieldName,\r
+                       MemberInfo memberInfo,\r
+                       int[] indices)\r
+               {\r
+                       if(info != null)\r
+                       {\r
+                               objMgr.RecordDelayedFixup(parentObjectId, fieldName, childObjectId);\r
+                       }\r
+                       else if (parentObject is Array) \r
+                       {\r
+                               if (indices.Length == 1)\r
+                                       objMgr.RecordArrayElementFixup (parentObjectId, indices[0], childObjectId);\r
+                               else\r
+                                       objMgr.RecordArrayElementFixup (parentObjectId, (int[])indices.Clone(), childObjectId);\r
+                       }\r
+                       else \r
+                       {\r
+                               objMgr.RecordFixup (parentObjectId, memberInfo, childObjectId);\r
+                       }\r
+               }\r
+\r
+               private void RegisterObject (\r
+                       long objectId, \r
+                       object objectInstance, \r
+                       SerializationInfo info, \r
+                       long parentObjectId, \r
+                       MemberInfo parentObjectMember, \r
+                       int[] indices)\r
+               {\r
+                       if (parentObjectId == 0) indices = null;\r
+\r
+                       if (!objectInstance.GetType().IsValueType || parentObjectId == 0)\r
+                               objMgr.RegisterObject (objectInstance, objectId, info, 0, null, null);\r
+                       else\r
+                       {\r
+                               if(objMgr.GetObject(objectId) != null)\r
+                                       throw new SerializationException("Object already registered");\r
+                               if (indices != null) indices = (int[])indices.Clone();\r
+                               objMgr.RegisterObject (\r
+                                       objectInstance, \r
+                                       objectId, \r
+                                       info, \r
+                                       parentObjectId, \r
+                                       parentObjectMember, \r
+                                       indices);\r
+                       }\r
+               }\r
+\r
+               TypeMetadata GetTypeMetadata (Type type)\r
+               {\r
+                       TypeMetadata tm = _fieldIndices[type] as TypeMetadata;\r
+                       if (tm != null) return tm;\r
+                       \r
+                       tm = new TypeMetadata ();\r
+                       tm.MemberInfos = FormatterServices.GetSerializableMembers (type, _context);\r
+                       \r
+                       tm.Indices      = new Hashtable();\r
+                       for(int i = 0; i < tm.MemberInfos.Length; i++) {\r
+                               SoapFieldAttribute at = (SoapFieldAttribute) InternalRemotingServices.GetCachedSoapAttribute (tm.MemberInfos[i]);\r
+                               tm.Indices [XmlConvert.EncodeLocalName (at.XmlElementName)] = i;\r
+                       }\r
+                       \r
+                       _fieldIndices[type] = tm;\r
+                       return tm;\r
                }
                
-               private int ReadFieldIdValueFromXml(string FieldName, XmlElement ParentElement)
+               public Type GetTypeFromQName (string qname)
                {
-                       XmlElement FieldElement= (XmlElement)ParentElement.GetElementsByTagName(FieldName).Item(0);//(XmlElement)GetCurrentElement(XmlParentElement, XmlParentElementId).GetElementsByTagName(FieldName).Item(0);
-                       if(FieldElement.GetAttribute(cXsiNull)== "") //if it is not a null field
-                       {
-                               string refvalue= FieldElement.GetAttribute(cId);
-                               int StartIndex= refvalue.IndexOf("-");
-                               return Convert.ToInt32(refvalue.Substring(StartIndex + 1, refvalue.Length - 1 - StartIndex));
-                       }
-                       else
-                               return -1;
-               }
-
-               private int ReadFieldIdValueFromXml(int ItemIndex, XmlElement ParentElement)
-               {
-                       XmlElement FieldElement= (XmlElement)ParentElement.ChildNodes.Item(ItemIndex);
-                       if(FieldElement.GetAttribute(cXsiNull)== "") //if it is not a null field
-                       {
-                               string refvalue= FieldElement.GetAttribute(cId);
-                               int StartIndex= refvalue.IndexOf("-");
-                               return Convert.ToInt32(refvalue.Substring(StartIndex + 1, refvalue.Length - 1 - StartIndex));
-                       }
-                       else
-                               return -1;
-               }
-       }       
-}
+                       string[] strName = qname.Split(':');\r
+                       string namespaceURI = xmlReader.LookupNamespace (strName[0]);\r
+                       return mapper.GetType (strName[1], namespaceURI);\r
+               }\r
+               \r
+               #endregion\r
+       }\r
+}\r