The Labs \ Source Viewer \ SSCLI \ System.Xml.Serialization \ Fixup

  1. //------------------------------------------------------------------------------
  2. // <copyright file="XmlSerializationReader.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. // <owner current="true" primary="true">ElenaK</owner>
  15. //------------------------------------------------------------------------------
  16. namespace System.Xml.Serialization
  17. {
  18.    
  19.     using System.IO;
  20.     using System;
  21.     using System.Security;
  22.     using System.Collections;
  23.     using System.Reflection;
  24.     using System.Text;
  25.     using System.Xml;
  26.     using System.Xml.Schema;
  27.     using System.ComponentModel;
  28.     using System.Globalization;
  29.     using System.CodeDom.Compiler;
  30.     using System.Diagnostics;
  31.     using System.Threading;
  32.     using System.Configuration;
  33.     using System.Xml.Serialization.Configuration;
  34.    
  35.     /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader"]/*' />
  36.     ///<internalonly/>
  37.     public abstract class XmlSerializationReader : XmlSerializationGeneratedCode
  38.     {
  39.         XmlReader r;
  40.         XmlCountingReader countingReader;
  41.         XmlDocument d;
  42.         Hashtable callbacks;
  43.         Hashtable types;
  44.         Hashtable typesReverse;
  45.         XmlDeserializationEvents events;
  46.         Hashtable targets;
  47.         Hashtable referencedTargets;
  48.         ArrayList targetsWithoutIds;
  49.         ArrayList fixups;
  50.         ArrayList collectionFixups;
  51.         bool soap12;
  52.         bool isReturnValue;
  53.         bool decodeName = true;
  54.        
  55.         string schemaNsID;
  56.         string schemaNs1999ID;
  57.         string schemaNs2000ID;
  58.         string schemaNonXsdTypesNsID;
  59.         string instanceNsID;
  60.         string instanceNs2000ID;
  61.         string instanceNs1999ID;
  62.         string soapNsID;
  63.         string soap12NsID;
  64.         string schemaID;
  65.         string wsdlNsID;
  66.         string wsdlArrayTypeID;
  67.         string nullID;
  68.         string nilID;
  69.         string typeID;
  70.         string arrayTypeID;
  71.         string itemTypeID;
  72.         string arraySizeID;
  73.         string arrayID;
  74.         string urTypeID;
  75.         string stringID;
  76.         string intID;
  77.         string booleanID;
  78.         string shortID;
  79.         string longID;
  80.         string floatID;
  81.         string doubleID;
  82.         string decimalID;
  83.         string dateTimeID;
  84.         string qnameID;
  85.         string dateID;
  86.         string timeID;
  87.         string hexBinaryID;
  88.         string base64BinaryID;
  89.         string base64ID;
  90.         string unsignedByteID;
  91.         string byteID;
  92.         string unsignedShortID;
  93.         string unsignedIntID;
  94.         string unsignedLongID;
  95.         string oldDecimalID;
  96.         string oldTimeInstantID;
  97.        
  98.         string anyURIID;
  99.         string durationID;
  100.         string ENTITYID;
  101.         string ENTITIESID;
  102.         string gDayID;
  103.         string gMonthID;
  104.         string gMonthDayID;
  105.         string gYearID;
  106.         string gYearMonthID;
  107.         string IDID;
  108.         string IDREFID;
  109.         string IDREFSID;
  110.         string integerID;
  111.         string languageID;
  112.         string NameID;
  113.         string NCNameID;
  114.         string NMTOKENID;
  115.         string NMTOKENSID;
  116.         string negativeIntegerID;
  117.         string nonPositiveIntegerID;
  118.         string nonNegativeIntegerID;
  119.         string normalizedStringID;
  120.         string NOTATIONID;
  121.         string positiveIntegerID;
  122.         string tokenID;
  123.        
  124.         string charID;
  125.         string guidID;
  126.        
  127.         static bool checkDeserializeAdvances;
  128.        
  129.         static XmlSerializationReader()
  130.         {
  131.             XmlSerializerSection configSection = ConfigurationManager.GetSection(ConfigurationStrings.XmlSerializerSectionPath) as XmlSerializerSection;
  132.             checkDeserializeAdvances = (configSection == null) ? false : configSection.CheckDeserializeAdvances;
  133.         }
  134.        
  135.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.InitIDs"]/*' />
  136.         protected abstract void InitIDs();
  137.        
  138.         // this method must be called before any generated deserialization methods are called
  139.         internal void Init(XmlReader r, XmlDeserializationEvents events, string encodingStyle, TempAssembly tempAssembly)
  140.         {
  141.             this.events = events;
  142.             if (checkDeserializeAdvances) {
  143.                 this.countingReader = new XmlCountingReader(r);
  144.                 this.r = this.countingReader;
  145.             }
  146.             else
  147.                 this.r = r;
  148.             this.d = null;
  149.             this.soap12 = (encodingStyle == Soap12.Encoding);
  150.             Init(tempAssembly);
  151.            
  152.             schemaNsID = r.NameTable.Add(XmlSchema.Namespace);
  153.             schemaNs2000ID = r.NameTable.Add("http://www.w3.org/2000/10/XMLSchema");
  154.             schemaNs1999ID = r.NameTable.Add("http://www.w3.org/1999/XMLSchema");
  155.             schemaNonXsdTypesNsID = r.NameTable.Add(UrtTypes.Namespace);
  156.             instanceNsID = r.NameTable.Add(XmlSchema.InstanceNamespace);
  157.             instanceNs2000ID = r.NameTable.Add("http://www.w3.org/2000/10/XMLSchema-instance");
  158.             instanceNs1999ID = r.NameTable.Add("http://www.w3.org/1999/XMLSchema-instance");
  159.             soapNsID = r.NameTable.Add(Soap.Encoding);
  160.             soap12NsID = r.NameTable.Add(Soap12.Encoding);
  161.             schemaID = r.NameTable.Add("schema");
  162.             wsdlNsID = r.NameTable.Add(Wsdl.Namespace);
  163.             wsdlArrayTypeID = r.NameTable.Add(Wsdl.ArrayType);
  164.             nullID = r.NameTable.Add("null");
  165.             nilID = r.NameTable.Add("nil");
  166.             typeID = r.NameTable.Add("type");
  167.             arrayTypeID = r.NameTable.Add("arrayType");
  168.             itemTypeID = r.NameTable.Add("itemType");
  169.             arraySizeID = r.NameTable.Add("arraySize");
  170.             arrayID = r.NameTable.Add("Array");
  171.             urTypeID = r.NameTable.Add(Soap.UrType);
  172.             InitIDs();
  173.         }
  174.        
  175.         /// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.DecodeName"]/*' />
  176.         protected bool DecodeName {
  177.             get { return decodeName; }
  178.             set { decodeName = value; }
  179.         }
  180.        
  181.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.Reader"]/*' />
  182.         protected XmlReader Reader {
  183.             get { return r; }
  184.         }
  185.        
  186.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReaderCount"]/*' />
  187.         protected int ReaderCount {
  188.             get { return checkDeserializeAdvances ? countingReader.AdvanceCount : 0; }
  189.         }
  190.        
  191.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.Document"]/*' />
  192.         protected XmlDocument Document {
  193.             get {
  194.                 if (d == null) {
  195.                     d = new XmlDocument(r.NameTable);
  196.                     d.SetBaseURI(r.BaseURI);
  197.                 }
  198.                 return d;
  199.             }
  200.         }
  201.        
  202.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ResolveDynamicAssembly"]/*' />
  203.         ///<internalonly/>
  204.         protected static Assembly ResolveDynamicAssembly(string assemblyFullName)
  205.         {
  206.             return DynamicAssemblies.Get(assemblyFullName);
  207.         }
  208.        
  209.         void InitPrimitiveIDs()
  210.         {
  211.             if (tokenID != null)
  212.                 return;
  213.             object ns = r.NameTable.Add(XmlSchema.Namespace);
  214.             object ns2 = r.NameTable.Add(UrtTypes.Namespace);
  215.            
  216.             stringID = r.NameTable.Add("string");
  217.             intID = r.NameTable.Add("int");
  218.             booleanID = r.NameTable.Add("boolean");
  219.             shortID = r.NameTable.Add("short");
  220.             longID = r.NameTable.Add("long");
  221.             floatID = r.NameTable.Add("float");
  222.             doubleID = r.NameTable.Add("double");
  223.             decimalID = r.NameTable.Add("decimal");
  224.             dateTimeID = r.NameTable.Add("dateTime");
  225.             qnameID = r.NameTable.Add("QName");
  226.             dateID = r.NameTable.Add("date");
  227.             timeID = r.NameTable.Add("time");
  228.             hexBinaryID = r.NameTable.Add("hexBinary");
  229.             base64BinaryID = r.NameTable.Add("base64Binary");
  230.             unsignedByteID = r.NameTable.Add("unsignedByte");
  231.             byteID = r.NameTable.Add("byte");
  232.             unsignedShortID = r.NameTable.Add("unsignedShort");
  233.             unsignedIntID = r.NameTable.Add("unsignedInt");
  234.             unsignedLongID = r.NameTable.Add("unsignedLong");
  235.             oldDecimalID = r.NameTable.Add("decimal");
  236.             oldTimeInstantID = r.NameTable.Add("timeInstant");
  237.             charID = r.NameTable.Add("char");
  238.             guidID = r.NameTable.Add("guid");
  239.             base64ID = r.NameTable.Add("base64");
  240.            
  241.             anyURIID = r.NameTable.Add("anyURI");
  242.             durationID = r.NameTable.Add("duration");
  243.             ENTITYID = r.NameTable.Add("ENTITY");
  244.             ENTITIESID = r.NameTable.Add("ENTITIES");
  245.             gDayID = r.NameTable.Add("gDay");
  246.             gMonthID = r.NameTable.Add("gMonth");
  247.             gMonthDayID = r.NameTable.Add("gMonthDay");
  248.             gYearID = r.NameTable.Add("gYear");
  249.             gYearMonthID = r.NameTable.Add("gYearMonth");
  250.             IDID = r.NameTable.Add("ID");
  251.             IDREFID = r.NameTable.Add("IDREF");
  252.             IDREFSID = r.NameTable.Add("IDREFS");
  253.             integerID = r.NameTable.Add("integer");
  254.             languageID = r.NameTable.Add("language");
  255.             NameID = r.NameTable.Add("Name");
  256.             NCNameID = r.NameTable.Add("NCName");
  257.             NMTOKENID = r.NameTable.Add("NMTOKEN");
  258.             NMTOKENSID = r.NameTable.Add("NMTOKENS");
  259.             negativeIntegerID = r.NameTable.Add("negativeInteger");
  260.             nonNegativeIntegerID = r.NameTable.Add("nonNegativeInteger");
  261.             nonPositiveIntegerID = r.NameTable.Add("nonPositiveInteger");
  262.             normalizedStringID = r.NameTable.Add("normalizedString");
  263.             NOTATIONID = r.NameTable.Add("NOTATION");
  264.             positiveIntegerID = r.NameTable.Add("positiveInteger");
  265.             tokenID = r.NameTable.Add("token");
  266.         }
  267.        
  268.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.GetXsiType"]/*' />
  269.         /// <devdoc>
  270.         /// <para>[To be supplied.]</para>
  271.         /// </devdoc>
  272.         protected XmlQualifiedName GetXsiType()
  273.         {
  274.             string type = r.GetAttribute(typeID, instanceNsID);
  275.             if (type == null) {
  276.                 type = r.GetAttribute(typeID, instanceNs2000ID);
  277.                 if (type == null) {
  278.                     type = r.GetAttribute(typeID, instanceNs1999ID);
  279.                     if (type == null)
  280.                         return null;
  281.                 }
  282.             }
  283.             return ToXmlQualifiedName(type, false);
  284.         }
  285.        
  286.         // throwOnUnknown flag controls whether this method throws an exception or just returns
  287.         // null if typeName.Namespace is unknown. the method still throws if typeName.Namespace
  288.         // is recognized but typeName.Name isn't.
  289.         Type GetPrimitiveType(XmlQualifiedName typeName, bool throwOnUnknown)
  290.         {
  291.             InitPrimitiveIDs();
  292.            
  293.             if ((object)typeName.Namespace == (object)schemaNsID || (object)typeName.Namespace == (object)soapNsID || (object)typeName.Namespace == (object)soap12NsID) {
  294.                 if ((object)typeName.Name == (object)stringID || (object)typeName.Name == (object)anyURIID || (object)typeName.Name == (object)durationID || (object)typeName.Name == (object)ENTITYID || (object)typeName.Name == (object)ENTITIESID || (object)typeName.Name == (object)gDayID || (object)typeName.Name == (object)gMonthID || (object)typeName.Name == (object)gMonthDayID || (object)typeName.Name == (object)gYearID || (object)typeName.Name == (object)gYearMonthID || (object)typeName.Name == (object)IDID || (object)typeName.Name == (object)IDREFID || (object)typeName.Name == (object)IDREFSID || (object)typeName.Name == (object)integerID || (object)typeName.Name == (object)languageID || (object)typeName.Name == (object)NameID || (object)typeName.Name == (object)NCNameID || (object)typeName.Name == (object)NMTOKENID || (object)typeName.Name == (object)NMTOKENSID || (object)typeName.Name == (object)negativeIntegerID || (object)typeName.Name == (object)nonPositiveIntegerID || (object)typeName.Name == (object)nonNegativeIntegerID || (object)typeName.Name == (object)normalizedStringID || (object)typeName.Name == (object)NOTATIONID || (object)typeName.Name == (object)positiveIntegerID || (object)typeName.Name == (object)tokenID)
  295.                     return typeof(string);
  296.                 else if ((object)typeName.Name == (object)intID)
  297.                     return typeof(int);
  298.                 else if ((object)typeName.Name == (object)booleanID)
  299.                     return typeof(bool);
  300.                 else if ((object)typeName.Name == (object)shortID)
  301.                     return typeof(short);
  302.                 else if ((object)typeName.Name == (object)longID)
  303.                     return typeof(long);
  304.                 else if ((object)typeName.Name == (object)floatID)
  305.                     return typeof(float);
  306.                 else if ((object)typeName.Name == (object)doubleID)
  307.                     return typeof(double);
  308.                 else if ((object)typeName.Name == (object)decimalID)
  309.                     return typeof(decimal);
  310.                 else if ((object)typeName.Name == (object)dateTimeID)
  311.                     return typeof(DateTime);
  312.                 else if ((object)typeName.Name == (object)qnameID)
  313.                     return typeof(XmlQualifiedName);
  314.                 else if ((object)typeName.Name == (object)dateID)
  315.                     return typeof(DateTime);
  316.                 else if ((object)typeName.Name == (object)timeID)
  317.                     return typeof(DateTime);
  318.                 else if ((object)typeName.Name == (object)hexBinaryID)
  319.                     return typeof(byte[]);
  320.                 else if ((object)typeName.Name == (object)base64BinaryID)
  321.                     return typeof(byte[]);
  322.                 else if ((object)typeName.Name == (object)unsignedByteID)
  323.                     return typeof(byte);
  324.                 else if ((object)typeName.Name == (object)byteID)
  325.                     return typeof(sbyte);
  326.                 else if ((object)typeName.Name == (object)unsignedShortID)
  327.                     return typeof(UInt16);
  328.                 else if ((object)typeName.Name == (object)unsignedIntID)
  329.                     return typeof(UInt32);
  330.                 else if ((object)typeName.Name == (object)unsignedLongID)
  331.                     return typeof(UInt64);
  332.                 else
  333.                     throw CreateUnknownTypeException(typeName);
  334.             }
  335.             else if ((object)typeName.Namespace == (object)schemaNs2000ID || (object)typeName.Namespace == (object)schemaNs1999ID) {
  336.                 if ((object)typeName.Name == (object)stringID || (object)typeName.Name == (object)anyURIID || (object)typeName.Name == (object)durationID || (object)typeName.Name == (object)ENTITYID || (object)typeName.Name == (object)ENTITIESID || (object)typeName.Name == (object)gDayID || (object)typeName.Name == (object)gMonthID || (object)typeName.Name == (object)gMonthDayID || (object)typeName.Name == (object)gYearID || (object)typeName.Name == (object)gYearMonthID || (object)typeName.Name == (object)IDID || (object)typeName.Name == (object)IDREFID || (object)typeName.Name == (object)IDREFSID || (object)typeName.Name == (object)integerID || (object)typeName.Name == (object)languageID || (object)typeName.Name == (object)NameID || (object)typeName.Name == (object)NCNameID || (object)typeName.Name == (object)NMTOKENID || (object)typeName.Name == (object)NMTOKENSID || (object)typeName.Name == (object)negativeIntegerID || (object)typeName.Name == (object)nonPositiveIntegerID || (object)typeName.Name == (object)nonNegativeIntegerID || (object)typeName.Name == (object)normalizedStringID || (object)typeName.Name == (object)NOTATIONID || (object)typeName.Name == (object)positiveIntegerID || (object)typeName.Name == (object)tokenID)
  337.                     return typeof(string);
  338.                 else if ((object)typeName.Name == (object)intID)
  339.                     return typeof(int);
  340.                 else if ((object)typeName.Name == (object)booleanID)
  341.                     return typeof(bool);
  342.                 else if ((object)typeName.Name == (object)shortID)
  343.                     return typeof(short);
  344.                 else if ((object)typeName.Name == (object)longID)
  345.                     return typeof(long);
  346.                 else if ((object)typeName.Name == (object)floatID)
  347.                     return typeof(float);
  348.                 else if ((object)typeName.Name == (object)doubleID)
  349.                     return typeof(double);
  350.                 else if ((object)typeName.Name == (object)oldDecimalID)
  351.                     return typeof(decimal);
  352.                 else if ((object)typeName.Name == (object)oldTimeInstantID)
  353.                     return typeof(DateTime);
  354.                 else if ((object)typeName.Name == (object)qnameID)
  355.                     return typeof(XmlQualifiedName);
  356.                 else if ((object)typeName.Name == (object)dateID)
  357.                     return typeof(DateTime);
  358.                 else if ((object)typeName.Name == (object)timeID)
  359.                     return typeof(DateTime);
  360.                 else if ((object)typeName.Name == (object)hexBinaryID)
  361.                     return typeof(byte[]);
  362.                 else if ((object)typeName.Name == (object)byteID)
  363.                     return typeof(sbyte);
  364.                 else if ((object)typeName.Name == (object)unsignedShortID)
  365.                     return typeof(UInt16);
  366.                 else if ((object)typeName.Name == (object)unsignedIntID)
  367.                     return typeof(UInt32);
  368.                 else if ((object)typeName.Name == (object)unsignedLongID)
  369.                     return typeof(UInt64);
  370.                 else
  371.                     throw CreateUnknownTypeException(typeName);
  372.             }
  373.             else if ((object)typeName.Namespace == (object)schemaNonXsdTypesNsID) {
  374.                 if ((object)typeName.Name == (object)charID)
  375.                     return typeof(char);
  376.                 else if ((object)typeName.Name == (object)guidID)
  377.                     return typeof(Guid);
  378.                 else
  379.                     throw CreateUnknownTypeException(typeName);
  380.             }
  381.             else if (throwOnUnknown)
  382.                 throw CreateUnknownTypeException(typeName);
  383.             else
  384.                 return null;
  385.         }
  386.        
  387.         bool IsPrimitiveNamespace(string ns)
  388.         {
  389.             return (object)ns == (object)schemaNsID || (object)ns == (object)schemaNonXsdTypesNsID || (object)ns == (object)soapNsID || (object)ns == (object)soap12NsID || (object)ns == (object)schemaNs2000ID || (object)ns == (object)schemaNs1999ID;
  390.         }
  391.        
  392.         private string ReadStringValue()
  393.         {
  394.             if (r.IsEmptyElement) {
  395.                 r.Skip();
  396.                 return string.Empty;
  397.             }
  398.             r.ReadStartElement();
  399.             string retVal = r.ReadString();
  400.             ReadEndElement();
  401.             return retVal;
  402.         }
  403.        
  404.         private XmlQualifiedName ReadXmlQualifiedName()
  405.         {
  406.             string s;
  407.             bool isEmpty = false;
  408.             if (r.IsEmptyElement) {
  409.                 s = string.Empty;
  410.                 isEmpty = true;
  411.             }
  412.             else {
  413.                 r.ReadStartElement();
  414.                 s = r.ReadString();
  415.             }
  416.             XmlQualifiedName retVal = ToXmlQualifiedName(s);
  417.             if (isEmpty)
  418.                 r.Skip();
  419.             else
  420.                 ReadEndElement();
  421.             return retVal;
  422.         }
  423.        
  424.         private byte[] ReadByteArray(bool isBase64)
  425.         {
  426.             ArrayList list = new ArrayList();
  427.             const int MAX_ALLOC_SIZE = 64 * 1024;
  428.             int currentSize = 1024;
  429.             byte[] buffer;
  430.             int bytes = -1;
  431.             int offset = 0;
  432.             int total = 0;
  433.             buffer = new byte[currentSize];
  434.             list.Add(buffer);
  435.             while (bytes != 0) {
  436.                 if (offset == buffer.Length) {
  437.                     currentSize = Math.Min(currentSize * 2, MAX_ALLOC_SIZE);
  438.                     buffer = new byte[currentSize];
  439.                     offset = 0;
  440.                     list.Add(buffer);
  441.                 }
  442.                 if (isBase64) {
  443.                     bytes = r.ReadElementContentAsBase64(buffer, offset, buffer.Length - offset);
  444.                 }
  445.                 else {
  446.                     bytes = r.ReadElementContentAsBinHex(buffer, offset, buffer.Length - offset);
  447.                 }
  448.                 offset += bytes;
  449.                 total += bytes;
  450.             }
  451.            
  452.             byte[] result = new byte[total];
  453.             offset = 0;
  454.             foreach (byte[] block in list) {
  455.                 currentSize = Math.Min(block.Length, total);
  456.                 if (currentSize > 0) {
  457.                     Buffer.BlockCopy(block, 0, result, offset, currentSize);
  458.                     offset += currentSize;
  459.                     total -= currentSize;
  460.                 }
  461.             }
  462.             list.Clear();
  463.             return result;
  464.         }
  465.        
  466.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadTypedPrimitive"]/*' />
  467.         protected object ReadTypedPrimitive(XmlQualifiedName type)
  468.         {
  469.             return ReadTypedPrimitive(type, false);
  470.         }
  471.        
  472.         private object ReadTypedPrimitive(XmlQualifiedName type, bool elementCanBeType)
  473.         {
  474.             InitPrimitiveIDs();
  475.             object value = null;
  476.             if (!IsPrimitiveNamespace(type.Namespace) || (object)type.Name == (object)urTypeID)
  477.                 return ReadXmlNodes(elementCanBeType);
  478.            
  479.             if ((object)type.Namespace == (object)schemaNsID || (object)type.Namespace == (object)soapNsID || (object)type.Namespace == (object)soap12NsID) {
  480.                 if ((object)type.Name == (object)stringID || (object)type.Name == (object)normalizedStringID)
  481.                     value = ReadStringValue();
  482.                 else if ((object)type.Name == (object)anyURIID || (object)type.Name == (object)durationID || (object)type.Name == (object)ENTITYID || (object)type.Name == (object)ENTITIESID || (object)type.Name == (object)gDayID || (object)type.Name == (object)gMonthID || (object)type.Name == (object)gMonthDayID || (object)type.Name == (object)gYearID || (object)type.Name == (object)gYearMonthID || (object)type.Name == (object)IDID || (object)type.Name == (object)IDREFID || (object)type.Name == (object)IDREFSID || (object)type.Name == (object)integerID || (object)type.Name == (object)languageID || (object)type.Name == (object)NameID || (object)type.Name == (object)NCNameID || (object)type.Name == (object)NMTOKENID || (object)type.Name == (object)NMTOKENSID || (object)type.Name == (object)negativeIntegerID || (object)type.Name == (object)nonPositiveIntegerID || (object)type.Name == (object)nonNegativeIntegerID || (object)type.Name == (object)NOTATIONID || (object)type.Name == (object)positiveIntegerID || (object)type.Name == (object)tokenID)
  483.                     value = CollapseWhitespace(ReadStringValue());
  484.                 else if ((object)type.Name == (object)intID)
  485.                     value = XmlConvert.ToInt32(ReadStringValue());
  486.                 else if ((object)type.Name == (object)booleanID)
  487.                     value = XmlConvert.ToBoolean(ReadStringValue());
  488.                 else if ((object)type.Name == (object)shortID)
  489.                     value = XmlConvert.ToInt16(ReadStringValue());
  490.                 else if ((object)type.Name == (object)longID)
  491.                     value = XmlConvert.ToInt64(ReadStringValue());
  492.                 else if ((object)type.Name == (object)floatID)
  493.                     value = XmlConvert.ToSingle(ReadStringValue());
  494.                 else if ((object)type.Name == (object)doubleID)
  495.                     value = XmlConvert.ToDouble(ReadStringValue());
  496.                 else if ((object)type.Name == (object)decimalID)
  497.                     value = XmlConvert.ToDecimal(ReadStringValue());
  498.                 else if ((object)type.Name == (object)dateTimeID)
  499.                     value = ToDateTime(ReadStringValue());
  500.                 else if ((object)type.Name == (object)qnameID)
  501.                     value = ReadXmlQualifiedName();
  502.                 else if ((object)type.Name == (object)dateID)
  503.                     value = ToDate(ReadStringValue());
  504.                 else if ((object)type.Name == (object)timeID)
  505.                     value = ToTime(ReadStringValue());
  506.                 else if ((object)type.Name == (object)unsignedByteID)
  507.                     value = XmlConvert.ToByte(ReadStringValue());
  508.                 else if ((object)type.Name == (object)byteID)
  509.                     value = XmlConvert.ToSByte(ReadStringValue());
  510.                 else if ((object)type.Name == (object)unsignedShortID)
  511.                     value = XmlConvert.ToUInt16(ReadStringValue());
  512.                 else if ((object)type.Name == (object)unsignedIntID)
  513.                     value = XmlConvert.ToUInt32(ReadStringValue());
  514.                 else if ((object)type.Name == (object)unsignedLongID)
  515.                     value = XmlConvert.ToUInt64(ReadStringValue());
  516.                 else if ((object)type.Name == (object)hexBinaryID)
  517.                     value = ToByteArrayHex(false);
  518.                 else if ((object)type.Name == (object)base64BinaryID)
  519.                     value = ToByteArrayBase64(false);
  520.                 else if ((object)type.Name == (object)base64ID && ((object)type.Namespace == (object)soapNsID || (object)type.Namespace == (object)soap12NsID))
  521.                     value = ToByteArrayBase64(false);
  522.                 else
  523.                     value = ReadXmlNodes(elementCanBeType);
  524.             }
  525.             else if ((object)type.Namespace == (object)schemaNs2000ID || (object)type.Namespace == (object)schemaNs1999ID) {
  526.                 if ((object)type.Name == (object)stringID || (object)type.Name == (object)normalizedStringID)
  527.                     value = ReadStringValue();
  528.                 else if ((object)type.Name == (object)anyURIID || (object)type.Name == (object)anyURIID || (object)type.Name == (object)durationID || (object)type.Name == (object)ENTITYID || (object)type.Name == (object)ENTITIESID || (object)type.Name == (object)gDayID || (object)type.Name == (object)gMonthID || (object)type.Name == (object)gMonthDayID || (object)type.Name == (object)gYearID || (object)type.Name == (object)gYearMonthID || (object)type.Name == (object)IDID || (object)type.Name == (object)IDREFID || (object)type.Name == (object)IDREFSID || (object)type.Name == (object)integerID || (object)type.Name == (object)languageID || (object)type.Name == (object)NameID || (object)type.Name == (object)NCNameID || (object)type.Name == (object)NMTOKENID || (object)type.Name == (object)NMTOKENSID || (object)type.Name == (object)negativeIntegerID || (object)type.Name == (object)nonPositiveIntegerID || (object)type.Name == (object)nonNegativeIntegerID || (object)type.Name == (object)NOTATIONID || (object)type.Name == (object)positiveIntegerID || (object)type.Name == (object)tokenID)
  529.                     value = CollapseWhitespace(ReadStringValue());
  530.                 else if ((object)type.Name == (object)intID)
  531.                     value = XmlConvert.ToInt32(ReadStringValue());
  532.                 else if ((object)type.Name == (object)booleanID)
  533.                     value = XmlConvert.ToBoolean(ReadStringValue());
  534.                 else if ((object)type.Name == (object)shortID)
  535.                     value = XmlConvert.ToInt16(ReadStringValue());
  536.                 else if ((object)type.Name == (object)longID)
  537.                     value = XmlConvert.ToInt64(ReadStringValue());
  538.                 else if ((object)type.Name == (object)floatID)
  539.                     value = XmlConvert.ToSingle(ReadStringValue());
  540.                 else if ((object)type.Name == (object)doubleID)
  541.                     value = XmlConvert.ToDouble(ReadStringValue());
  542.                 else if ((object)type.Name == (object)oldDecimalID)
  543.                     value = XmlConvert.ToDecimal(ReadStringValue());
  544.                 else if ((object)type.Name == (object)oldTimeInstantID)
  545.                     value = ToDateTime(ReadStringValue());
  546.                 else if ((object)type.Name == (object)qnameID)
  547.                     value = ReadXmlQualifiedName();
  548.                 else if ((object)type.Name == (object)dateID)
  549.                     value = ToDate(ReadStringValue());
  550.                 else if ((object)type.Name == (object)timeID)
  551.                     value = ToTime(ReadStringValue());
  552.                 else if ((object)type.Name == (object)unsignedByteID)
  553.                     value = XmlConvert.ToByte(ReadStringValue());
  554.                 else if ((object)type.Name == (object)byteID)
  555.                     value = XmlConvert.ToSByte(ReadStringValue());
  556.                 else if ((object)type.Name == (object)unsignedShortID)
  557.                     value = XmlConvert.ToUInt16(ReadStringValue());
  558.                 else if ((object)type.Name == (object)unsignedIntID)
  559.                     value = XmlConvert.ToUInt32(ReadStringValue());
  560.                 else if ((object)type.Name == (object)unsignedLongID)
  561.                     value = XmlConvert.ToUInt64(ReadStringValue());
  562.                 else
  563.                     value = ReadXmlNodes(elementCanBeType);
  564.             }
  565.             else if ((object)type.Namespace == (object)schemaNonXsdTypesNsID) {
  566.                 if ((object)type.Name == (object)charID)
  567.                     value = ToChar(ReadStringValue());
  568.                 else if ((object)type.Name == (object)guidID)
  569.                     value = new Guid(CollapseWhitespace(ReadStringValue()));
  570.                 else
  571.                     value = ReadXmlNodes(elementCanBeType);
  572.             }
  573.             else
  574.                 value = ReadXmlNodes(elementCanBeType);
  575.             return value;
  576.         }
  577.        
  578.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadTypedNull"]/*' />
  579.         protected object ReadTypedNull(XmlQualifiedName type)
  580.         {
  581.             InitPrimitiveIDs();
  582.             object value = null;
  583.             if (!IsPrimitiveNamespace(type.Namespace) || (object)type.Name == (object)urTypeID) {
  584.                 return null;
  585.             }
  586.            
  587.             if ((object)type.Namespace == (object)schemaNsID || (object)type.Namespace == (object)soapNsID || (object)type.Namespace == (object)soap12NsID) {
  588.                 if ((object)type.Name == (object)stringID || (object)type.Name == (object)anyURIID || (object)type.Name == (object)durationID || (object)type.Name == (object)ENTITYID || (object)type.Name == (object)ENTITIESID || (object)type.Name == (object)gDayID || (object)type.Name == (object)gMonthID || (object)type.Name == (object)gMonthDayID || (object)type.Name == (object)gYearID || (object)type.Name == (object)gYearMonthID || (object)type.Name == (object)IDID || (object)type.Name == (object)IDREFID || (object)type.Name == (object)IDREFSID || (object)type.Name == (object)integerID || (object)type.Name == (object)languageID || (object)type.Name == (object)NameID || (object)type.Name == (object)NCNameID || (object)type.Name == (object)NMTOKENID || (object)type.Name == (object)NMTOKENSID || (object)type.Name == (object)negativeIntegerID || (object)type.Name == (object)nonPositiveIntegerID || (object)type.Name == (object)nonNegativeIntegerID || (object)type.Name == (object)normalizedStringID || (object)type.Name == (object)NOTATIONID || (object)type.Name == (object)positiveIntegerID || (object)type.Name == (object)tokenID)
  589.                     value = null;
  590.                 else if ((object)type.Name == (object)intID) {
  591.                     value = default(Nullable<int>);
  592.                 }
  593.                 else if ((object)type.Name == (object)booleanID)
  594.                     value = default(Nullable<bool>);
  595.                 else if ((object)type.Name == (object)shortID)
  596.                     value = default(Nullable<Int16>);
  597.                 else if ((object)type.Name == (object)longID)
  598.                     value = default(Nullable<long>);
  599.                 else if ((object)type.Name == (object)floatID)
  600.                     value = default(Nullable<float>);
  601.                 else if ((object)type.Name == (object)doubleID)
  602.                     value = default(Nullable<double>);
  603.                 else if ((object)type.Name == (object)decimalID)
  604.                     value = default(Nullable<decimal>);
  605.                 else if ((object)type.Name == (object)dateTimeID)
  606.                     value = default(Nullable<DateTime>);
  607.                 else if ((object)type.Name == (object)qnameID)
  608.                     value = null;
  609.                 else if ((object)type.Name == (object)dateID)
  610.                     value = default(Nullable<DateTime>);
  611.                 else if ((object)type.Name == (object)timeID)
  612.                     value = default(Nullable<DateTime>);
  613.                 else if ((object)type.Name == (object)unsignedByteID)
  614.                     value = default(Nullable<byte>);
  615.                 else if ((object)type.Name == (object)byteID)
  616.                     value = default(Nullable<sbyte>);
  617.                 else if ((object)type.Name == (object)unsignedShortID)
  618.                     value = default(Nullable<UInt16>);
  619.                 else if ((object)type.Name == (object)unsignedIntID)
  620.                     value = default(Nullable<UInt32>);
  621.                 else if ((object)type.Name == (object)unsignedLongID)
  622.                     value = default(Nullable<UInt64>);
  623.                 else if ((object)type.Name == (object)hexBinaryID)
  624.                     value = null;
  625.                 else if ((object)type.Name == (object)base64BinaryID)
  626.                     value = null;
  627.                 else if ((object)type.Name == (object)base64ID && ((object)type.Namespace == (object)soapNsID || (object)type.Namespace == (object)soap12NsID))
  628.                     value = null;
  629.                 else
  630.                     value = null;
  631.             }
  632.             else if ((object)type.Namespace == (object)schemaNonXsdTypesNsID) {
  633.                 if ((object)type.Name == (object)charID)
  634.                     value = default(Nullable<char>);
  635.                 else if ((object)type.Name == (object)guidID)
  636.                     value = default(Nullable<Guid>);
  637.                 else
  638.                     value = null;
  639.             }
  640.             else
  641.                 value = null;
  642.             return value;
  643.         }
  644.        
  645.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.IsXmlnsAttribute"]/*' />
  646.         protected bool IsXmlnsAttribute(string name)
  647.         {
  648.             if (!name.StartsWith("xmlns", StringComparison.Ordinal))
  649.                 return false;
  650.             if (name.Length == 5)
  651.                 return true;
  652.             return name[5] == ':';
  653.         }
  654.        
  655.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.IsArrayTypeAttribute"]/*' />
  656.         protected void ParseWsdlArrayType(XmlAttribute attr)
  657.         {
  658.             if ((object)attr.LocalName == (object)wsdlArrayTypeID && (object)attr.NamespaceURI == (object)wsdlNsID) {
  659.                
  660.                 int colon = attr.Value.LastIndexOf(':');
  661.                 if (colon < 0) {
  662.                     attr.Value = r.LookupNamespace("") + ":" + attr.Value;
  663.                 }
  664.                 else {
  665.                     attr.Value = r.LookupNamespace(attr.Value.Substring(0, colon)) + ":" + attr.Value.Substring(colon + 1);
  666.                 }
  667.             }
  668.             return;
  669.         }
  670.        
  671.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.IsReturnValue"]/*' />
  672.         protected bool IsReturnValue {
  673.             // value only valid for soap 1.1
  674.             get { return isReturnValue && !soap12; }
  675.             set { isReturnValue = value; }
  676.         }
  677.        
  678.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadNull"]/*' />
  679.         protected bool ReadNull()
  680.         {
  681.             if (!GetNullAttr())
  682.                 return false;
  683.             if (r.IsEmptyElement) {
  684.                 r.Skip();
  685.                 return true;
  686.             }
  687.             r.ReadStartElement();
  688.             int whileIterations = 0;
  689.             int readerCount = ReaderCount;
  690.             while (r.NodeType != XmlNodeType.EndElement) {
  691.                 UnknownNode(null);
  692.                 CheckReaderCount(ref whileIterations, ref readerCount);
  693.             }
  694.             ReadEndElement();
  695.             return true;
  696.         }
  697.        
  698.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.GetNullAttr"]/*' />
  699.         protected bool GetNullAttr()
  700.         {
  701.             string isNull = r.GetAttribute(nilID, instanceNsID);
  702.             if (isNull == null)
  703.                 isNull = r.GetAttribute(nullID, instanceNsID);
  704.             if (isNull == null) {
  705.                 isNull = r.GetAttribute(nullID, instanceNs2000ID);
  706.                 if (isNull == null)
  707.                     isNull = r.GetAttribute(nullID, instanceNs1999ID);
  708.             }
  709.             if (isNull == null || !XmlConvert.ToBoolean(isNull))
  710.                 return false;
  711.             return true;
  712.         }
  713.        
  714.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadNullableString"]/*' />
  715.         protected string ReadNullableString()
  716.         {
  717.             if (ReadNull())
  718.                 return null;
  719.             return r.ReadElementString();
  720.         }
  721.        
  722.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadNullableQualifiedName"]/*' />
  723.         /// <devdoc>
  724.         /// <para>[To be supplied.]</para>
  725.         /// </devdoc>
  726.         protected XmlQualifiedName ReadNullableQualifiedName()
  727.         {
  728.             if (ReadNull())
  729.                 return null;
  730.             return ReadElementQualifiedName();
  731.         }
  732.        
  733.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadElementQualifiedName"]/*' />
  734.         /// <devdoc>
  735.         /// <para>[To be supplied.]</para>
  736.         /// </devdoc>
  737.         protected XmlQualifiedName ReadElementQualifiedName()
  738.         {
  739.             if (r.IsEmptyElement) {
  740.                 XmlQualifiedName empty = new XmlQualifiedName(string.Empty, r.LookupNamespace(""));
  741.                 r.Skip();
  742.                 return empty;
  743.             }
  744.             XmlQualifiedName qname = ToXmlQualifiedName(CollapseWhitespace(r.ReadString()));
  745.             r.ReadEndElement();
  746.             return qname;
  747.         }
  748.        
  749.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadXmlDocument"]/*' />
  750.         protected XmlDocument ReadXmlDocument(bool wrapped)
  751.         {
  752.             XmlNode n = ReadXmlNode(wrapped);
  753.             if (n == null)
  754.                 return null;
  755.             XmlDocument doc = new XmlDocument();
  756.             doc.AppendChild(doc.ImportNode(n, true));
  757.             return doc;
  758.         }
  759.        
  760.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CollapseWhitespace"]/*' />
  761.         protected string CollapseWhitespace(string value)
  762.         {
  763.             if (value == null)
  764.                 return null;
  765.             return value.Trim();
  766.         }
  767.        
  768.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadXmlNode"]/*' />
  769.         protected XmlNode ReadXmlNode(bool wrapped)
  770.         {
  771.             XmlNode node = null;
  772.             if (wrapped) {
  773.                 if (ReadNull())
  774.                     return null;
  775.                 r.ReadStartElement();
  776.                 r.MoveToContent();
  777.                 if (r.NodeType != XmlNodeType.EndElement)
  778.                     node = Document.ReadNode(r);
  779.                 int whileIterations = 0;
  780.                 int readerCount = ReaderCount;
  781.                 while (r.NodeType != XmlNodeType.EndElement) {
  782.                     UnknownNode(null);
  783.                     CheckReaderCount(ref whileIterations, ref readerCount);
  784.                 }
  785.                 r.ReadEndElement();
  786.             }
  787.             else {
  788.                 node = Document.ReadNode(r);
  789.             }
  790.             return node;
  791.         }
  792.        
  793.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToByteArrayBase64"]/*' />
  794.         protected static byte[] ToByteArrayBase64(string value)
  795.         {
  796.             return XmlCustomFormatter.ToByteArrayBase64(value);
  797.         }
  798.        
  799.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToByteArrayBase641"]/*' />
  800.         protected byte[] ToByteArrayBase64(bool isNull)
  801.         {
  802.             if (isNull) {
  803.                 return null;
  804.             }
  805.             return ReadByteArray(true);
  806.             //means use Base64
  807.         }
  808.        
  809.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToByteArrayHex"]/*' />
  810.         protected static byte[] ToByteArrayHex(string value)
  811.         {
  812.             return XmlCustomFormatter.ToByteArrayHex(value);
  813.         }
  814.        
  815.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToByteArrayHex1"]/*' />
  816.         protected byte[] ToByteArrayHex(bool isNull)
  817.         {
  818.             if (isNull) {
  819.                 return null;
  820.             }
  821.             return ReadByteArray(false);
  822.             //means use BinHex
  823.         }
  824.        
  825.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.GetArrayLength"]/*' />
  826.         protected int GetArrayLength(string name, string ns)
  827.         {
  828.             if (GetNullAttr())
  829.                 return 0;
  830.             string arrayType = r.GetAttribute(arrayTypeID, soapNsID);
  831.             SoapArrayInfo arrayInfo = ParseArrayType(arrayType);
  832.             if (arrayInfo.dimensions != 1)
  833.                 throw new InvalidOperationException(Res.GetString(Res.XmlInvalidArrayDimentions, CurrentTag()));
  834.             XmlQualifiedName qname = ToXmlQualifiedName(arrayInfo.qname, false);
  835.             if (qname.Name != name)
  836.                 throw new InvalidOperationException(Res.GetString(Res.XmlInvalidArrayTypeName, qname.Name, name, CurrentTag()));
  837.             if (qname.Namespace != ns)
  838.                 throw new InvalidOperationException(Res.GetString(Res.XmlInvalidArrayTypeNamespace, qname.Namespace, ns, CurrentTag()));
  839.             return arrayInfo.length;
  840.         }
  841.        
  842.         struct SoapArrayInfo
  843.         {
  844.             /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.qname;"]/*' />
  845.             public string qname;
  846.             /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.dimensions;"]/*' />
  847.             public int dimensions;
  848.             /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.length;"]/*' />
  849.             public int length;
  850.             public int jaggedDimensions;
  851.         }
  852.        
  853.         private SoapArrayInfo ParseArrayType(string value)
  854.         {
  855.             if (value == null) {
  856.                 throw new ArgumentNullException(Res.GetString(Res.XmlMissingArrayType, CurrentTag()));
  857.             }
  858.            
  859.             if (value.Length == 0) {
  860.                 throw new ArgumentException(Res.GetString(Res.XmlEmptyArrayType, CurrentTag()), "value");
  861.             }
  862.            
  863.             char[] chars = value.ToCharArray();
  864.             int charsLength = chars.Length;
  865.            
  866.             SoapArrayInfo soapArrayInfo = new SoapArrayInfo();
  867.            
  868.             // Parse backwards to get length first, then optional dimensions, then qname.
  869.             int pos = charsLength - 1;
  870.            
  871.             // Must end with ]
  872.             if (chars[pos] != ']') {
  873.                 throw new ArgumentException(Res.GetString(Res.XmlInvalidArraySyntax), "value");
  874.             }
  875.             pos--;
  876.            
  877.             // Find [
  878.             while (pos != -1 && chars[pos] != '[') {
  879.                 if (chars[pos] == ',')
  880.                     throw new ArgumentException(Res.GetString(Res.XmlInvalidArrayDimentions, CurrentTag()), "value");
  881.                 pos--;
  882.             }
  883.             if (pos == -1) {
  884.                 throw new ArgumentException(Res.GetString(Res.XmlMismatchedArrayBrackets), "value");
  885.             }
  886.            
  887.             int len = charsLength - pos - 2;
  888.             if (len > 0) {
  889.                 string lengthString = new string(chars, pos + 1, len);
  890.                 try {
  891.                     soapArrayInfo.length = Int32.Parse(lengthString, CultureInfo.InvariantCulture);
  892.                 }
  893.                 catch (Exception e) {
  894.                     if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  895.                         throw;
  896.                     }
  897.                     throw new ArgumentException(Res.GetString(Res.XmlInvalidArrayLength, lengthString), "value");
  898.                 }
  899.                 catch {
  900.                     throw new ArgumentException(Res.GetString(Res.XmlInvalidArrayLength, lengthString), "value");
  901.                 }
  902.             }
  903.             else {
  904.                 soapArrayInfo.length = -1;
  905.             }
  906.            
  907.             pos--;
  908.            
  909.             soapArrayInfo.jaggedDimensions = 0;
  910.             while (pos != -1 && chars[pos] == ']') {
  911.                 pos--;
  912.                 if (pos < 0)
  913.                     throw new ArgumentException(Res.GetString(Res.XmlMismatchedArrayBrackets), "value");
  914.                 if (chars[pos] == ',')
  915.                     throw new ArgumentException(Res.GetString(Res.XmlInvalidArrayDimentions, CurrentTag()), "value");
  916.                 else if (chars[pos] != '[')
  917.                     throw new ArgumentException(Res.GetString(Res.XmlInvalidArraySyntax), "value");
  918.                 pos--;
  919.                 soapArrayInfo.jaggedDimensions++;
  920.             }
  921.            
  922.             soapArrayInfo.dimensions = 1;
  923.            
  924.             // everything else is qname - validation of qnames?
  925.             soapArrayInfo.qname = new string(chars, 0, pos + 1);
  926.             return soapArrayInfo;
  927.         }
  928.        
  929.         private SoapArrayInfo ParseSoap12ArrayType(string itemType, string arraySize)
  930.         {
  931.             SoapArrayInfo soapArrayInfo = new SoapArrayInfo();
  932.            
  933.             if (itemType != null && itemType.Length > 0)
  934.                 soapArrayInfo.qname = itemType;
  935.             else
  936.                 soapArrayInfo.qname = "";
  937.            
  938.             string[] dimensions;
  939.             if (arraySize != null && arraySize.Length > 0)
  940.                 dimensions = arraySize.Split(null);
  941.             else
  942.                 dimensions = new string[0];
  943.            
  944.             soapArrayInfo.dimensions = 0;
  945.             soapArrayInfo.length = -1;
  946.             for (int i = 0; i < dimensions.Length; i++) {
  947.                 if (dimensions[i].Length > 0) {
  948.                     if (dimensions[i] == "*") {
  949.                         soapArrayInfo.dimensions++;
  950.                     }
  951.                     else {
  952.                         try {
  953.                             soapArrayInfo.length = Int32.Parse(dimensions[i], CultureInfo.InvariantCulture);
  954.                             soapArrayInfo.dimensions++;
  955.                         }
  956.                         catch (Exception e) {
  957.                             if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
  958.                                 throw;
  959.                             }
  960.                             throw new ArgumentException(Res.GetString(Res.XmlInvalidArrayLength, dimensions[i]), "value");
  961.                         }
  962.                         catch {
  963.                             throw new ArgumentException(Res.GetString(Res.XmlInvalidArrayLength, dimensions[i]), "value");
  964.                         }
  965.                     }
  966.                 }
  967.             }
  968.             if (soapArrayInfo.dimensions == 0)
  969.                 soapArrayInfo.dimensions = 1;
  970.             // default is 1D even if no arraySize is specified
  971.             return soapArrayInfo;
  972.         }
  973.        
  974.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToDateTime"]/*' />
  975.         protected static DateTime ToDateTime(string value)
  976.         {
  977.             return XmlCustomFormatter.ToDateTime(value);
  978.         }
  979.        
  980.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToDate"]/*' />
  981.         protected static DateTime ToDate(string value)
  982.         {
  983.             return XmlCustomFormatter.ToDate(value);
  984.         }
  985.        
  986.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToTime"]/*' />
  987.         protected static DateTime ToTime(string value)
  988.         {
  989.             return XmlCustomFormatter.ToTime(value);
  990.         }
  991.        
  992.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToChar"]/*' />
  993.         protected static char ToChar(string value)
  994.         {
  995.             return XmlCustomFormatter.ToChar(value);
  996.         }
  997.        
  998.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToEnum"]/*' />
  999.         protected static long ToEnum(string value, Hashtable h, string typeName)
  1000.         {
  1001.             return XmlCustomFormatter.ToEnum(value, h, typeName, true);
  1002.         }
  1003.        
  1004.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToXmlName"]/*' />
  1005.         protected static string ToXmlName(string value)
  1006.         {
  1007.             return XmlCustomFormatter.ToXmlName(value);
  1008.         }
  1009.        
  1010.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToXmlNCName"]/*' />
  1011.         protected static string ToXmlNCName(string value)
  1012.         {
  1013.             return XmlCustomFormatter.ToXmlNCName(value);
  1014.         }
  1015.        
  1016.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToXmlNmToken"]/*' />
  1017.         protected static string ToXmlNmToken(string value)
  1018.         {
  1019.             return XmlCustomFormatter.ToXmlNmToken(value);
  1020.         }
  1021.        
  1022.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToXmlNmTokens"]/*' />
  1023.         protected static string ToXmlNmTokens(string value)
  1024.         {
  1025.             return XmlCustomFormatter.ToXmlNmTokens(value);
  1026.         }
  1027.        
  1028.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ToXmlQualifiedName"]/*' />
  1029.         protected XmlQualifiedName ToXmlQualifiedName(string value)
  1030.         {
  1031.             return ToXmlQualifiedName(value, DecodeName);
  1032.         }
  1033.        
  1034.         internal XmlQualifiedName ToXmlQualifiedName(string value, bool decodeName)
  1035.         {
  1036.             int colon = value == null ? -1 : value.LastIndexOf(':');
  1037.             string prefix = colon < 0 ? null : value.Substring(0, colon);
  1038.             string localName = value.Substring(colon + 1);
  1039.            
  1040.             if (decodeName) {
  1041.                 prefix = XmlConvert.DecodeName(prefix);
  1042.                 localName = XmlConvert.DecodeName(localName);
  1043.             }
  1044.             if (prefix == null || prefix.Length == 0) {
  1045.                 return new XmlQualifiedName(r.NameTable.Add(value), r.LookupNamespace(String.Empty));
  1046.             }
  1047.             else {
  1048.                 string ns = r.LookupNamespace(prefix);
  1049.                 if (ns == null) {
  1050.                     // Namespace prefix '{0}' is not defined.
  1051.                     throw new InvalidOperationException(Res.GetString(Res.XmlUndefinedAlias, prefix));
  1052.                 }
  1053.                 return new XmlQualifiedName(r.NameTable.Add(localName), ns);
  1054.             }
  1055.         }
  1056.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.UnknownAttribute"]/*' />
  1057.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.UnknownAttribute"]/*' />
  1058.         protected void UnknownAttribute(object o, XmlAttribute attr)
  1059.         {
  1060.             UnknownAttribute(o, attr, null);
  1061.         }
  1062.        
  1063.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.UnknownAttribute1"]/*' />
  1064.         protected void UnknownAttribute(object o, XmlAttribute attr, string qnames)
  1065.         {
  1066.             if (events.OnUnknownAttribute != null) {
  1067.                 int lineNumber;
  1068.                 int linePosition;
  1069.                 GetCurrentPosition(out lineNumber, out linePosition);
  1070.                 XmlAttributeEventArgs e = new XmlAttributeEventArgs(attr, lineNumber, linePosition, o, qnames);
  1071.                 events.OnUnknownAttribute(events.sender, e);
  1072.             }
  1073.         }
  1074.        
  1075.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.UnknownAttribute"]/*' />
  1076.         protected void UnknownElement(object o, XmlElement elem)
  1077.         {
  1078.             UnknownElement(o, elem, null);
  1079.         }
  1080.        
  1081.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.UnknownElement1"]/*' />
  1082.         protected void UnknownElement(object o, XmlElement elem, string qnames)
  1083.         {
  1084.             if (events.OnUnknownElement != null) {
  1085.                 int lineNumber;
  1086.                 int linePosition;
  1087.                 GetCurrentPosition(out lineNumber, out linePosition);
  1088.                 XmlElementEventArgs e = new XmlElementEventArgs(elem, lineNumber, linePosition, o, qnames);
  1089.                 events.OnUnknownElement(events.sender, e);
  1090.             }
  1091.         }
  1092.        
  1093.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.UnknownNode"]/*' />
  1094.         protected void UnknownNode(object o)
  1095.         {
  1096.             UnknownNode(o, null);
  1097.         }
  1098.        
  1099.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.UnknownNode1"]/*' />
  1100.         protected void UnknownNode(object o, string qnames)
  1101.         {
  1102.             if (r.NodeType == XmlNodeType.None || r.NodeType == XmlNodeType.Whitespace) {
  1103.                 r.Read();
  1104.                 return;
  1105.             }
  1106.             if (r.NodeType == XmlNodeType.EndElement)
  1107.                 return;
  1108.             if (events.OnUnknownNode != null) {
  1109.                 UnknownNode(Document.ReadNode(r), o, qnames);
  1110.             }
  1111.             else if (r.NodeType == XmlNodeType.Attribute && events.OnUnknownAttribute == null) {
  1112.                 return;
  1113.             }
  1114.             else if (r.NodeType == XmlNodeType.Element && events.OnUnknownElement == null) {
  1115.                 r.Skip();
  1116.                 return;
  1117.             }
  1118.             else {
  1119.                 UnknownNode(Document.ReadNode(r), o, qnames);
  1120.             }
  1121.         }
  1122.        
  1123.         void UnknownNode(XmlNode unknownNode, object o, string qnames)
  1124.         {
  1125.             if (unknownNode == null)
  1126.                 return;
  1127.             if (unknownNode.NodeType != XmlNodeType.None && unknownNode.NodeType != XmlNodeType.Whitespace && events.OnUnknownNode != null) {
  1128.                 int lineNumber;
  1129.                 int linePosition;
  1130.                 GetCurrentPosition(out lineNumber, out linePosition);
  1131.                 XmlNodeEventArgs e = new XmlNodeEventArgs(unknownNode, lineNumber, linePosition, o);
  1132.                 events.OnUnknownNode(events.sender, e);
  1133.             }
  1134.             if (unknownNode.NodeType == XmlNodeType.Attribute) {
  1135.                 UnknownAttribute(o, (XmlAttribute)unknownNode, qnames);
  1136.             }
  1137.             else if (unknownNode.NodeType == XmlNodeType.Element) {
  1138.                 UnknownElement(o, (XmlElement)unknownNode, qnames);
  1139.             }
  1140.         }
  1141.        
  1142.        
  1143.         void GetCurrentPosition(out int lineNumber, out int linePosition)
  1144.         {
  1145.             if (Reader is IXmlLineInfo) {
  1146.                 IXmlLineInfo lineInfo = (IXmlLineInfo)Reader;
  1147.                 lineNumber = lineInfo.LineNumber;
  1148.                 linePosition = lineInfo.LinePosition;
  1149.             }
  1150.             else
  1151.                 lineNumber = linePosition = -1;
  1152.         }
  1153.        
  1154.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.UnreferencedObject"]/*' />
  1155.         protected void UnreferencedObject(string id, object o)
  1156.         {
  1157.             if (events.OnUnreferencedObject != null) {
  1158.                 UnreferencedObjectEventArgs e = new UnreferencedObjectEventArgs(o, id);
  1159.                 events.OnUnreferencedObject(events.sender, e);
  1160.             }
  1161.         }
  1162.        
  1163.         string CurrentTag()
  1164.         {
  1165.             switch (r.NodeType) {
  1166.                 case XmlNodeType.Element:
  1167.                     return "<" + r.LocalName + " xmlns='" + r.NamespaceURI + "'>";
  1168.                 case XmlNodeType.EndElement:
  1169.                     return ">";
  1170.                 case XmlNodeType.Text:
  1171.                     return r.Value;
  1172.                 case XmlNodeType.CDATA:
  1173.                     return "CDATA";
  1174.                 case XmlNodeType.Comment:
  1175.                     return "<--";
  1176.                 case XmlNodeType.ProcessingInstruction:
  1177.                     return "<?";
  1178.                 default:
  1179.                     return "(unknown)";
  1180.             }
  1181.         }
  1182.        
  1183.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CreateUnknownTypeException"]/*' />
  1184.         protected Exception CreateUnknownTypeException(XmlQualifiedName type)
  1185.         {
  1186.             return new InvalidOperationException(Res.GetString(Res.XmlUnknownType, type.Name, type.Namespace, CurrentTag()));
  1187.         }
  1188.        
  1189.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CreateReadOnlyCollectionException"]/*' />
  1190.         protected Exception CreateReadOnlyCollectionException(string name)
  1191.         {
  1192.             return new InvalidOperationException(Res.GetString(Res.XmlReadOnlyCollection, name));
  1193.         }
  1194.        
  1195.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CreateAbstractTypeException"]/*' />
  1196.         protected Exception CreateAbstractTypeException(string name, string ns)
  1197.         {
  1198.             return new InvalidOperationException(Res.GetString(Res.XmlAbstractType, name, ns, CurrentTag()));
  1199.         }
  1200.        
  1201.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CreateInaccessibleConstructorException"]/*' />
  1202.         protected Exception CreateInaccessibleConstructorException(string typeName)
  1203.         {
  1204.             return new InvalidOperationException(Res.GetString(Res.XmlConstructorInaccessible, typeName));
  1205.         }
  1206.        
  1207.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CreateCtorHasSecurityException"]/*' />
  1208.         protected Exception CreateCtorHasSecurityException(string typeName)
  1209.         {
  1210.             return new InvalidOperationException(Res.GetString(Res.XmlConstructorHasSecurityAttributes, typeName));
  1211.         }
  1212.        
  1213.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CreateUnknownNodeException"]/*' />
  1214.         protected Exception CreateUnknownNodeException()
  1215.         {
  1216.             return new InvalidOperationException(Res.GetString(Res.XmlUnknownNode, CurrentTag()));
  1217.         }
  1218.        
  1219.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CreateUnknownConstantException"]/*' />
  1220.         protected Exception CreateUnknownConstantException(string value, Type enumType)
  1221.         {
  1222.             return new InvalidOperationException(Res.GetString(Res.XmlUnknownConstant, value, enumType.Name));
  1223.         }
  1224.        
  1225.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CreateInvalidCastException"]/*' />
  1226.         protected Exception CreateInvalidCastException(Type type, object value)
  1227.         {
  1228.             return CreateInvalidCastException(type, value, null);
  1229.         }
  1230.        
  1231.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CreateInvalidCastException1"]/*' />
  1232.         protected Exception CreateInvalidCastException(Type type, object value, string id)
  1233.         {
  1234.             if (value == null)
  1235.                 return new InvalidCastException(Res.GetString(Res.XmlInvalidNullCast, type.FullName));
  1236.             else if (id == null)
  1237.                 return new InvalidCastException(Res.GetString(Res.XmlInvalidCast, value.GetType().FullName, type.FullName));
  1238.             else
  1239.                 return new InvalidCastException(Res.GetString(Res.XmlInvalidCastWithId, value.GetType().FullName, type.FullName, id));
  1240.            
  1241.         }
  1242.        
  1243.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CreateBadDerivationException"]/*' />
  1244.         protected Exception CreateBadDerivationException(string xsdDerived, string nsDerived, string xsdBase, string nsBase, string clrDerived, string clrBase)
  1245.         {
  1246.             return new InvalidOperationException(Res.GetString(Res.XmlSerializableBadDerivation, xsdDerived, nsDerived, xsdBase, nsBase, clrDerived, clrBase));
  1247.         }
  1248.        
  1249.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CreateMissingIXmlSerializableType"]/*' />
  1250.         protected Exception CreateMissingIXmlSerializableType(string name, string ns, string clrType)
  1251.         {
  1252.             return new InvalidOperationException(Res.GetString(Res.XmlSerializableMissingClrType, name, ns, typeof(XmlIncludeAttribute).Name, clrType));
  1253.         }
  1254.        
  1255.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.EnsureArrayIndex"]/*' />
  1256.         protected Array EnsureArrayIndex(Array a, int index, Type elementType)
  1257.         {
  1258.             if (a == null)
  1259.                 return Array.CreateInstance(elementType, 32);
  1260.             if (index < a.Length)
  1261.                 return a;
  1262.             Array b = Array.CreateInstance(elementType, a.Length * 2);
  1263.             Array.Copy(a, b, index);
  1264.             return b;
  1265.         }
  1266.        
  1267.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ShrinkArray"]/*' />
  1268.         protected Array ShrinkArray(Array a, int length, Type elementType, bool isNullable)
  1269.         {
  1270.             if (a == null) {
  1271.                 if (isNullable)
  1272.                     return null;
  1273.                 return Array.CreateInstance(elementType, 0);
  1274.             }
  1275.             if (a.Length == length)
  1276.                 return a;
  1277.             Array b = Array.CreateInstance(elementType, length);
  1278.             Array.Copy(a, b, length);
  1279.             return b;
  1280.         }
  1281.        
  1282.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadString"]/*' />
  1283.         protected string ReadString(string value)
  1284.         {
  1285.             return ReadString(value, false);
  1286.         }
  1287.        
  1288.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadString1"]/*' />
  1289.         protected string ReadString(string value, bool trim)
  1290.         {
  1291.             string str = r.ReadString();
  1292.             if (str != null && trim)
  1293.                 str = str.Trim();
  1294.             if (value == null || value.Length == 0)
  1295.                 return str;
  1296.             return value + str;
  1297.         }
  1298.        
  1299.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadSerializable"]/*' />
  1300.         protected IXmlSerializable ReadSerializable(IXmlSerializable serializable)
  1301.         {
  1302.             serializable.ReadXml(r);
  1303.             return serializable;
  1304.         }
  1305.        
  1306.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadReference"]/*' />
  1307.         protected bool ReadReference(out string fixupReference)
  1308.         {
  1309.             string href = soap12 ? r.GetAttribute("ref", Soap12.Encoding) : r.GetAttribute("href");
  1310.             if (href == null) {
  1311.                 fixupReference = null;
  1312.                 return false;
  1313.             }
  1314.             if (!soap12) {
  1315.                 // soap 1.1 href starts with '#'; soap 1.2 ref does not
  1316.                 if (!href.StartsWith("#", StringComparison.Ordinal))
  1317.                     throw new InvalidOperationException(Res.GetString(Res.XmlMissingHref, href));
  1318.                 fixupReference = href.Substring(1);
  1319.             }
  1320.             else
  1321.                 fixupReference = href;
  1322.            
  1323.             if (r.IsEmptyElement) {
  1324.                 r.Skip();
  1325.             }
  1326.             else {
  1327.                 r.ReadStartElement();
  1328.                 ReadEndElement();
  1329.             }
  1330.             return true;
  1331.         }
  1332.        
  1333.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.AddTarget"]/*' />
  1334.         protected void AddTarget(string id, object o)
  1335.         {
  1336.             if (id == null) {
  1337.                 if (targetsWithoutIds == null)
  1338.                     targetsWithoutIds = new ArrayList();
  1339.                 if (o != null)
  1340.                     targetsWithoutIds.Add(o);
  1341.             }
  1342.             else {
  1343.                 if (targets == null)
  1344.                     targets = new Hashtable();
  1345.                 if (!targets.Contains(id))
  1346.                     targets.Add(id, o);
  1347.             }
  1348.         }
  1349.        
  1350.        
  1351.        
  1352.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.AddFixup"]/*' />
  1353.         protected void AddFixup(Fixup fixup)
  1354.         {
  1355.             if (fixups == null)
  1356.                 fixups = new ArrayList();
  1357.             fixups.Add(fixup);
  1358.         }
  1359.        
  1360.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.AddFixup2"]/*' />
  1361.         protected void AddFixup(CollectionFixup fixup)
  1362.         {
  1363.             if (collectionFixups == null)
  1364.                 collectionFixups = new ArrayList();
  1365.             collectionFixups.Add(fixup);
  1366.         }
  1367.        
  1368.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.GetTarget"]/*' />
  1369.         protected object GetTarget(string id)
  1370.         {
  1371.             object target = targets != null ? targets[id] : null;
  1372.             if (target == null) {
  1373.                 throw new InvalidOperationException(Res.GetString(Res.XmlInvalidHref, id));
  1374.             }
  1375.             Referenced(target);
  1376.             return target;
  1377.         }
  1378.        
  1379.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.Referenced"]/*' />
  1380.         protected void Referenced(object o)
  1381.         {
  1382.             if (o == null)
  1383.                 return;
  1384.             if (referencedTargets == null)
  1385.                 referencedTargets = new Hashtable();
  1386.             referencedTargets[o] = o;
  1387.         }
  1388.        
  1389.         void HandleUnreferencedObjects()
  1390.         {
  1391.             if (targets != null) {
  1392.                 foreach (DictionaryEntry target in targets) {
  1393.                     if (referencedTargets == null || !referencedTargets.Contains(target.Value)) {
  1394.                         UnreferencedObject((string)target.Key, target.Value);
  1395.                     }
  1396.                 }
  1397.             }
  1398.             if (targetsWithoutIds != null) {
  1399.                 foreach (object o in targetsWithoutIds) {
  1400.                     if (referencedTargets == null || !referencedTargets.Contains(o)) {
  1401.                         UnreferencedObject(null, o);
  1402.                     }
  1403.                 }
  1404.             }
  1405.         }
  1406.        
  1407.         void DoFixups()
  1408.         {
  1409.             if (fixups == null)
  1410.                 return;
  1411.             for (int i = 0; i < fixups.Count; i++) {
  1412.                 Fixup fixup = (Fixup)fixups[i];
  1413.                 fixup.Callback(fixup);
  1414.             }
  1415.            
  1416.             if (collectionFixups == null)
  1417.                 return;
  1418.             for (int i = 0; i < collectionFixups.Count; i++) {
  1419.                 CollectionFixup collectionFixup = (CollectionFixup)collectionFixups[i];
  1420.                 collectionFixup.Callback(collectionFixup.Collection, collectionFixup.CollectionItems);
  1421.             }
  1422.         }
  1423.        
  1424.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.FixupArrayRefs"]/*' />
  1425.         protected void FixupArrayRefs(object fixup)
  1426.         {
  1427.             Fixup f = (Fixup)fixup;
  1428.             Array array = (Array)f.Source;
  1429.             for (int i = 0; i < array.Length; i++) {
  1430.                 string id = f.Ids[i];
  1431.                 if (id == null)
  1432.                     continue;
  1433.                 object o = GetTarget(id);
  1434.                 try {
  1435.                     array.SetValue(o, i);
  1436.                 }
  1437.                 catch (InvalidCastException) {
  1438.                     throw new InvalidOperationException(Res.GetString(Res.XmlInvalidArrayRef, id, o.GetType().FullName, i.ToString(CultureInfo.InvariantCulture)));
  1439.                 }
  1440.             }
  1441.         }
  1442.        
  1443.         object ReadArray(string typeName, string typeNs)
  1444.         {
  1445.             SoapArrayInfo arrayInfo;
  1446.             Type fallbackElementType = null;
  1447.             if (soap12) {
  1448.                 string itemType = r.GetAttribute(itemTypeID, soap12NsID);
  1449.                 string arraySize = r.GetAttribute(arraySizeID, soap12NsID);
  1450.                 Type arrayType = (Type)types[new XmlQualifiedName(typeName, typeNs)];
  1451.                 // no indication that this is an array?
  1452.                 if (itemType == null && arraySize == null && (arrayType == null || !arrayType.IsArray))
  1453.                     return null;
  1454.                
  1455.                 arrayInfo = ParseSoap12ArrayType(itemType, arraySize);
  1456.                 if (arrayType != null)
  1457.                     fallbackElementType = TypeScope.GetArrayElementType(arrayType, null);
  1458.             }
  1459.             else {
  1460.                 string arrayType = r.GetAttribute(arrayTypeID, soapNsID);
  1461.                 if (arrayType == null)
  1462.                     return null;
  1463.                
  1464.                 arrayInfo = ParseArrayType(arrayType);
  1465.             }
  1466.            
  1467.             if (arrayInfo.dimensions != 1)
  1468.                 throw new InvalidOperationException(Res.GetString(Res.XmlInvalidArrayDimentions, CurrentTag()));
  1469.            
  1470.             // NOTE: don't use the array size that is specified since an evil client might pass
  1471.             // a number larger than the actual number of items in an attempt to harm the server.
  1472.            
  1473.             XmlQualifiedName qname;
  1474.             bool isPrimitive;
  1475.             Type elementType = null;
  1476.             XmlQualifiedName urTypeName = new XmlQualifiedName(urTypeID, schemaNsID);
  1477.             if (arrayInfo.qname.Length > 0) {
  1478.                 qname = ToXmlQualifiedName(arrayInfo.qname, false);
  1479.                 elementType = (Type)types[qname];
  1480.             }
  1481.             else
  1482.                 qname = urTypeName;
  1483.            
  1484.             // try again if the best we could come up with was object
  1485.             if (soap12 && elementType == typeof(object))
  1486.                 elementType = null;
  1487.            
  1488.             if (elementType == null) {
  1489.                 if (!soap12) {
  1490.                     elementType = GetPrimitiveType(qname, true);
  1491.                     isPrimitive = true;
  1492.                 }
  1493.                 else {
  1494.                     // try it as a primitive
  1495.                     if (qname != urTypeName)
  1496.                         elementType = GetPrimitiveType(qname, false);
  1497.                     if (elementType != null) {
  1498.                         isPrimitive = true;
  1499.                     }
  1500.                     else {
  1501.                         // still nothing: go with fallback type or object
  1502.                         if (fallbackElementType == null) {
  1503.                             elementType = typeof(object);
  1504.                             isPrimitive = false;
  1505.                         }
  1506.                         else {
  1507.                             elementType = fallbackElementType;
  1508.                             XmlQualifiedName newQname = (XmlQualifiedName)typesReverse[elementType];
  1509.                             if (newQname == null) {
  1510.                                 newQname = XmlSerializationWriter.GetPrimitiveTypeNameInternal(elementType);
  1511.                                 isPrimitive = true;
  1512.                             }
  1513.                             else
  1514.                                 isPrimitive = elementType.IsPrimitive;
  1515.                             if (newQname != null)
  1516.                                 qname = newQname;
  1517.                         }
  1518.                     }
  1519.                 }
  1520.             }
  1521.             else
  1522.                 isPrimitive = elementType.IsPrimitive;
  1523.            
  1524.             if (!soap12 && arrayInfo.jaggedDimensions > 0) {
  1525.                 for (int i = 0; i < arrayInfo.jaggedDimensions; i++)
  1526.                     elementType = elementType.MakeArrayType();
  1527.             }
  1528.            
  1529.             if (r.IsEmptyElement) {
  1530.                 r.Skip();
  1531.                 return Array.CreateInstance(elementType, 0);
  1532.             }
  1533.            
  1534.             r.ReadStartElement();
  1535.             r.MoveToContent();
  1536.            
  1537.             int arrayLength = 0;
  1538.             Array array = null;
  1539.            
  1540.             if (elementType.IsValueType) {
  1541.                 if (!isPrimitive && !elementType.IsEnum) {
  1542.                     throw new NotSupportedException(Res.GetString(Res.XmlRpcArrayOfValueTypes, elementType.FullName));
  1543.                 }
  1544.                 int whileIterations = 0;
  1545.                 int readerCount = ReaderCount;
  1546.                 while (r.NodeType != XmlNodeType.EndElement) {
  1547.                     array = EnsureArrayIndex(array, arrayLength, elementType);
  1548.                     array.SetValue(ReadReferencedElement(qname.Name, qname.Namespace), arrayLength);
  1549.                     arrayLength++;
  1550.                     r.MoveToContent();
  1551.                     CheckReaderCount(ref whileIterations, ref readerCount);
  1552.                 }
  1553.                 array = ShrinkArray(array, arrayLength, elementType, false);
  1554.             }
  1555.             else {
  1556.                 string type;
  1557.                 string typens;
  1558.                 string[] ids = null;
  1559.                 int idsLength = 0;
  1560.                
  1561.                 int whileIterations = 0;
  1562.                 int readerCount = ReaderCount;
  1563.                 while (r.NodeType != XmlNodeType.EndElement) {
  1564.                     array = EnsureArrayIndex(array, arrayLength, elementType);
  1565.                     ids = (string[])EnsureArrayIndex(ids, idsLength, typeof(string));
  1566.                     if (r.NamespaceURI.Length != 0) {
  1567.                         type = r.LocalName;
  1568.                         if ((object)r.NamespaceURI == (object)soapNsID)
  1569.                             typens = XmlSchema.Namespace;
  1570.                         else
  1571.                             typens = r.NamespaceURI;
  1572.                     }
  1573.                     else {
  1574.                         type = qname.Name;
  1575.                         typens = qname.Namespace;
  1576.                     }
  1577.                     array.SetValue(ReadReferencingElement(type, typens, out ids[idsLength]), arrayLength);
  1578.                     arrayLength++;
  1579.                     idsLength++;
  1580.                     r.MoveToContent();
  1581.                     CheckReaderCount(ref whileIterations, ref readerCount);
  1582.                 }
  1583.                
  1584.                 // special case for soap 1.2: try to get a better fit than object[] when no metadata is known
  1585.                 // this applies in the doc/enc/bare case
  1586.                 if (soap12 && elementType == typeof(object)) {
  1587.                     Type itemType = null;
  1588.                     for (int i = 0; i < arrayLength; i++) {
  1589.                         object currItem = array.GetValue(i);
  1590.                         if (currItem != null) {
  1591.                             Type currItemType = currItem.GetType();
  1592.                             if (currItemType.IsValueType) {
  1593.                                 itemType = null;
  1594.                                 break;
  1595.                             }
  1596.                             if (itemType == null || currItemType.IsAssignableFrom(itemType)) {
  1597.                                 itemType = currItemType;
  1598.                             }
  1599.                             else if (!itemType.IsAssignableFrom(currItemType)) {
  1600.                                 itemType = null;
  1601.                                 break;
  1602.                             }
  1603.                         }
  1604.                     }
  1605.                     if (itemType != null)
  1606.                         elementType = itemType;
  1607.                 }
  1608.                 ids = (string[])ShrinkArray(ids, idsLength, typeof(string), false);
  1609.                 array = ShrinkArray(array, arrayLength, elementType, false);
  1610.                 Fixup fixupArray = new Fixup(array, new XmlSerializationFixupCallback(this.FixupArrayRefs), ids);
  1611.                 AddFixup(fixupArray);
  1612.             }
  1613.            
  1614.            
  1615.             ReadEndElement();
  1616.             return array;
  1617.         }
  1618.        
  1619.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.InitCallbacks"]/*' />
  1620.         protected abstract void InitCallbacks();
  1621.        
  1622.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadReferencedElements"]/*' />
  1623.         protected void ReadReferencedElements()
  1624.         {
  1625.             r.MoveToContent();
  1626.             string dummy;
  1627.             int whileIterations = 0;
  1628.             int readerCount = ReaderCount;
  1629.             while (r.NodeType != XmlNodeType.EndElement && r.NodeType != XmlNodeType.None) {
  1630.                 ReadReferencingElement(null, null, true, out dummy);
  1631.                 r.MoveToContent();
  1632.                 CheckReaderCount(ref whileIterations, ref readerCount);
  1633.             }
  1634.             DoFixups();
  1635.            
  1636.             HandleUnreferencedObjects();
  1637.         }
  1638.        
  1639.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadReferencedElement"]/*' />
  1640.         protected object ReadReferencedElement()
  1641.         {
  1642.             return ReadReferencedElement(null, null);
  1643.         }
  1644.        
  1645.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadReferencedElement1"]/*' />
  1646.         protected object ReadReferencedElement(string name, string ns)
  1647.         {
  1648.             string dummy;
  1649.             return ReadReferencingElement(name, ns, out dummy);
  1650.         }
  1651.        
  1652.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadReferencingElement"]/*' />
  1653.         protected object ReadReferencingElement(out string fixupReference)
  1654.         {
  1655.             return ReadReferencingElement(null, null, out fixupReference);
  1656.         }
  1657.        
  1658.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadReferencingElement1"]/*' />
  1659.         protected object ReadReferencingElement(string name, string ns, out string fixupReference)
  1660.         {
  1661.             return ReadReferencingElement(name, ns, false, out fixupReference);
  1662.         }
  1663.        
  1664.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadReferencingElement2"]/*' />
  1665.         protected object ReadReferencingElement(string name, string ns, bool elementCanBeType, out string fixupReference)
  1666.         {
  1667.             object o = null;
  1668.            
  1669.             if (callbacks == null) {
  1670.                 callbacks = new Hashtable();
  1671.                 types = new Hashtable();
  1672.                 XmlQualifiedName urType = new XmlQualifiedName(urTypeID, r.NameTable.Add(XmlSchema.Namespace));
  1673.                 types.Add(urType, typeof(object));
  1674.                 typesReverse = new Hashtable();
  1675.                 typesReverse.Add(typeof(object), urType);
  1676.                 InitCallbacks();
  1677.             }
  1678.            
  1679.             r.MoveToContent();
  1680.            
  1681.             if (ReadReference(out fixupReference))
  1682.                 return null;
  1683.            
  1684.             if (ReadNull())
  1685.                 return null;
  1686.            
  1687.             string id = soap12 ? r.GetAttribute("id", Soap12.Encoding) : r.GetAttribute("id", null);
  1688.            
  1689.             if ((o = ReadArray(name, ns)) == null) {
  1690.                 XmlQualifiedName typeId = GetXsiType();
  1691.                 if (typeId == null) {
  1692.                     if (name == null)
  1693.                         typeId = new XmlQualifiedName(r.NameTable.Add(r.LocalName), r.NameTable.Add(r.NamespaceURI));
  1694.                     else
  1695.                         typeId = new XmlQualifiedName(r.NameTable.Add(name), r.NameTable.Add(ns));
  1696.                 }
  1697.                 XmlSerializationReadCallback callback = (XmlSerializationReadCallback)callbacks[typeId];
  1698.                 if (callback != null) {
  1699.                     o = callback();
  1700.                 }
  1701.                 else
  1702.                     o = ReadTypedPrimitive(typeId, elementCanBeType);
  1703.             }
  1704.            
  1705.             AddTarget(id, o);
  1706.            
  1707.             return o;
  1708.         }
  1709.        
  1710.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.AddReadCallback"]/*' />
  1711.         protected void AddReadCallback(string name, string ns, Type type, XmlSerializationReadCallback read)
  1712.         {
  1713.             XmlQualifiedName typeName = new XmlQualifiedName(r.NameTable.Add(name), r.NameTable.Add(ns));
  1714.             callbacks.Add(typeName, read);
  1715.             types.Add(typeName, type);
  1716.             typesReverse[type] = typeName;
  1717.         }
  1718.        
  1719.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.ReadEndElement"]/*' />
  1720.         protected void ReadEndElement()
  1721.         {
  1722.             while (r.NodeType == XmlNodeType.Whitespace)
  1723.                 r.Skip();
  1724.             if (r.NodeType == XmlNodeType.None)
  1725.                 r.Skip();
  1726.             else
  1727.                 r.ReadEndElement();
  1728.         }
  1729.        
  1730.         object ReadXmlNodes(bool elementCanBeType)
  1731.         {
  1732.            
  1733.             ArrayList xmlNodeList = new ArrayList();
  1734.             string elemLocalName = Reader.LocalName;
  1735.             string elemNs = Reader.NamespaceURI;
  1736.             string elemName = Reader.Name;
  1737.             string xsiTypeName = null;
  1738.             string xsiTypeNs = null;
  1739.             int skippableNodeCount = 0;
  1740.             int lineNumber = -1;
  1741.             int linePosition = -1;
  1742.             XmlNode unknownNode = null;
  1743.             if (Reader.NodeType == XmlNodeType.Attribute) {
  1744.                 XmlAttribute attr = Document.CreateAttribute(elemName, elemNs);
  1745.                 attr.Value = Reader.Value;
  1746.                 unknownNode = attr;
  1747.             }
  1748.             else
  1749.                 unknownNode = Document.CreateElement(elemName, elemNs);
  1750.             GetCurrentPosition(out lineNumber, out linePosition);
  1751.             XmlElement unknownElement = unknownNode as XmlElement;
  1752.            
  1753.             while (Reader.MoveToNextAttribute()) {
  1754.                 if (IsXmlnsAttribute(Reader.Name) || (Reader.Name == "id" && (!soap12 || Reader.NamespaceURI == Soap12.Encoding)))
  1755.                     skippableNodeCount++;
  1756.                 if ((object)Reader.LocalName == (object)typeID && ((object)Reader.NamespaceURI == (object)instanceNsID || (object)Reader.NamespaceURI == (object)instanceNs2000ID || (object)Reader.NamespaceURI == (object)instanceNs1999ID)) {
  1757.                     string value = Reader.Value;
  1758.                     int colon = value.LastIndexOf(':');
  1759.                     xsiTypeName = (colon >= 0) ? value.Substring(colon + 1) : value;
  1760.                     xsiTypeNs = Reader.LookupNamespace((colon >= 0) ? value.Substring(0, colon) : "");
  1761.                 }
  1762.                 XmlAttribute xmlAttribute = (XmlAttribute)Document.ReadNode(r);
  1763.                 xmlNodeList.Add(xmlAttribute);
  1764.                 if (unknownElement != null)
  1765.                     unknownElement.SetAttributeNode(xmlAttribute);
  1766.             }
  1767.            
  1768.             // If the node is referenced (or in case of paramStyle = bare) and if xsi:type is not
  1769.             // specified then the element name is used as the type name. Reveal this to the user
  1770.             // by adding an extra attribute node "xsi:type" with value as the element name.
  1771.             if (elementCanBeType && xsiTypeName == null) {
  1772.                 xsiTypeName = elemLocalName;
  1773.                 xsiTypeNs = elemNs;
  1774.                 XmlAttribute xsiTypeAttribute = Document.CreateAttribute(typeID, instanceNsID);
  1775.                 xsiTypeAttribute.Value = elemName;
  1776.                 xmlNodeList.Add(xsiTypeAttribute);
  1777.             }
  1778.             if (xsiTypeName == Soap.UrType && ((object)xsiTypeNs == (object)schemaNsID || (object)xsiTypeNs == (object)schemaNs1999ID || (object)xsiTypeNs == (object)schemaNs2000ID))
  1779.                 skippableNodeCount++;
  1780.            
  1781.            
  1782.             Reader.MoveToElement();
  1783.             if (Reader.IsEmptyElement) {
  1784.                 Reader.Skip();
  1785.             }
  1786.             else {
  1787.                 Reader.ReadStartElement();
  1788.                 Reader.MoveToContent();
  1789.                 int whileIterations = 0;
  1790.                 int readerCount = ReaderCount;
  1791.                 while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) {
  1792.                     XmlNode xmlNode = Document.ReadNode(r);
  1793.                     xmlNodeList.Add(xmlNode);
  1794.                     if (unknownElement != null)
  1795.                         unknownElement.AppendChild(xmlNode);
  1796.                     Reader.MoveToContent();
  1797.                     CheckReaderCount(ref whileIterations, ref readerCount);
  1798.                 }
  1799.                 ReadEndElement();
  1800.                
  1801.             }
  1802.            
  1803.            
  1804.             if (xmlNodeList.Count <= skippableNodeCount)
  1805.                 return new object();
  1806.            
  1807.             XmlNode[] childNodes = (XmlNode[])xmlNodeList.ToArray(typeof(XmlNode));
  1808.            
  1809.             UnknownNode(unknownNode, null, null);
  1810.             return childNodes;
  1811.         }
  1812.        
  1813.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReader.CheckReaderCount"]/*' />
  1814.         protected void CheckReaderCount(ref int whileIterations, ref int readerCount)
  1815.         {
  1816.             if (checkDeserializeAdvances) {
  1817.                 whileIterations++;
  1818.                 if ((whileIterations & 128) == 128) {
  1819.                     if (readerCount == ReaderCount)
  1820.                         throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorReaderAdvance));
  1821.                     readerCount = ReaderCount;
  1822.                 }
  1823.             }
  1824.         }
  1825.        
  1826.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="Fixup"]/*' />
  1827.         ///<internalonly/>
  1828.         protected class Fixup
  1829.         {
  1830.             XmlSerializationFixupCallback callback;
  1831.             object source;
  1832.             string[] ids;
  1833.            
  1834.             /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="Fixup.Fixup1"]/*' />
  1835.             public Fixup(object o, XmlSerializationFixupCallback callback, int count) : this(o, callback, new string[count])
  1836.             {
  1837.             }
  1838.            
  1839.             /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="Fixup.Fixup2"]/*' />
  1840.             public Fixup(object o, XmlSerializationFixupCallback callback, string[] ids)
  1841.             {
  1842.                 this.callback = callback;
  1843.                 this.Source = o;
  1844.                 this.ids = ids;
  1845.             }
  1846.            
  1847.             /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="Fixup.Callback"]/*' />
  1848.             public XmlSerializationFixupCallback Callback {
  1849.                 get { return callback; }
  1850.             }
  1851.            
  1852.             /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="Fixup.Source"]/*' />
  1853.             public object Source {
  1854.                 get { return source; }
  1855.                 set { source = value; }
  1856.             }
  1857.            
  1858.             /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="Fixup.Ids"]/*' />
  1859.             public string[] Ids {
  1860.                 get { return ids; }
  1861.             }
  1862.         }
  1863.        
  1864.         /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="CollectionFixup"]/*' />
  1865.         protected class CollectionFixup
  1866.         {
  1867.             XmlSerializationCollectionFixupCallback callback;
  1868.             object collection;
  1869.             object collectionItems;
  1870.            
  1871.             /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="CollectionFixup.CollectionFixup"]/*' />
  1872.             public CollectionFixup(object collection, XmlSerializationCollectionFixupCallback callback, object collectionItems)
  1873.             {
  1874.                 this.callback = callback;
  1875.                 this.collection = collection;
  1876.                 this.collectionItems = collectionItems;
  1877.             }
  1878.            
  1879.             /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="CollectionFixup.Callback"]/*' />
  1880.             public XmlSerializationCollectionFixupCallback Callback {
  1881.                 get { return callback; }
  1882.             }
  1883.            
  1884.             /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="CollectionFixup.Collection"]/*' />
  1885.             public object Collection {
  1886.                 get { return collection; }
  1887.             }
  1888.            
  1889.             /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="CollectionFixup.CollectionItems"]/*' />
  1890.             public object CollectionItems {
  1891.                 get { return collectionItems; }
  1892.             }
  1893.         }
  1894.     }
  1895.    
  1896.     /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationFixupCallback"]/*' />
  1897.     ///<internalonly/>
  1898.     public delegate void XmlSerializationFixupCallback(object fixup);
  1899.    
  1900.    
  1901.     /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationCollectionFixupCallback"]/*' />
  1902.     ///<internalonly/>
  1903.     public delegate void XmlSerializationCollectionFixupCallback(object collection, object collectionItems);
  1904.    
  1905.     /// <include file='doc\XmlSerializationReader.uex' path='docs/doc[@for="XmlSerializationReadCallback"]/*' />
  1906.     ///<internalonly/>
  1907.     public delegate object XmlSerializationReadCallback();
  1908.    
  1909.     internal class XmlSerializationReaderCodeGen : XmlSerializationCodeGen
  1910.     {
  1911.         Hashtable idNames = new Hashtable();
  1912.         Hashtable enums;
  1913.         Hashtable createMethods = new Hashtable();
  1914.         int nextCreateMethodNumber = 0;
  1915.         int nextIdNumber = 0;
  1916.         int nextWhileLoopIndex = 0;
  1917.        
  1918.         internal Hashtable Enums {
  1919.             get {
  1920.                 if (enums == null) {
  1921.                     enums = new Hashtable();
  1922.                 }
  1923.                 return enums;
  1924.             }
  1925.         }
  1926.        
  1927.         class CreateCollectionInfo
  1928.         {
  1929.             string name;
  1930.             TypeDesc td;
  1931.            
  1932.             internal CreateCollectionInfo(string name, TypeDesc td)
  1933.             {
  1934.                 this.name = name;
  1935.                 this.td = td;
  1936.             }
  1937.             internal string Name {
  1938.                 get { return name; }
  1939.             }
  1940.            
  1941.             internal TypeDesc TypeDesc {
  1942.                 get { return td; }
  1943.             }
  1944.         }
  1945.         class Member
  1946.         {
  1947.             string source;
  1948.             string arrayName;
  1949.             string arraySource;
  1950.             string choiceArrayName;
  1951.             string choiceSource;
  1952.             string choiceArraySource;
  1953.             MemberMapping mapping;
  1954.             bool isArray;
  1955.             bool isList;
  1956.             bool isNullable;
  1957.             bool multiRef;
  1958.             int fixupIndex = -1;
  1959.             string paramsReadSource;
  1960.             string checkSpecifiedSource;
  1961.            
  1962.             internal Member(XmlSerializationReaderCodeGen outerClass, string source, string arrayName, int i, MemberMapping mapping) : this(outerClass, source, null, arrayName, i, mapping, false, null)
  1963.             {
  1964.             }
  1965.             internal Member(XmlSerializationReaderCodeGen outerClass, string source, string arrayName, int i, MemberMapping mapping, string choiceSource) : this(outerClass, source, null, arrayName, i, mapping, false, choiceSource)
  1966.             {
  1967.             }
  1968.             internal Member(XmlSerializationReaderCodeGen outerClass, string source, string arraySource, string arrayName, int i, MemberMapping mapping) : this(outerClass, source, arraySource, arrayName, i, mapping, false, null)
  1969.             {
  1970.             }
  1971.             internal Member(XmlSerializationReaderCodeGen outerClass, string source, string arraySource, string arrayName, int i, MemberMapping mapping, string choiceSource) : this(outerClass, source, arraySource, arrayName, i, mapping, false, choiceSource)
  1972.             {
  1973.             }
  1974.             internal Member(XmlSerializationReaderCodeGen outerClass, string source, string arrayName, int i, MemberMapping mapping, bool multiRef) : this(outerClass, source, null, arrayName, i, mapping, multiRef, null)
  1975.             {
  1976.             }
  1977.             internal Member(XmlSerializationReaderCodeGen outerClass, string source, string arraySource, string arrayName, int i, MemberMapping mapping, bool multiRef, string choiceSource)
  1978.             {
  1979.                 this.source = source;
  1980.                 this.arrayName = arrayName + "_" + i.ToString(CultureInfo.InvariantCulture);
  1981.                 this.choiceArrayName = "choice_" + this.arrayName;
  1982.                 this.choiceSource = choiceSource;
  1983.                 ElementAccessor[] elements = mapping.Elements;
  1984.                
  1985.                 if (mapping.TypeDesc.IsArrayLike) {
  1986.                     if (arraySource != null)
  1987.                         this.arraySource = arraySource;
  1988.                     else
  1989.                         this.arraySource = outerClass.GetArraySource(mapping.TypeDesc, this.arrayName, multiRef);
  1990.                     isArray = mapping.TypeDesc.IsArray;
  1991.                     isList = !isArray;
  1992.                     if (mapping.ChoiceIdentifier != null) {
  1993.                         this.choiceArraySource = outerClass.GetArraySource(mapping.TypeDesc, this.choiceArrayName, multiRef);
  1994.                        
  1995.                         string a = choiceArrayName;
  1996.                         string c = "c" + a;
  1997.                         bool choiceUseReflection = mapping.ChoiceIdentifier.Mapping.TypeDesc.UseReflection;
  1998.                         string choiceTypeFullName = mapping.ChoiceIdentifier.Mapping.TypeDesc.CSharpName;
  1999.                         string castString = choiceUseReflection ? "" : "(" + choiceTypeFullName + "[])";
  2000.                        
  2001.                         string init = a + " = " + castString + "EnsureArrayIndex(" + a + ", " + c + ", " + outerClass.RaCodeGen.GetStringForTypeof(choiceTypeFullName, choiceUseReflection) + ");";
  2002.                         this.choiceArraySource = init + outerClass.RaCodeGen.GetStringForArrayMember(a, c + "++", mapping.ChoiceIdentifier.Mapping.TypeDesc);
  2003.                     }
  2004.                     else {
  2005.                         this.choiceArraySource = this.choiceSource;
  2006.                     }
  2007.                 }
  2008.                 else {
  2009.                     this.arraySource = arraySource == null ? source : arraySource;
  2010.                     this.choiceArraySource = this.choiceSource;
  2011.                 }
  2012.                 this.mapping = mapping;
  2013.             }
  2014.            
  2015.             internal MemberMapping Mapping {
  2016.                 get { return mapping; }
  2017.             }
  2018.            
  2019.             internal string Source {
  2020.                 get { return source; }
  2021.             }
  2022.            
  2023.             internal string ArrayName {
  2024.                 get { return arrayName; }
  2025.             }
  2026.            
  2027.             internal string ArraySource {
  2028.                 get { return arraySource; }
  2029.             }
  2030.            
  2031.             internal bool IsList {
  2032.                 get { return isList; }
  2033.             }
  2034.            
  2035.             internal bool IsArrayLike {
  2036.                 get { return (isArray || isList); }
  2037.             }
  2038.            
  2039.             internal bool IsNullable {
  2040.                 get { return isNullable; }
  2041.                 set { isNullable = value; }
  2042.             }
  2043.            
  2044.             internal bool MultiRef {
  2045.                 get { return multiRef; }
  2046.                 set { multiRef = value; }
  2047.             }
  2048.            
  2049.             internal int FixupIndex {
  2050.                 get { return fixupIndex; }
  2051.                 set { fixupIndex = value; }
  2052.             }
  2053.            
  2054.             internal string ParamsReadSource {
  2055.                 get { return paramsReadSource; }
  2056.                 set { paramsReadSource = value; }
  2057.             }
  2058.            
  2059.             internal string CheckSpecifiedSource {
  2060.                 get { return checkSpecifiedSource; }
  2061.                 set { checkSpecifiedSource = value; }
  2062.             }
  2063.            
  2064.             internal string ChoiceSource {
  2065.                 get { return choiceSource; }
  2066.             }
  2067.             internal string ChoiceArrayName {
  2068.                 get { return choiceArrayName; }
  2069.             }
  2070.             internal string ChoiceArraySource {
  2071.                 get { return choiceArraySource; }
  2072.             }
  2073.         }
  2074.        
  2075.         internal XmlSerializationReaderCodeGen(IndentedWriter writer, TypeScope[] scopes, string access, string className) : base(writer, scopes, access, className)
  2076.         {
  2077.         }
  2078.        
  2079.         internal void GenerateBegin()
  2080.         {
  2081.             Writer.Write(Access);
  2082.             Writer.Write(" class ");
  2083.             Writer.Write(ClassName);
  2084.             Writer.Write(" : ");
  2085.             Writer.Write(typeof(XmlSerializationReader).FullName);
  2086.             Writer.WriteLine(" {");
  2087.             Writer.Indent++;
  2088.             foreach (TypeScope scope in Scopes) {
  2089.                 foreach (TypeMapping mapping in scope.TypeMappings) {
  2090.                     if (mapping is StructMapping || mapping is EnumMapping || mapping is NullableMapping)
  2091.                         MethodNames.Add(mapping, NextMethodName(mapping.TypeDesc.Name));
  2092.                 }
  2093.                 RaCodeGen.WriteReflectionInit(scope);
  2094.             }
  2095.             // pre-generate read methods only for the encoded soap
  2096.             foreach (TypeScope scope in Scopes) {
  2097.                 foreach (TypeMapping mapping in scope.TypeMappings) {
  2098.                     if (!mapping.IsSoap)
  2099.                         continue;
  2100.                     if (mapping is StructMapping)
  2101.                         WriteStructMethod((StructMapping)mapping);
  2102.                     else if (mapping is EnumMapping)
  2103.                         WriteEnumMethod((EnumMapping)mapping);
  2104.                     else if (mapping is NullableMapping) {
  2105.                         WriteNullableMethod((NullableMapping)mapping);
  2106.                     }
  2107.                 }
  2108.             }
  2109.         }
  2110.        
  2111.         internal override void GenerateMethod(TypeMapping mapping)
  2112.         {
  2113.             if (GeneratedMethods.Contains(mapping))
  2114.                 return;
  2115.            
  2116.             GeneratedMethods[mapping] = mapping;
  2117.             if (mapping is StructMapping) {
  2118.                 WriteStructMethod((StructMapping)mapping);
  2119.             }
  2120.             else if (mapping is EnumMapping) {
  2121.                 WriteEnumMethod((EnumMapping)mapping);
  2122.             }
  2123.             else if (mapping is NullableMapping) {
  2124.                 WriteNullableMethod((NullableMapping)mapping);
  2125.             }
  2126.         }
  2127.        
  2128.         internal void GenerateEnd()
  2129.         {
  2130.             GenerateEnd(new string[0], new XmlMapping[0], new Type[0]);
  2131.         }
  2132.         internal void GenerateEnd(string[] methods, XmlMapping[] xmlMappings, Type[] types)
  2133.         {
  2134.             GenerateReferencedMethods();
  2135.             GenerateInitCallbacksMethod();
  2136.            
  2137.             foreach (CreateCollectionInfo c in createMethods.Values) {
  2138.                 WriteCreateCollectionMethod(c);
  2139.             }
  2140.            
  2141.             Writer.WriteLine();
  2142.             foreach (string idName in idNames.Values) {
  2143.                 Writer.Write("string ");
  2144.                 Writer.Write(idName);
  2145.                 Writer.WriteLine(";");
  2146.             }
  2147.            
  2148.             Writer.WriteLine();
  2149.             Writer.WriteLine("protected override void InitIDs() {");
  2150.             Writer.Indent++;
  2151.             foreach (string id in idNames.Keys) {
  2152.                 string idName = (string)idNames[id];
  2153.                 Writer.Write(idName);
  2154.                 Writer.Write(" = Reader.NameTable.Add(");
  2155.                 WriteQuotedCSharpString(id);
  2156.                 Writer.WriteLine(");");
  2157.             }
  2158.             Writer.Indent--;
  2159.             Writer.WriteLine("}");
  2160.            
  2161.             Writer.Indent--;
  2162.             Writer.WriteLine("}");
  2163.         }
  2164.        
  2165.         internal string GenerateElement(XmlMapping xmlMapping)
  2166.         {
  2167.             if (!xmlMapping.IsReadable)
  2168.                 return null;
  2169.             if (!xmlMapping.GenerateSerializer)
  2170.                 throw new ArgumentException(Res.GetString(Res.XmlInternalError), "xmlMapping");
  2171.             if (xmlMapping is XmlTypeMapping)
  2172.                 return GenerateTypeElement((XmlTypeMapping)xmlMapping);
  2173.             else if (xmlMapping is XmlMembersMapping)
  2174.                 return GenerateMembersElement((XmlMembersMapping)xmlMapping);
  2175.             else
  2176.                 throw new ArgumentException(Res.GetString(Res.XmlInternalError), "xmlMapping");
  2177.         }
  2178.        
  2179.         void WriteIsStartTag(string name, string ns)
  2180.         {
  2181.             Writer.Write("if (Reader.IsStartElement(");
  2182.             WriteID(name);
  2183.             Writer.Write(", ");
  2184.             WriteID(ns);
  2185.             Writer.WriteLine(")) {");
  2186.             Writer.Indent++;
  2187.         }
  2188.        
  2189.         void WriteUnknownNode(string func, string node, ElementAccessor e, bool anyIfs)
  2190.         {
  2191.             if (anyIfs) {
  2192.                 Writer.WriteLine("else {");
  2193.                 Writer.Indent++;
  2194.             }
  2195.             Writer.Write(func);
  2196.             Writer.Write("(");
  2197.             Writer.Write(node);
  2198.             if (e != null) {
  2199.                 Writer.Write(", ");
  2200.                 string expectedElement = e.Form == XmlSchemaForm.Qualified ? e.Namespace : "";
  2201.                 expectedElement += ":";
  2202.                 expectedElement += e.Name;
  2203.                 ReflectionAwareCodeGen.WriteQuotedCSharpString(Writer, expectedElement);
  2204.             }
  2205.             Writer.WriteLine(");");
  2206.             if (anyIfs) {
  2207.                 Writer.Indent--;
  2208.                 Writer.WriteLine("}");
  2209.             }
  2210.         }
  2211.        
  2212.         void GenerateInitCallbacksMethod()
  2213.         {
  2214.             Writer.WriteLine();
  2215.             Writer.WriteLine("protected override void InitCallbacks() {");
  2216.             Writer.Indent++;
  2217.            
  2218.             string dummyArrayMethodName = NextMethodName("Array");
  2219.             bool needDummyArrayMethod = false;
  2220.             foreach (TypeScope scope in Scopes) {
  2221.                 foreach (TypeMapping mapping in scope.TypeMappings) {
  2222.                     if (mapping.IsSoap && (mapping is StructMapping || mapping is EnumMapping || mapping is ArrayMapping || mapping is NullableMapping) && !mapping.TypeDesc.IsRoot) {
  2223.                        
  2224.                         string methodName;
  2225.                         if (mapping is ArrayMapping) {
  2226.                             methodName = dummyArrayMethodName;
  2227.                             needDummyArrayMethod = true;
  2228.                         }
  2229.                         else
  2230.                             methodName = (string)MethodNames[mapping];
  2231.                        
  2232.                         Writer.Write("AddReadCallback(");
  2233.                         WriteID(mapping.TypeName);
  2234.                         Writer.Write(", ");
  2235.                         WriteID(mapping.Namespace);
  2236.                         Writer.Write(", ");
  2237.                         Writer.Write(RaCodeGen.GetStringForTypeof(mapping.TypeDesc.CSharpName, mapping.TypeDesc.UseReflection));
  2238.                         Writer.Write(", new ");
  2239.                         Writer.Write(typeof(XmlSerializationReadCallback).FullName);
  2240.                         Writer.Write("(this.");
  2241.                         Writer.Write(methodName);
  2242.                         Writer.WriteLine("));");
  2243.                     }
  2244.                 }
  2245.             }
  2246.            
  2247.             Writer.Indent--;
  2248.             Writer.WriteLine("}");
  2249.            
  2250.             if (needDummyArrayMethod) {
  2251.                 Writer.WriteLine();
  2252.                 Writer.Write("object ");
  2253.                 Writer.Write(dummyArrayMethodName);
  2254.                 Writer.WriteLine("() {");
  2255.                 Writer.Indent++;
  2256.                 Writer.WriteLine("// dummy array method");
  2257.                 Writer.WriteLine("UnknownNode(null);");
  2258.                 Writer.WriteLine("return null;");
  2259.                 Writer.Indent--;
  2260.                 Writer.WriteLine("}");
  2261.             }
  2262.         }
  2263.        
  2264.        
  2265.         string GenerateMembersElement(XmlMembersMapping xmlMembersMapping)
  2266.         {
  2267.             if (xmlMembersMapping.Accessor.IsSoap)
  2268.                 return GenerateEncodedMembersElement(xmlMembersMapping);
  2269.             else
  2270.                 return GenerateLiteralMembersElement(xmlMembersMapping);
  2271.         }
  2272.        
  2273.         string GetChoiceIdentifierSource(MemberMapping[] mappings, MemberMapping member)
  2274.         {
  2275.             string choiceSource = null;
  2276.             if (member.ChoiceIdentifier != null) {
  2277.                 for (int j = 0; j < mappings.Length; j++) {
  2278.                     if (mappings[j].Name == member.ChoiceIdentifier.MemberName) {
  2279.                         choiceSource = "p[" + j.ToString(CultureInfo.InvariantCulture) + "]";
  2280.                         break;
  2281.                     }
  2282.                 }
  2283.                 #if DEBUG
  2284.                 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  2285.                 if (choiceSource == null)
  2286.                     throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "Can not find " + member.ChoiceIdentifier.MemberName + " in the members mapping."));
  2287.                 #endif
  2288.                
  2289.             }
  2290.             return choiceSource;
  2291.         }
  2292.        
  2293.         string GetChoiceIdentifierSource(MemberMapping mapping, string parent, TypeDesc parentTypeDesc)
  2294.         {
  2295.             if (mapping.ChoiceIdentifier == null)
  2296.                 return "";
  2297.             CodeIdentifier.CheckValidIdentifier(mapping.ChoiceIdentifier.MemberName);
  2298.             return RaCodeGen.GetStringForMember(parent, mapping.ChoiceIdentifier.MemberName, parentTypeDesc);
  2299.         }
  2300.        
  2301.         string GenerateLiteralMembersElement(XmlMembersMapping xmlMembersMapping)
  2302.         {
  2303.             ElementAccessor element = xmlMembersMapping.Accessor;
  2304.             MemberMapping[] mappings = ((MembersMapping)element.Mapping).Members;
  2305.             bool hasWrapperElement = ((MembersMapping)element.Mapping).HasWrapperElement;
  2306.             string methodName = NextMethodName(element.Name);
  2307.             Writer.WriteLine();
  2308.             Writer.Write("public object[] ");
  2309.             Writer.Write(methodName);
  2310.             Writer.WriteLine("() {");
  2311.             Writer.Indent++;
  2312.             Writer.WriteLine("Reader.MoveToContent();");
  2313.            
  2314.             Writer.Write("object[] p = new object[");
  2315.             Writer.Write(mappings.Length.ToString(CultureInfo.InvariantCulture));
  2316.             Writer.WriteLine("];");
  2317.             InitializeValueTypes("p", mappings);
  2318.            
  2319.             int wrapperLoopIndex = 0;
  2320.             if (hasWrapperElement) {
  2321.                 wrapperLoopIndex = WriteWhileNotLoopStart();
  2322.                 Writer.Indent++;
  2323.                 WriteIsStartTag(element.Name, element.Form == XmlSchemaForm.Qualified ? element.Namespace : "");
  2324.             }
  2325.            
  2326.             Member anyText = null;
  2327.             Member anyElement = null;
  2328.             Member anyAttribute = null;
  2329.            
  2330.             ArrayList membersList = new ArrayList();
  2331.             ArrayList textOrArrayMembersList = new ArrayList();
  2332.             ArrayList attributeMembersList = new ArrayList();
  2333.            
  2334.             for (int i = 0; i < mappings.Length; i++) {
  2335.                 MemberMapping mapping = mappings[i];
  2336.                 string source = "p[" + i.ToString(CultureInfo.InvariantCulture) + "]";
  2337.                 string arraySource = source;
  2338.                 if (mapping.Xmlns != null) {
  2339.                     arraySource = "((" + mapping.TypeDesc.CSharpName + ")" + source + ")";
  2340.                 }
  2341.                 string choiceSource = GetChoiceIdentifierSource(mappings, mapping);
  2342.                 Member member = new Member(this, source, arraySource, "a", i, mapping, choiceSource);
  2343.                 Member anyMember = new Member(this, source, null, "a", i, mapping, choiceSource);
  2344.                 if (!mapping.IsSequence)
  2345.                     member.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]";
  2346.                 if (mapping.CheckSpecified) {
  2347.                     string nameSpecified = mapping.Name + "Specified";
  2348.                     for (int j = 0; j < mappings.Length; j++) {
  2349.                         if (mappings[j].Name == nameSpecified) {
  2350.                             member.CheckSpecifiedSource = "p[" + j.ToString(CultureInfo.InvariantCulture) + "]";
  2351.                             break;
  2352.                         }
  2353.                     }
  2354.                 }
  2355.                 bool foundAnyElement = false;
  2356.                 if (mapping.Text != null)
  2357.                     anyText = anyMember;
  2358.                 if (mapping.Attribute != null && mapping.Attribute.Any)
  2359.                     anyAttribute = anyMember;
  2360.                 if (mapping.Attribute != null || mapping.Xmlns != null)
  2361.                     attributeMembersList.Add(member);
  2362.                 else if (mapping.Text != null)
  2363.                     textOrArrayMembersList.Add(member);
  2364.                
  2365.                 if (!mapping.IsSequence) {
  2366.                     for (int j = 0; j < mapping.Elements.Length; j++) {
  2367.                         if (mapping.Elements[j].Any && mapping.Elements[j].Name.Length == 0) {
  2368.                             anyElement = anyMember;
  2369.                             if (mapping.Attribute == null && mapping.Text == null)
  2370.                                 textOrArrayMembersList.Add(anyMember);
  2371.                             foundAnyElement = true;
  2372.                             break;
  2373.                         }
  2374.                     }
  2375.                 }
  2376.                 if (mapping.Attribute != null || mapping.Text != null || foundAnyElement)
  2377.                     membersList.Add(anyMember);
  2378.                 else if (mapping.TypeDesc.IsArrayLike && !(mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping)) {
  2379.                     membersList.Add(anyMember);
  2380.                     textOrArrayMembersList.Add(anyMember);
  2381.                 }
  2382.                 else {
  2383.                     if (mapping.TypeDesc.IsArrayLike && !mapping.TypeDesc.IsArray)
  2384.                         member.ParamsReadSource = null;
  2385.                     // collection
  2386.                     membersList.Add(member);
  2387.                 }
  2388.             }
  2389.             Member[] members = (Member[])membersList.ToArray(typeof(Member));
  2390.             Member[] textOrArrayMembers = (Member[])textOrArrayMembersList.ToArray(typeof(Member));
  2391.            
  2392.             if (members.Length > 0 && members[0].Mapping.IsReturnValue)
  2393.                 Writer.WriteLine("IsReturnValue = true;");
  2394.            
  2395.             WriteParamsRead(mappings.Length);
  2396.            
  2397.             if (attributeMembersList.Count > 0) {
  2398.                 Member[] attributeMembers = (Member[])attributeMembersList.ToArray(typeof(Member));
  2399.                 WriteMemberBegin(attributeMembers);
  2400.                 WriteAttributes(attributeMembers, anyAttribute, "UnknownNode", "(object)p");
  2401.                 WriteMemberEnd(attributeMembers);
  2402.                 Writer.WriteLine("Reader.MoveToElement();");
  2403.             }
  2404.            
  2405.             WriteMemberBegin(textOrArrayMembers);
  2406.            
  2407.             if (hasWrapperElement) {
  2408.                 Writer.WriteLine("if (Reader.IsEmptyElement) { Reader.Skip(); Reader.MoveToContent(); continue; }");
  2409.                 Writer.WriteLine("Reader.ReadStartElement();");
  2410.             }
  2411.             if (IsSequence(members)) {
  2412.                 Writer.WriteLine("int state = 0;");
  2413.             }
  2414.             int loopIndex = WriteWhileNotLoopStart();
  2415.             Writer.Indent++;
  2416.            
  2417.             string unknownNode = "UnknownNode((object)p, " + ExpectedElements(members) + ");";
  2418.             WriteMemberElements(members, unknownNode, unknownNode, anyElement, anyText, null);
  2419.            
  2420.             Writer.WriteLine("Reader.MoveToContent();");
  2421.             WriteWhileLoopEnd(loopIndex);
  2422.            
  2423.             WriteMemberEnd(textOrArrayMembers);
  2424.            
  2425.             if (hasWrapperElement) {
  2426.                 Writer.WriteLine("ReadEndElement();");
  2427.                
  2428.                 Writer.Indent--;
  2429.                 Writer.WriteLine("}");
  2430.                
  2431.                 WriteUnknownNode("UnknownNode", "null", element, true);
  2432.                
  2433.                 Writer.WriteLine("Reader.MoveToContent();");
  2434.                 WriteWhileLoopEnd(wrapperLoopIndex);
  2435.             }
  2436.            
  2437.             Writer.WriteLine("return p;");
  2438.             Writer.Indent--;
  2439.             Writer.WriteLine("}");
  2440.            
  2441.             return methodName;
  2442.         }
  2443.        
  2444.         void InitializeValueTypes(string arrayName, MemberMapping[] mappings)
  2445.         {
  2446.             for (int i = 0; i < mappings.Length; i++) {
  2447.                 if (!mappings[i].TypeDesc.IsValueType)
  2448.                     continue;
  2449.                 Writer.Write(arrayName);
  2450.                 Writer.Write("[");
  2451.                 Writer.Write(i.ToString(CultureInfo.InvariantCulture));
  2452.                 Writer.Write("] = ");
  2453.                
  2454.                 if (mappings[i].TypeDesc.IsOptionalValue && mappings[i].TypeDesc.BaseTypeDesc.UseReflection) {
  2455.                     Writer.Write("null");
  2456.                 }
  2457.                 else {
  2458.                     Writer.Write(RaCodeGen.GetStringForCreateInstance(mappings[i].TypeDesc.CSharpName, mappings[i].TypeDesc.UseReflection, false, false));
  2459.                 }
  2460.                 Writer.WriteLine(";");
  2461.             }
  2462.         }
  2463.        
  2464.         string GenerateEncodedMembersElement(XmlMembersMapping xmlMembersMapping)
  2465.         {
  2466.             ElementAccessor element = xmlMembersMapping.Accessor;
  2467.             MembersMapping membersMapping = (MembersMapping)element.Mapping;
  2468.             MemberMapping[] mappings = membersMapping.Members;
  2469.             bool hasWrapperElement = membersMapping.HasWrapperElement;
  2470.             bool writeAccessors = membersMapping.WriteAccessors;
  2471.             string methodName = NextMethodName(element.Name);
  2472.             Writer.WriteLine();
  2473.             Writer.Write("public object[] ");
  2474.             Writer.Write(methodName);
  2475.             Writer.WriteLine("() {");
  2476.             Writer.Indent++;
  2477.            
  2478.             Writer.WriteLine("Reader.MoveToContent();");
  2479.            
  2480.             Writer.Write("object[] p = new object[");
  2481.             Writer.Write(mappings.Length.ToString(CultureInfo.InvariantCulture));
  2482.             Writer.WriteLine("];");
  2483.             InitializeValueTypes("p", mappings);
  2484.            
  2485.             if (hasWrapperElement) {
  2486.                 WriteReadNonRoots();
  2487.                
  2488.                 if (membersMapping.ValidateRpcWrapperElement) {
  2489.                     Writer.Write("if (!");
  2490.                     WriteXmlNodeEqual("Reader", element.Name, element.Form == XmlSchemaForm.Qualified ? element.Namespace : "");
  2491.                     Writer.WriteLine(") throw CreateUnknownNodeException();");
  2492.                 }
  2493.                 Writer.WriteLine("bool isEmptyWrapper = Reader.IsEmptyElement;");
  2494.                 Writer.WriteLine("Reader.ReadStartElement();");
  2495.             }
  2496.            
  2497.             Member[] members = new Member[mappings.Length];
  2498.             for (int i = 0; i < mappings.Length; i++) {
  2499.                 MemberMapping mapping = mappings[i];
  2500.                 string source = "p[" + i.ToString(CultureInfo.InvariantCulture) + "]";
  2501.                 string arraySource = source;
  2502.                 if (mapping.Xmlns != null) {
  2503.                     arraySource = "((" + mapping.TypeDesc.CSharpName + ")" + source + ")";
  2504.                 }
  2505.                 Member member = new Member(this, source, arraySource, "a", i, mapping);
  2506.                 if (!mapping.IsSequence)
  2507.                     member.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]";
  2508.                 members[i] = member;
  2509.                
  2510.                 if (mapping.CheckSpecified) {
  2511.                     string nameSpecified = mapping.Name + "Specified";
  2512.                     for (int j = 0; j < mappings.Length; j++) {
  2513.                         if (mappings[j].Name == nameSpecified) {
  2514.                             member.CheckSpecifiedSource = "p[" + j.ToString(CultureInfo.InvariantCulture) + "]";
  2515.                             break;
  2516.                         }
  2517.                     }
  2518.                 }
  2519.                
  2520.             }
  2521.            
  2522.             string fixupMethodName = "fixup_" + methodName;
  2523.             bool anyFixups = WriteMemberFixupBegin(members, fixupMethodName, "p");
  2524.            
  2525.             if (members.Length > 0 && members[0].Mapping.IsReturnValue)
  2526.                 Writer.WriteLine("IsReturnValue = true;");
  2527.            
  2528.             string checkTypeHrefSource = (!hasWrapperElement && !writeAccessors) ? "hrefList" : null;
  2529.             if (checkTypeHrefSource != null)
  2530.                 WriteInitCheckTypeHrefList(checkTypeHrefSource);
  2531.            
  2532.             WriteParamsRead(mappings.Length);
  2533.             int loopIndex = WriteWhileNotLoopStart();
  2534.             Writer.Indent++;
  2535.            
  2536.             string unrecognizedElementSource = checkTypeHrefSource == null ? "UnknownNode((object)p);" : "if (Reader.GetAttribute(\"id\", null) != null) { ReadReferencedElement(); } else { UnknownNode((object)p); }";
  2537.             WriteMemberElements(members, unrecognizedElementSource, "UnknownNode((object)p);", null, null, checkTypeHrefSource);
  2538.             Writer.WriteLine("Reader.MoveToContent();");
  2539.            
  2540.             WriteWhileLoopEnd(loopIndex);
  2541.            
  2542.             if (hasWrapperElement)
  2543.                 Writer.WriteLine("if (!isEmptyWrapper) ReadEndElement();");
  2544.            
  2545.             if (checkTypeHrefSource != null)
  2546.                 WriteHandleHrefList(members, checkTypeHrefSource);
  2547.            
  2548.             Writer.WriteLine("ReadReferencedElements();");
  2549.             Writer.WriteLine("return p;");
  2550.            
  2551.             Writer.Indent--;
  2552.             Writer.WriteLine("}");
  2553.            
  2554.             if (anyFixups)
  2555.                 WriteFixupMethod(fixupMethodName, members, "object[]", false, false, "p");
  2556.            
  2557.             return methodName;
  2558.         }
  2559.        
  2560.         void WriteCreateCollection(TypeDesc td, string source)
  2561.         {
  2562.             bool useReflection = td.UseReflection;
  2563.             string item = (td.ArrayElementTypeDesc == null ? "object" : td.ArrayElementTypeDesc.CSharpName) + "[]";
  2564.             bool arrayElementUseReflection = td.ArrayElementTypeDesc == null ? false : td.ArrayElementTypeDesc.UseReflection;
  2565.            
  2566.             //cannot call WriteArrayLocalDecl since 'ci' is always
  2567.             //array and 'td' corresponds to 'c'
  2568.             if (arrayElementUseReflection)
  2569.                 item = typeof(Array).FullName;
  2570.             Writer.Write(item);
  2571.             Writer.Write(" ");
  2572.             Writer.Write("ci =");
  2573.             Writer.Write("(" + item + ")");
  2574.             Writer.Write(source);
  2575.             Writer.WriteLine(";");
  2576.            
  2577.             Writer.WriteLine("for (int i = 0; i < ci.Length; i++) {");
  2578.             Writer.Indent++;
  2579.             Writer.Write(RaCodeGen.GetStringForMethod("c", td.CSharpName, "Add", useReflection));
  2580.            
  2581.             //cannot call GetStringForArrayMember since 'ci' is always
  2582.             //array and 'td' corresponds to 'c'
  2583.             if (!arrayElementUseReflection)
  2584.                 Writer.Write("ci[i]");
  2585.             else
  2586.                 Writer.Write(RaCodeGen.GetReflectionVariable(typeof(Array).FullName, "0") + "[ci , i]");
  2587.            
  2588.            
  2589.             if (useReflection)
  2590.                 Writer.WriteLine("}");
  2591.             Writer.WriteLine(");");
  2592.             Writer.Indent--;
  2593.             Writer.WriteLine("}");
  2594.         }
  2595.        
  2596.         string GenerateTypeElement(XmlTypeMapping xmlTypeMapping)
  2597.         {
  2598.             ElementAccessor element = xmlTypeMapping.Accessor;
  2599.             TypeMapping mapping = element.Mapping;
  2600.             string methodName = NextMethodName(element.Name);
  2601.             Writer.WriteLine();
  2602.             Writer.Write("public object ");
  2603.             Writer.Write(methodName);
  2604.             Writer.WriteLine("() {");
  2605.             Writer.Indent++;
  2606.             Writer.WriteLine("object o = null;");
  2607.             MemberMapping member = new MemberMapping();
  2608.             member.TypeDesc = mapping.TypeDesc;
  2609.             //member.ReadOnly = !mapping.TypeDesc.HasDefaultConstructor;
  2610.             member.Elements = new ElementAccessor[] {element};
  2611.             Member[] members = new Member[] {new Member(this, "o", "o", "a", 0, member)};
  2612.             Writer.WriteLine("Reader.MoveToContent();");
  2613.             string unknownNode = "UnknownNode(null, " + ExpectedElements(members) + ");";
  2614.             WriteMemberElements(members, "throw CreateUnknownNodeException();", unknownNode, element.Any ? members[0] : null, null, null);
  2615.             if (element.IsSoap) {
  2616.                 Writer.WriteLine("Referenced(o);");
  2617.                 Writer.WriteLine("ReadReferencedElements();");
  2618.             }
  2619.             Writer.WriteLine("return (object)o;");
  2620.             Writer.Indent--;
  2621.             Writer.WriteLine("}");
  2622.             return methodName;
  2623.         }
  2624.        
  2625.         string NextMethodName(string name)
  2626.         {
  2627.             return "Read" + (++NextMethodNumber).ToString(CultureInfo.InvariantCulture) + "_" + CodeIdentifier.MakeValidInternal(name);
  2628.         }
  2629.        
  2630.         string NextIdName(string name)
  2631.         {
  2632.             return "id" + (++nextIdNumber).ToString(CultureInfo.InvariantCulture) + "_" + CodeIdentifier.MakeValidInternal(name);
  2633.         }
  2634.        
  2635.         void WritePrimitive(TypeMapping mapping, string source)
  2636.         {
  2637.             if (mapping is EnumMapping) {
  2638.                 string enumMethodName = ReferenceMapping(mapping);
  2639.                 if (enumMethodName == null)
  2640.                     throw new InvalidOperationException(Res.GetString(Res.XmlMissingMethodEnum, mapping.TypeDesc.Name));
  2641.                 if (mapping.IsSoap) {
  2642.                     // SOAP methods are not strongly-typed (the return object), so we need to add a cast
  2643.                     Writer.Write("(");
  2644.                     Writer.Write(mapping.TypeDesc.CSharpName);
  2645.                     Writer.Write(")");
  2646.                 }
  2647.                 Writer.Write(enumMethodName);
  2648.                 Writer.Write("(");
  2649.                 if (!mapping.IsSoap)
  2650.                     Writer.Write(source);
  2651.                 Writer.Write(")");
  2652.             }
  2653.             else if (mapping.TypeDesc == StringTypeDesc) {
  2654.                 Writer.Write(source);
  2655.             }
  2656.             else if (mapping.TypeDesc.FormatterName == "String") {
  2657.                 if (mapping.TypeDesc.CollapseWhitespace) {
  2658.                     Writer.Write("CollapseWhitespace(");
  2659.                     Writer.Write(source);
  2660.                     Writer.Write(")");
  2661.                 }
  2662.                 else {
  2663.                     Writer.Write(source);
  2664.                 }
  2665.             }
  2666.             else {
  2667.                 if (!mapping.TypeDesc.HasCustomFormatter) {
  2668.                     Writer.Write(typeof(XmlConvert).FullName);
  2669.                     Writer.Write(".");
  2670.                 }
  2671.                 Writer.Write("To");
  2672.                 Writer.Write(mapping.TypeDesc.FormatterName);
  2673.                 Writer.Write("(");
  2674.                 Writer.Write(source);
  2675.                 Writer.Write(")");
  2676.             }
  2677.         }
  2678.        
  2679.         string MakeUnique(EnumMapping mapping, string name)
  2680.         {
  2681.             string uniqueName = name;
  2682.             object m = Enums[uniqueName];
  2683.             if (m != null) {
  2684.                 if (m == mapping) {
  2685.                     // we already have created the hashtable
  2686.                     return null;
  2687.                 }
  2688.                 int i = 0;
  2689.                 while (m != null) {
  2690.                     i++;
  2691.                     uniqueName = name + i.ToString(CultureInfo.InvariantCulture);
  2692.                     m = Enums[uniqueName];
  2693.                 }
  2694.             }
  2695.             Enums.Add(uniqueName, mapping);
  2696.             return uniqueName;
  2697.         }
  2698.        
  2699.         string WriteHashtable(EnumMapping mapping, string typeName)
  2700.         {
  2701.            
  2702.             CodeIdentifier.CheckValidIdentifier(typeName);
  2703.             string propName = MakeUnique(mapping, typeName + "Values");
  2704.             if (propName == null)
  2705.                 return CodeIdentifier.GetCSharpName(typeName);
  2706.             string memberName = MakeUnique(mapping, "_" + propName);
  2707.             propName = CodeIdentifier.GetCSharpName(propName);
  2708.            
  2709.             Writer.WriteLine();
  2710.             Writer.Write(typeof(Hashtable).FullName);
  2711.             Writer.Write(" ");
  2712.             Writer.Write(memberName);
  2713.             Writer.WriteLine(";");
  2714.             Writer.WriteLine();
  2715.            
  2716.             Writer.Write("internal ");
  2717.             Writer.Write(typeof(Hashtable).FullName);
  2718.             Writer.Write(" ");
  2719.             Writer.Write(propName);
  2720.             Writer.WriteLine(" {");
  2721.             Writer.Indent++;
  2722.            
  2723.             Writer.WriteLine("get {");
  2724.             Writer.Indent++;
  2725.            
  2726.             Writer.Write("if ((object)");
  2727.             Writer.Write(memberName);
  2728.             Writer.WriteLine(" == null) {");
  2729.             Writer.Indent++;
  2730.            
  2731.             Writer.Write(typeof(Hashtable).FullName);
  2732.             Writer.Write(" h = new ");
  2733.             Writer.Write(typeof(Hashtable).FullName);
  2734.             Writer.WriteLine("();");
  2735.            
  2736.             ConstantMapping[] constants = mapping.Constants;
  2737.            
  2738.             for (int i = 0; i < constants.Length; i++) {
  2739.                 Writer.Write("h.Add(");
  2740.                 WriteQuotedCSharpString(constants[i].XmlName);
  2741.                 if (!mapping.TypeDesc.UseReflection) {
  2742.                     Writer.Write(", (long)");
  2743.                     Writer.Write(mapping.TypeDesc.CSharpName);
  2744.                     Writer.Write(".@");
  2745.                     CodeIdentifier.CheckValidIdentifier(constants[i].Name);
  2746.                     Writer.Write(constants[i].Name);
  2747.                 }
  2748.                 else {
  2749.                     Writer.Write(", ");
  2750.                     Writer.Write(constants[i].Value.ToString(CultureInfo.InvariantCulture) + "L");
  2751.                 }
  2752.                
  2753.                 Writer.WriteLine(");");
  2754.             }
  2755.            
  2756.             Writer.Write(memberName);
  2757.             Writer.WriteLine(" = h;");
  2758.            
  2759.             Writer.Indent--;
  2760.             Writer.WriteLine("}");
  2761.            
  2762.             Writer.Write("return ");
  2763.             Writer.Write(memberName);
  2764.             Writer.WriteLine(";");
  2765.            
  2766.             Writer.Indent--;
  2767.             Writer.WriteLine("}");
  2768.            
  2769.             Writer.Indent--;
  2770.             Writer.WriteLine("}");
  2771.            
  2772.             return propName;
  2773.         }
  2774.        
  2775.         void WriteEnumMethod(EnumMapping mapping)
  2776.         {
  2777.             string tableName = null;
  2778.             if (mapping.IsFlags)
  2779.                 tableName = WriteHashtable(mapping, mapping.TypeDesc.Name);
  2780.            
  2781.             string methodName = (string)MethodNames[mapping];
  2782.             Writer.WriteLine();
  2783.             bool useReflection = mapping.TypeDesc.UseReflection;
  2784.             string fullTypeName = mapping.TypeDesc.CSharpName;
  2785.            
  2786.             if (mapping.IsSoap) {
  2787.                 Writer.Write("object");
  2788.                 Writer.Write(" ");
  2789.                 Writer.Write(methodName);
  2790.                 Writer.WriteLine("() {");
  2791.                 Writer.Indent++;
  2792.                 Writer.WriteLine("string s = Reader.ReadElementString();");
  2793.             }
  2794.             else {
  2795.                 Writer.Write(useReflection ? "object" : fullTypeName);
  2796.                 Writer.Write(" ");
  2797.                 Writer.Write(methodName);
  2798.                 Writer.WriteLine("(string s) {");
  2799.                 Writer.Indent++;
  2800.             }
  2801.            
  2802.             ConstantMapping[] constants = mapping.Constants;
  2803.             if (mapping.IsFlags) {
  2804.                 if (useReflection) {
  2805.                     Writer.Write("return ");
  2806.                     Writer.Write(typeof(Enum).FullName);
  2807.                     Writer.Write(".ToObject(");
  2808.                     Writer.Write(RaCodeGen.GetStringForTypeof(fullTypeName, useReflection));
  2809.                     Writer.Write(", ToEnum(s, ");
  2810.                     Writer.Write(tableName);
  2811.                     Writer.Write(", ");
  2812.                     WriteQuotedCSharpString(fullTypeName);
  2813.                     Writer.WriteLine("));");
  2814.                 }
  2815.                 else {
  2816.                     Writer.Write("return (");
  2817.                     Writer.Write(fullTypeName);
  2818.                     Writer.Write(")ToEnum(s, ");
  2819.                     Writer.Write(tableName);
  2820.                     Writer.Write(", ");
  2821.                     WriteQuotedCSharpString(fullTypeName);
  2822.                     Writer.WriteLine(");");
  2823.                 }
  2824.             }
  2825.             else {
  2826.                 Writer.WriteLine("switch (s) {");
  2827.                 Writer.Indent++;
  2828.                 Hashtable cases = new Hashtable();
  2829.                 for (int i = 0; i < constants.Length; i++) {
  2830.                     ConstantMapping c = constants[i];
  2831.                    
  2832.                     CodeIdentifier.CheckValidIdentifier(c.Name);
  2833.                     if (cases[c.XmlName] == null) {
  2834.                         Writer.Write("case ");
  2835.                         WriteQuotedCSharpString(c.XmlName);
  2836.                         Writer.Write(": return ");
  2837.                         Writer.Write(RaCodeGen.GetStringForEnumMember(fullTypeName, c.Name, useReflection));
  2838.                         Writer.WriteLine(";");
  2839.                         cases[c.XmlName] = c.XmlName;
  2840.                     }
  2841.                 }
  2842.                
  2843.                 Writer.Write("default: throw CreateUnknownConstantException(s, ");
  2844.                 Writer.Write(RaCodeGen.GetStringForTypeof(fullTypeName, useReflection));
  2845.                 Writer.WriteLine(");");
  2846.                 Writer.Indent--;
  2847.                 Writer.WriteLine("}");
  2848.             }
  2849.            
  2850.             Writer.Indent--;
  2851.             Writer.WriteLine("}");
  2852.         }
  2853.        
  2854.         void WriteDerivedTypes(StructMapping mapping, bool isTypedReturn, string returnTypeName)
  2855.         {
  2856.            
  2857.             for (StructMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping) {
  2858.                 Writer.Write("else if (");
  2859.                 WriteQNameEqual("xsiType", derived.TypeName, derived.Namespace);
  2860.                 Writer.WriteLine(")");
  2861.                 Writer.Indent++;
  2862.                
  2863.                 string methodName = ReferenceMapping(derived);
  2864.                 #if DEBUG
  2865.                 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  2866.                 if (methodName == null)
  2867.                     throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, derived.TypeDesc.Name));
  2868.                 #endif
  2869.                
  2870.                 Writer.Write("return ");
  2871.                 if (derived.TypeDesc.UseReflection && isTypedReturn)
  2872.                     Writer.Write("(" + returnTypeName + ")");
  2873.                 Writer.Write(methodName);
  2874.                 Writer.Write("(");
  2875.                 if (derived.TypeDesc.IsNullable)
  2876.                     Writer.Write("isNullable, ");
  2877.                 Writer.WriteLine("false);");
  2878.                
  2879.                 Writer.Indent--;
  2880.                
  2881.                 WriteDerivedTypes(derived, isTypedReturn, returnTypeName);
  2882.             }
  2883.         }
  2884.        
  2885.         void WriteEnumAndArrayTypes()
  2886.         {
  2887.             foreach (TypeScope scope in Scopes) {
  2888.                 foreach (Mapping m in scope.TypeMappings) {
  2889.                     if (m.IsSoap)
  2890.                         continue;
  2891.                     if (m is EnumMapping) {
  2892.                         EnumMapping mapping = (EnumMapping)m;
  2893.                         Writer.Write("else if (");
  2894.                         WriteQNameEqual("xsiType", mapping.TypeName, mapping.Namespace);
  2895.                         Writer.WriteLine(") {");
  2896.                         Writer.Indent++;
  2897.                         Writer.WriteLine("Reader.ReadStartElement();");
  2898.                         string methodName = ReferenceMapping(mapping);
  2899.                         #if DEBUG
  2900.                         // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  2901.                         if (methodName == null)
  2902.                             throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, mapping.TypeDesc.Name));
  2903.                         #endif
  2904.                         Writer.Write("object e = ");
  2905.                         Writer.Write(methodName);
  2906.                         Writer.WriteLine("(CollapseWhitespace(Reader.ReadString()));");
  2907.                         Writer.WriteLine("ReadEndElement();");
  2908.                         Writer.WriteLine("return e;");
  2909.                         Writer.Indent--;
  2910.                         Writer.WriteLine("}");
  2911.                     }
  2912.                     else if (m is ArrayMapping) {
  2913.                         ArrayMapping mapping = (ArrayMapping)m;
  2914.                         if (mapping.TypeDesc.HasDefaultConstructor) {
  2915.                             Writer.Write("else if (");
  2916.                             WriteQNameEqual("xsiType", mapping.TypeName, mapping.Namespace);
  2917.                             Writer.WriteLine(") {");
  2918.                             Writer.Indent++;
  2919.                             MemberMapping memberMapping = new MemberMapping();
  2920.                             memberMapping.TypeDesc = mapping.TypeDesc;
  2921.                             memberMapping.Elements = mapping.Elements;
  2922.                             Member member = new Member(this, "a", "z", 0, memberMapping);
  2923.                            
  2924.                             TypeDesc td = mapping.TypeDesc;
  2925.                             string fullTypeName = mapping.TypeDesc.CSharpName;
  2926.                             if (td.UseReflection) {
  2927.                                 if (td.IsArray)
  2928.                                     Writer.Write(typeof(Array).FullName);
  2929.                                 else
  2930.                                     Writer.Write("object");
  2931.                             }
  2932.                             else
  2933.                                 Writer.Write(fullTypeName);
  2934.                             Writer.Write(" a = ");
  2935.                             if (mapping.TypeDesc.IsValueType) {
  2936.                                 Writer.Write(RaCodeGen.GetStringForCreateInstance(fullTypeName, td.UseReflection, false, false));
  2937.                                 Writer.WriteLine(";");
  2938.                             }
  2939.                             else
  2940.                                 Writer.WriteLine("null;");
  2941.                            
  2942.                             WriteArray(member.Source, member.ArrayName, mapping, false, false, -1);
  2943.                             Writer.WriteLine("return a;");
  2944.                             Writer.Indent--;
  2945.                             Writer.WriteLine("}");
  2946.                         }
  2947.                     }
  2948.                 }
  2949.             }
  2950.         }
  2951.        
  2952.         void WriteNullableMethod(NullableMapping nullableMapping)
  2953.         {
  2954.             string methodName = (string)MethodNames[nullableMapping];
  2955.             bool useReflection = nullableMapping.BaseMapping.TypeDesc.UseReflection;
  2956.             string typeName = useReflection ? "object" : nullableMapping.TypeDesc.CSharpName;
  2957.             Writer.WriteLine();
  2958.            
  2959.             Writer.Write(typeName);
  2960.             Writer.Write(" ");
  2961.             Writer.Write(methodName);
  2962.             Writer.WriteLine("(bool checkType) {");
  2963.             Writer.Indent++;
  2964.            
  2965.             Writer.Write(typeName);
  2966.             Writer.Write(" o = ");
  2967.            
  2968.             if (useReflection) {
  2969.                 Writer.Write("null");
  2970.             }
  2971.             else {
  2972.                 Writer.Write("default(");
  2973.                 Writer.Write(typeName);
  2974.                 Writer.Write(")");
  2975.             }
  2976.             Writer.WriteLine(";");
  2977.            
  2978.             Writer.WriteLine("if (ReadNull())");
  2979.             Writer.Indent++;
  2980.            
  2981.             Writer.WriteLine("return o;");
  2982.             Writer.Indent--;
  2983.            
  2984.             ElementAccessor element = new ElementAccessor();
  2985.             element.Mapping = nullableMapping.BaseMapping;
  2986.             element.Any = false;
  2987.             element.IsNullable = nullableMapping.BaseMapping.TypeDesc.IsNullable;
  2988.            
  2989.             WriteElement("o", null, null, element, null, null, false, false, -1, -1
  2990.             );
  2991.             Writer.WriteLine("return o;");
  2992.            
  2993.             Writer.Indent--;
  2994.             Writer.WriteLine("}");
  2995.         }
  2996.        
  2997.         void WriteStructMethod(StructMapping structMapping)
  2998.         {
  2999.             if (structMapping.IsSoap)
  3000.                 WriteEncodedStructMethod(structMapping);
  3001.             else
  3002.                 WriteLiteralStructMethod(structMapping);
  3003.         }
  3004.        
  3005.         void WriteLiteralStructMethod(StructMapping structMapping)
  3006.         {
  3007.             string methodName = (string)MethodNames[structMapping];
  3008.             bool useReflection = structMapping.TypeDesc.UseReflection;
  3009.             string typeName = useReflection ? "object" : structMapping.TypeDesc.CSharpName;
  3010.             Writer.WriteLine();
  3011.             Writer.Write(typeName);
  3012.             Writer.Write(" ");
  3013.             Writer.Write(methodName);
  3014.             Writer.Write("(");
  3015.             if (structMapping.TypeDesc.IsNullable)
  3016.                 Writer.Write("bool isNullable, ");
  3017.             Writer.WriteLine("bool checkType) {");
  3018.             Writer.Indent++;
  3019.            
  3020.             Writer.Write(typeof(XmlQualifiedName).FullName);
  3021.             Writer.WriteLine(" xsiType = checkType ? GetXsiType() : null;");
  3022.             Writer.WriteLine("bool isNull = false;");
  3023.             if (structMapping.TypeDesc.IsNullable)
  3024.                 Writer.WriteLine("if (isNullable) isNull = ReadNull();");
  3025.            
  3026.             Writer.WriteLine("if (checkType) {");
  3027.             if (structMapping.TypeDesc.IsRoot) {
  3028.                 Writer.Indent++;
  3029.                 Writer.WriteLine("if (isNull) {");
  3030.                 Writer.Indent++;
  3031.                 Writer.WriteLine("if (xsiType != null) return (" + typeName + ")ReadTypedNull(xsiType);");
  3032.                 Writer.Write("else return ");
  3033.                 if (structMapping.TypeDesc.IsValueType) {
  3034.                     Writer.Write(RaCodeGen.GetStringForCreateInstance(structMapping.TypeDesc.CSharpName, useReflection, false, false));
  3035.                     Writer.WriteLine(";");
  3036.                 }
  3037.                 else
  3038.                     Writer.WriteLine("null;");
  3039.                
  3040.                 Writer.Indent--;
  3041.                 Writer.WriteLine("}");
  3042.             }
  3043.             Writer.Write("if (xsiType == null");
  3044.             if (!structMapping.TypeDesc.IsRoot) {
  3045.                 Writer.Write(" || ");
  3046.                 WriteQNameEqual("xsiType", structMapping.TypeName, structMapping.Namespace);
  3047.             }
  3048.             Writer.WriteLine(") {");
  3049.             if (structMapping.TypeDesc.IsRoot) {
  3050.                 Writer.Indent++;
  3051.                 Writer.WriteLine("return ReadTypedPrimitive(new System.Xml.XmlQualifiedName(\"" + Soap.UrType + "\", \"" + XmlSchema.Namespace + "\"));");
  3052.                 Writer.Indent--;
  3053.             }
  3054.             Writer.WriteLine("}");
  3055.             WriteDerivedTypes(structMapping, !useReflection && !structMapping.TypeDesc.IsRoot, typeName);
  3056.             if (structMapping.TypeDesc.IsRoot)
  3057.                 WriteEnumAndArrayTypes();
  3058.             Writer.WriteLine("else");
  3059.             Writer.Indent++;
  3060.             if (structMapping.TypeDesc.IsRoot)
  3061.                 Writer.Write("return ReadTypedPrimitive((");
  3062.             else
  3063.                 Writer.Write("throw CreateUnknownTypeException((");
  3064.             Writer.Write(typeof(XmlQualifiedName).FullName);
  3065.             Writer.WriteLine(")xsiType);");
  3066.             Writer.Indent--;
  3067.             Writer.WriteLine("}");
  3068.            
  3069.             if (structMapping.TypeDesc.IsNullable)
  3070.                 Writer.WriteLine("if (isNull) return null;");
  3071.            
  3072.             if (structMapping.TypeDesc.IsAbstract) {
  3073.                 Writer.Write("throw CreateAbstractTypeException(");
  3074.                 WriteQuotedCSharpString(structMapping.TypeName);
  3075.                 Writer.Write(", ");
  3076.                 WriteQuotedCSharpString(structMapping.Namespace);
  3077.                 Writer.WriteLine(");");
  3078.             }
  3079.             else {
  3080.                 if (structMapping.TypeDesc.Type != null && typeof(XmlSchemaObject).IsAssignableFrom(structMapping.TypeDesc.Type)) {
  3081.                     Writer.WriteLine("DecodeName = false;");
  3082.                 }
  3083.                 WriteCreateMapping(structMapping, "o");
  3084.                
  3085.                 MemberMapping[] mappings = TypeScope.GetAllMembers(structMapping);
  3086.                
  3087.                 Member anyText = null;
  3088.                 Member anyElement = null;
  3089.                 Member anyAttribute = null;
  3090.                 bool isSequence = structMapping.HasExplicitSequence();
  3091.                
  3092.                 ArrayList arraysToDeclareList = new ArrayList(mappings.Length);
  3093.                 ArrayList arraysToSetList = new ArrayList(mappings.Length);
  3094.                 ArrayList allMembersList = new ArrayList(mappings.Length);
  3095.                
  3096.                 for (int i = 0; i < mappings.Length; i++) {
  3097.                     MemberMapping mapping = mappings[i];
  3098.                     CodeIdentifier.CheckValidIdentifier(mapping.Name);
  3099.                     string source = RaCodeGen.GetStringForMember("o", mapping.Name, structMapping.TypeDesc);
  3100.                     Member member = new Member(this, source, "a", i, mapping, GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc));
  3101.                     if (!mapping.IsSequence)
  3102.                         member.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]";
  3103.                     member.IsNullable = mapping.TypeDesc.IsNullable;
  3104.                     if (mapping.CheckSpecified)
  3105.                         member.CheckSpecifiedSource = RaCodeGen.GetStringForMember("o", mapping.Name + "Specified", structMapping.TypeDesc);
  3106.                     if (mapping.Text != null)
  3107.                         anyText = member;
  3108.                     if (mapping.Attribute != null && mapping.Attribute.Any)
  3109.                         anyAttribute = member;
  3110.                     if (!isSequence) {
  3111.                         // find anyElement if present.
  3112.                         for (int j = 0; j < mapping.Elements.Length; j++) {
  3113.                             if (mapping.Elements[j].Any && (mapping.Elements[j].Name == null || mapping.Elements[j].Name.Length == 0)) {
  3114.                                 anyElement = member;
  3115.                                 break;
  3116.                             }
  3117.                         }
  3118.                     }
  3119.                     else if (mapping.IsParticle && !mapping.IsSequence) {
  3120.                         StructMapping declaringMapping;
  3121.                         structMapping.FindDeclaringMapping(mapping, out declaringMapping, structMapping.TypeName);
  3122.                         throw new InvalidOperationException(Res.GetString(Res.XmlSequenceHierarchy, structMapping.TypeDesc.FullName, mapping.Name, declaringMapping.TypeDesc.FullName, "Order"));
  3123.                     }
  3124.                     if (mapping.Attribute == null && mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping) {
  3125.                         Member arrayMember = new Member(this, source, source, "a", i, mapping, GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc));
  3126.                         arrayMember.CheckSpecifiedSource = member.CheckSpecifiedSource;
  3127.                         allMembersList.Add(arrayMember);
  3128.                     }
  3129.                     else {
  3130.                         allMembersList.Add(member);
  3131.                     }
  3132.                    
  3133.                     if (mapping.TypeDesc.IsArrayLike) {
  3134.                         arraysToDeclareList.Add(member);
  3135.                         if (mapping.TypeDesc.IsArrayLike && !(mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping)) {
  3136.                             member.ParamsReadSource = null;
  3137.                             // flat arrays -- don't want to count params read.
  3138.                             if (member != anyText && member != anyElement) {
  3139.                                 arraysToSetList.Add(member);
  3140.                             }
  3141.                         }
  3142.                         else if (!mapping.TypeDesc.IsArray) {
  3143.                             member.ParamsReadSource = null;
  3144.                             // collection
  3145.                         }
  3146.                     }
  3147.                 }
  3148.                 if (anyElement != null)
  3149.                     arraysToSetList.Add(anyElement);
  3150.                 if (anyText != null && anyText != anyElement)
  3151.                     arraysToSetList.Add(anyText);
  3152.                
  3153.                 Member[] arraysToDeclare = (Member[])arraysToDeclareList.ToArray(typeof(Member));
  3154.                 Member[] arraysToSet = (Member[])arraysToSetList.ToArray(typeof(Member));
  3155.                 Member[] allMembers = (Member[])allMembersList.ToArray(typeof(Member));
  3156.                
  3157.                 WriteMemberBegin(arraysToDeclare);
  3158.                 WriteParamsRead(mappings.Length);
  3159.                
  3160.                 WriteAttributes(allMembers, anyAttribute, "UnknownNode", "(object)o");
  3161.                 if (anyAttribute != null)
  3162.                     WriteMemberEnd(arraysToDeclare);
  3163.                
  3164.                 Writer.WriteLine("Reader.MoveToElement();");
  3165.                
  3166.                 Writer.WriteLine("if (Reader.IsEmptyElement) {");
  3167.                 Writer.Indent++;
  3168.                 Writer.WriteLine("Reader.Skip();");
  3169.                 WriteMemberEnd(arraysToSet);
  3170.                 Writer.WriteLine("return o;");
  3171.                 Writer.Indent--;
  3172.                 Writer.WriteLine("}");
  3173.                
  3174.                 Writer.WriteLine("Reader.ReadStartElement();");
  3175.                 if (IsSequence(allMembers)) {
  3176.                     Writer.WriteLine("int state = 0;");
  3177.                 }
  3178.                 int loopIndex = WriteWhileNotLoopStart();
  3179.                 Writer.Indent++;
  3180.                 string unknownNode = "UnknownNode((object)o, " + ExpectedElements(allMembers) + ");";
  3181.                 WriteMemberElements(allMembers, unknownNode, unknownNode, anyElement, anyText, null);
  3182.                 Writer.WriteLine("Reader.MoveToContent();");
  3183.                
  3184.                 WriteWhileLoopEnd(loopIndex);
  3185.                 WriteMemberEnd(arraysToSet);
  3186.                
  3187.                 Writer.WriteLine("ReadEndElement();");
  3188.                 Writer.WriteLine("return o;");
  3189.             }
  3190.             Writer.Indent--;
  3191.             Writer.WriteLine("}");
  3192.         }
  3193.        
  3194.         void WriteEncodedStructMethod(StructMapping structMapping)
  3195.         {
  3196.             if (structMapping.TypeDesc.IsRoot)
  3197.                 return;
  3198.             bool useReflection = structMapping.TypeDesc.UseReflection;
  3199.             string methodName = (string)MethodNames[structMapping];
  3200.             Writer.WriteLine();
  3201.             Writer.Write("object");
  3202.             Writer.Write(" ");
  3203.             Writer.Write(methodName);
  3204.             Writer.Write("(");
  3205.             Writer.WriteLine(") {");
  3206.             Writer.Indent++;
  3207.            
  3208.             Member[] members;
  3209.             bool anyFixups;
  3210.             string fixupMethodName;
  3211.            
  3212.             if (structMapping.TypeDesc.IsAbstract) {
  3213.                 Writer.Write("throw CreateAbstractTypeException(");
  3214.                 WriteQuotedCSharpString(structMapping.TypeName);
  3215.                 Writer.Write(", ");
  3216.                 WriteQuotedCSharpString(structMapping.Namespace);
  3217.                 Writer.WriteLine(");");
  3218.                 members = new Member[0];
  3219.                 anyFixups = false;
  3220.                 fixupMethodName = null;
  3221.             }
  3222.             else {
  3223.                 WriteCreateMapping(structMapping, "o");
  3224.                
  3225.                 MemberMapping[] mappings = TypeScope.GetAllMembers(structMapping);
  3226.                 members = new Member[mappings.Length];
  3227.                 for (int i = 0; i < mappings.Length; i++) {
  3228.                     MemberMapping mapping = mappings[i];
  3229.                     CodeIdentifier.CheckValidIdentifier(mapping.Name);
  3230.                     string source = RaCodeGen.GetStringForMember("o", mapping.Name, structMapping.TypeDesc);
  3231.                     Member member = new Member(this, source, source, "a", i, mapping, GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc));
  3232.                     if (mapping.CheckSpecified)
  3233.                         member.CheckSpecifiedSource = RaCodeGen.GetStringForMember("o", mapping.Name + "Specified", structMapping.TypeDesc);
  3234.                     if (!mapping.IsSequence)
  3235.                         member.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]";
  3236.                     members[i] = member;
  3237.                 }
  3238.                
  3239.                 fixupMethodName = "fixup_" + methodName;
  3240.                 anyFixups = WriteMemberFixupBegin(members, fixupMethodName, "o");
  3241.                
  3242.                 // we're able to not do WriteMemberBegin here because we don't allow arrays as attributes
  3243.                
  3244.                 WriteParamsRead(mappings.Length);
  3245.                 WriteAttributes(members, null, "UnknownNode", "(object)o");
  3246.                 Writer.WriteLine("Reader.MoveToElement();");
  3247.                
  3248.                 Writer.WriteLine("if (Reader.IsEmptyElement) { Reader.Skip(); return o; }");
  3249.                 Writer.WriteLine("Reader.ReadStartElement();");
  3250.                
  3251.                 int loopIndex = WriteWhileNotLoopStart();
  3252.                 Writer.Indent++;
  3253.                
  3254.                 WriteMemberElements(members, "UnknownNode((object)o);", "UnknownNode((object)o);", null, null, null);
  3255.                 Writer.WriteLine("Reader.MoveToContent();");
  3256.                
  3257.                 WriteWhileLoopEnd(loopIndex);
  3258.                
  3259.                 Writer.WriteLine("ReadEndElement();");
  3260.                 Writer.WriteLine("return o;");
  3261.             }
  3262.             Writer.Indent--;
  3263.             Writer.WriteLine("}");
  3264.            
  3265.             if (anyFixups)
  3266.                 WriteFixupMethod(fixupMethodName, members, structMapping.TypeDesc.CSharpName, structMapping.TypeDesc.UseReflection, true, "o");
  3267.         }
  3268.        
  3269.         void WriteFixupMethod(string fixupMethodName, Member[] members, string typeName, bool useReflection, bool typed, string source)
  3270.         {
  3271.             Writer.WriteLine();
  3272.             Writer.Write("void ");
  3273.             Writer.Write(fixupMethodName);
  3274.             Writer.WriteLine("(object objFixup) {");
  3275.             Writer.Indent++;
  3276.             Writer.WriteLine("Fixup fixup = (Fixup)objFixup;");
  3277.             WriteLocalDecl(typeName, source, "fixup.Source", useReflection);
  3278.             Writer.WriteLine("string[] ids = fixup.Ids;");
  3279.            
  3280.             for (int i = 0; i < members.Length; i++) {
  3281.                 Member member = members[i];
  3282.                 if (member.MultiRef) {
  3283.                     string fixupIndex = member.FixupIndex.ToString(CultureInfo.InvariantCulture);
  3284.                     Writer.Write("if (ids[");
  3285.                     Writer.Write(fixupIndex);
  3286.                     Writer.WriteLine("] != null) {");
  3287.                     Writer.Indent++;
  3288.                    
  3289.                         /*member.IsList ? source + ".Add(" :*/                    string memberSource = member.ArraySource;
  3290.                    
  3291.                     string targetSource = "GetTarget(ids[" + fixupIndex + "])";
  3292.                     TypeDesc td = member.Mapping.TypeDesc;
  3293.                     if (td.IsCollection || td.IsEnumerable) {
  3294.                         WriteAddCollectionFixup(td, member.Mapping.ReadOnly, memberSource, targetSource);
  3295.                     }
  3296.                     else {
  3297.                         if (typed) {
  3298.                             Writer.WriteLine("try {");
  3299.                             Writer.Indent++;
  3300.                             WriteSourceBeginTyped(memberSource, member.Mapping.TypeDesc);
  3301.                         }
  3302.                         else
  3303.                             WriteSourceBegin(memberSource);
  3304.                        
  3305.                         Writer.Write(targetSource);
  3306.                         WriteSourceEnd(memberSource);
  3307.                         Writer.WriteLine(";");
  3308.                        
  3309.                         if (member.Mapping.CheckSpecified && member.CheckSpecifiedSource != null && member.CheckSpecifiedSource.Length > 0) {
  3310.                             Writer.Write(member.CheckSpecifiedSource);
  3311.                             Writer.WriteLine(" = true;");
  3312.                         }
  3313.                        
  3314.                         if (typed) {
  3315.                             WriteCatchCastException(member.Mapping.TypeDesc, targetSource, "ids[" + fixupIndex + "]");
  3316.                         }
  3317.                     }
  3318.                     Writer.Indent--;
  3319.                     Writer.WriteLine("}");
  3320.                 }
  3321.             }
  3322.             Writer.Indent--;
  3323.             Writer.WriteLine("}");
  3324.         }
  3325.        
  3326.         void WriteAddCollectionFixup(TypeDesc typeDesc, bool readOnly, string memberSource, string targetSource)
  3327.         {
  3328.             Writer.WriteLine("// get array of the collection items");
  3329.             bool useReflection = typeDesc.UseReflection;
  3330.             CreateCollectionInfo create = (CreateCollectionInfo)createMethods[typeDesc];
  3331.             if (create == null) {
  3332.                 string createName = "create" + (++nextCreateMethodNumber).ToString(CultureInfo.InvariantCulture) + "_" + typeDesc.Name;
  3333.                 create = new CreateCollectionInfo(createName, typeDesc);
  3334.                 createMethods.Add(typeDesc, create);
  3335.             }
  3336.            
  3337.             Writer.Write("if ((object)(");
  3338.             Writer.Write(memberSource);
  3339.             Writer.WriteLine(") == null) {");
  3340.             Writer.Indent++;
  3341.            
  3342.             if (readOnly) {
  3343.                 Writer.Write("throw CreateReadOnlyCollectionException(");
  3344.                 WriteQuotedCSharpString(typeDesc.CSharpName);
  3345.                 Writer.WriteLine(");");
  3346.             }
  3347.             else {
  3348.                 Writer.Write(memberSource);
  3349.                 Writer.Write(" = ");
  3350.                 Writer.Write(RaCodeGen.GetStringForCreateInstance(typeDesc.CSharpName, typeDesc.UseReflection, typeDesc.CannotNew, true));
  3351.                 Writer.WriteLine(";");
  3352.             }
  3353.            
  3354.             Writer.Indent--;
  3355.             Writer.WriteLine("}");
  3356.            
  3357.             Writer.Write("CollectionFixup collectionFixup = new CollectionFixup(");
  3358.             Writer.Write(memberSource);
  3359.             Writer.Write(", ");
  3360.             Writer.Write("new ");
  3361.             Writer.Write(typeof(XmlSerializationCollectionFixupCallback).FullName);
  3362.             Writer.Write("(this.");
  3363.             Writer.Write(create.Name);
  3364.             Writer.Write("), ");
  3365.             Writer.Write(targetSource);
  3366.             Writer.WriteLine(");");
  3367.             Writer.WriteLine("AddFixup(collectionFixup);");
  3368.         }
  3369.        
  3370.         void WriteCreateCollectionMethod(CreateCollectionInfo c)
  3371.         {
  3372.             Writer.Write("void ");
  3373.             Writer.Write(c.Name);
  3374.             Writer.WriteLine("(object collection, object collectionItems) {");
  3375.             Writer.Indent++;
  3376.            
  3377.             Writer.WriteLine("if (collectionItems == null) return;");
  3378.             Writer.WriteLine("if (collection == null) return;");
  3379.            
  3380.             TypeDesc td = c.TypeDesc;
  3381.             bool useReflection = td.UseReflection;
  3382.             string fullTypeName = td.CSharpName;
  3383.             WriteLocalDecl(fullTypeName, "c", "collection", useReflection);
  3384.            
  3385.             WriteCreateCollection(td, "collectionItems");
  3386.            
  3387.             Writer.Indent--;
  3388.             Writer.WriteLine("}");
  3389.         }
  3390.        
  3391.         void WriteQNameEqual(string source, string name, string ns)
  3392.         {
  3393.             Writer.Write("((object) ((");
  3394.             Writer.Write(typeof(XmlQualifiedName).FullName);
  3395.             Writer.Write(")");
  3396.             Writer.Write(source);
  3397.             Writer.Write(").Name == (object)");
  3398.             WriteID(name);
  3399.             Writer.Write(" && (object) ((");
  3400.             Writer.Write(typeof(XmlQualifiedName).FullName);
  3401.             Writer.Write(")");
  3402.             Writer.Write(source);
  3403.             Writer.Write(").Namespace == (object)");
  3404.             WriteID(ns);
  3405.             Writer.Write(")");
  3406.         }
  3407.        
  3408.         void WriteXmlNodeEqual(string source, string name, string ns)
  3409.         {
  3410.             Writer.Write("(");
  3411.             if (name != null && name.Length > 0) {
  3412.                 Writer.Write("(object) ");
  3413.                 Writer.Write(source);
  3414.                 Writer.Write(".LocalName == (object)");
  3415.                 WriteID(name);
  3416.                 Writer.Write(" && ");
  3417.             }
  3418.             Writer.Write("(object) ");
  3419.             Writer.Write(source);
  3420.             Writer.Write(".NamespaceURI == (object)");
  3421.             WriteID(ns);
  3422.             Writer.Write(")");
  3423.         }
  3424.        
  3425.         void WriteID(string name)
  3426.         {
  3427.             if (name == null) {
  3428.                 //Writer.Write("null");
  3429.                 //return;
  3430.                 name = "";
  3431.             }
  3432.             string idName = (string)idNames[name];
  3433.             if (idName == null) {
  3434.                 idName = NextIdName(name);
  3435.                 idNames.Add(name, idName);
  3436.             }
  3437.             Writer.Write(idName);
  3438.         }
  3439.        
  3440.         void WriteAttributes(Member[] members, Member anyAttribute, string elseCall, string firstParam)
  3441.         {
  3442.             int count = 0;
  3443.             Member xmlnsMember = null;
  3444.             ArrayList attributes = new ArrayList();
  3445.            
  3446.             Writer.WriteLine("while (Reader.MoveToNextAttribute()) {");
  3447.             Writer.Indent++;
  3448.            
  3449.             for (int i = 0; i < members.Length; i++) {
  3450.                 Member member = (Member)members[i];
  3451.                 if (member.Mapping.Xmlns != null) {
  3452.                     xmlnsMember = member;
  3453.                     continue;
  3454.                 }
  3455.                 if (member.Mapping.Ignore)
  3456.                     continue;
  3457.                 AttributeAccessor attribute = member.Mapping.Attribute;
  3458.                
  3459.                 if (attribute == null)
  3460.                     continue;
  3461.                 if (attribute.Any)
  3462.                     continue;
  3463.                
  3464.                 attributes.Add(attribute);
  3465.                
  3466.                 if (count++ > 0)
  3467.                     Writer.Write("else ");
  3468.                
  3469.                 Writer.Write("if (");
  3470.                 if (member.ParamsReadSource != null) {
  3471.                     Writer.Write("!");
  3472.                     Writer.Write(member.ParamsReadSource);
  3473.                     Writer.Write(" && ");
  3474.                 }
  3475.                
  3476.                 if (attribute.IsSpecialXmlNamespace) {
  3477.                     WriteXmlNodeEqual("Reader", attribute.Name, XmlReservedNs.NsXml);
  3478.                 }
  3479.                 else
  3480.                     WriteXmlNodeEqual("Reader", attribute.Name, attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : "");
  3481.                 Writer.WriteLine(") {");
  3482.                 Writer.Indent++;
  3483.                
  3484.                 WriteAttribute(member);
  3485.                 Writer.Indent--;
  3486.                 Writer.WriteLine("}");
  3487.             }
  3488.            
  3489.             if (count > 0)
  3490.                 Writer.Write("else ");
  3491.            
  3492.             if (xmlnsMember != null) {
  3493.                 Writer.WriteLine("if (IsXmlnsAttribute(Reader.Name)) {");
  3494.                 Writer.Indent++;
  3495.                
  3496.                 Writer.Write("if (");
  3497.                 Writer.Write(xmlnsMember.Source);
  3498.                 Writer.Write(" == null) ");
  3499.                 Writer.Write(xmlnsMember.Source);
  3500.                 Writer.Write(" = new ");
  3501.                 Writer.Write(xmlnsMember.Mapping.TypeDesc.CSharpName);
  3502.                 Writer.WriteLine("();");
  3503.                
  3504.                 //Writer.Write(xmlnsMember.ArraySource);
  3505.                 Writer.Write("((" + xmlnsMember.Mapping.TypeDesc.CSharpName + ")" + xmlnsMember.ArraySource + ")");
  3506.                 Writer.WriteLine(".Add(Reader.Name.Length == 5 ? \"\" : Reader.LocalName, Reader.Value);");
  3507.                
  3508.                 Writer.Indent--;
  3509.                 Writer.WriteLine("}");
  3510.                
  3511.                 Writer.WriteLine("else {");
  3512.                 Writer.Indent++;
  3513.             }
  3514.             else {
  3515.                 Writer.WriteLine("if (!IsXmlnsAttribute(Reader.Name)) {");
  3516.                 Writer.Indent++;
  3517.             }
  3518.             if (anyAttribute != null) {
  3519.                 Writer.Write(typeof(XmlAttribute).FullName);
  3520.                 Writer.Write(" attr = ");
  3521.                 Writer.Write("(");
  3522.                 Writer.Write(typeof(XmlAttribute).FullName);
  3523.                 Writer.WriteLine(") Document.ReadNode(Reader);");
  3524.                 Writer.WriteLine("ParseWsdlArrayType(attr);");
  3525.                 WriteAttribute(anyAttribute);
  3526.             }
  3527.             else {
  3528.                 Writer.Write(elseCall);
  3529.                 Writer.Write("(");
  3530.                 Writer.Write(firstParam);
  3531.                 if (attributes.Count > 0) {
  3532.                     Writer.Write(", ");
  3533.                     string qnames = "";
  3534.                    
  3535.                     for (int i = 0; i < attributes.Count; i++) {
  3536.                         AttributeAccessor attribute = (AttributeAccessor)attributes[i];
  3537.                         if (i > 0)
  3538.                             qnames += ", ";
  3539.                         qnames += attribute.IsSpecialXmlNamespace ? XmlReservedNs.NsXml : (attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : "") + ":" + attribute.Name;
  3540.                     }
  3541.                     WriteQuotedCSharpString(qnames);
  3542.                 }
  3543.                 Writer.WriteLine(");");
  3544.             }
  3545.             Writer.Indent--;
  3546.             Writer.WriteLine("}");
  3547.            
  3548.             Writer.Indent--;
  3549.             Writer.WriteLine("}");
  3550.         }
  3551.        
  3552.         void WriteAttribute(Member member)
  3553.         {
  3554.            
  3555.             AttributeAccessor attribute = member.Mapping.Attribute;
  3556.            
  3557.             if (attribute.Mapping is SpecialMapping) {
  3558.                 SpecialMapping special = (SpecialMapping)attribute.Mapping;
  3559.                
  3560.                 if (special.TypeDesc.Kind == TypeKind.Attribute) {
  3561.                     WriteSourceBegin(member.ArraySource);
  3562.                     Writer.Write("attr");
  3563.                     WriteSourceEnd(member.ArraySource);
  3564.                     Writer.WriteLine(";");
  3565.                 }
  3566.                 else if (special.TypeDesc.CanBeAttributeValue) {
  3567.                     Writer.Write("if (attr is ");
  3568.                     Writer.Write(typeof(XmlAttribute).FullName);
  3569.                     Writer.WriteLine(") {");
  3570.                     Writer.Indent++;
  3571.                     WriteSourceBegin(member.ArraySource);
  3572.                     Writer.Write("(");
  3573.                     Writer.Write(typeof(XmlAttribute).FullName);
  3574.                     Writer.Write(")attr");
  3575.                     WriteSourceEnd(member.ArraySource);
  3576.                     Writer.WriteLine(";");
  3577.                     Writer.Indent--;
  3578.                     Writer.WriteLine("}");
  3579.                 }
  3580.                 else
  3581.                     throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
  3582.             }
  3583.             else {
  3584.                 if (attribute.IsList) {
  3585.                     Writer.WriteLine("string listValues = Reader.Value;");
  3586.                     Writer.WriteLine("string[] vals = listValues.Split(null);");
  3587.                     Writer.WriteLine("for (int i = 0; i < vals.Length; i++) {");
  3588.                     Writer.Indent++;
  3589.                    
  3590.                     string attributeSource = GetArraySource(member.Mapping.TypeDesc, member.ArrayName);
  3591.                    
  3592.                     WriteSourceBegin(attributeSource);
  3593.                     WritePrimitive(attribute.Mapping, "vals[i]");
  3594.                     WriteSourceEnd(attributeSource);
  3595.                     Writer.WriteLine(";");
  3596.                     Writer.Indent--;
  3597.                     Writer.WriteLine("}");
  3598.                 }
  3599.                 else {
  3600.                     WriteSourceBegin(member.ArraySource);
  3601.                     WritePrimitive(attribute.Mapping, attribute.IsList ? "vals[i]" : "Reader.Value");
  3602.                     WriteSourceEnd(member.ArraySource);
  3603.                     Writer.WriteLine(";");
  3604.                 }
  3605.             }
  3606.             if (member.Mapping.CheckSpecified && member.CheckSpecifiedSource != null && member.CheckSpecifiedSource.Length > 0) {
  3607.                 Writer.Write(member.CheckSpecifiedSource);
  3608.                 Writer.WriteLine(" = true;");
  3609.             }
  3610.             if (member.ParamsReadSource != null) {
  3611.                 Writer.Write(member.ParamsReadSource);
  3612.                 Writer.WriteLine(" = true;");
  3613.             }
  3614.         }
  3615.        
  3616.         bool WriteMemberFixupBegin(Member[] members, string fixupMethodName, string source)
  3617.         {
  3618.             int fixupCount = 0;
  3619.             for (int i = 0; i < members.Length; i++) {
  3620.                 Member member = (Member)members[i];
  3621.                 if (member.Mapping.Elements.Length == 0)
  3622.                     continue;
  3623.                
  3624.                 TypeMapping mapping = member.Mapping.Elements[0].Mapping;
  3625.                 if (mapping is StructMapping || mapping is ArrayMapping || mapping is PrimitiveMapping || mapping is NullableMapping) {
  3626.                     member.MultiRef = true;
  3627.                     member.FixupIndex = fixupCount++;
  3628.                 }
  3629.             }
  3630.            
  3631.             if (fixupCount > 0) {
  3632.                 Writer.Write("Fixup fixup = new Fixup(");
  3633.                 Writer.Write(source);
  3634.                 Writer.Write(", ");
  3635.                 Writer.Write("new ");
  3636.                 Writer.Write(typeof(XmlSerializationFixupCallback).FullName);
  3637.                 Writer.Write("(this.");
  3638.                 Writer.Write(fixupMethodName);
  3639.                 Writer.Write("), ");
  3640.                 Writer.Write(fixupCount.ToString(CultureInfo.InvariantCulture));
  3641.                 Writer.WriteLine(");");
  3642.                 Writer.WriteLine("AddFixup(fixup);");
  3643.                 return true;
  3644.             }
  3645.             return false;
  3646.         }
  3647.        
  3648.         void WriteMemberBegin(Member[] members)
  3649.         {
  3650.            
  3651.             for (int i = 0; i < members.Length; i++) {
  3652.                 Member member = (Member)members[i];
  3653.                
  3654.                 if (member.IsArrayLike) {
  3655.                     string a = member.ArrayName;
  3656.                     string c = "c" + a;
  3657.                    
  3658.                     TypeDesc typeDesc = member.Mapping.TypeDesc;
  3659.                     string typeDescFullName = typeDesc.CSharpName;
  3660.                    
  3661.                     if (member.Mapping.TypeDesc.IsArray) {
  3662.                         WriteArrayLocalDecl(typeDesc.CSharpName, a, "null", typeDesc);
  3663.                         Writer.Write("int ");
  3664.                         Writer.Write(c);
  3665.                         Writer.WriteLine(" = 0;");
  3666.                        
  3667.                         if (member.Mapping.ChoiceIdentifier != null) {
  3668.                             WriteArrayLocalDecl(member.Mapping.ChoiceIdentifier.Mapping.TypeDesc.CSharpName + "[]", member.ChoiceArrayName, "null", member.Mapping.ChoiceIdentifier.Mapping.TypeDesc);
  3669.                             Writer.Write("int c");
  3670.                             Writer.Write(member.ChoiceArrayName);
  3671.                             Writer.WriteLine(" = 0;");
  3672.                            
  3673.                         }
  3674.                     }
  3675.                     else {
  3676.                         bool useReflection = typeDesc.UseReflection;
  3677.                         if (member.Source[member.Source.Length - 1] == '(' || member.Source[member.Source.Length - 1] == '{') {
  3678.                             WriteCreateInstance(typeDescFullName, a, useReflection, typeDesc.CannotNew);
  3679.                             Writer.Write(member.Source);
  3680.                             Writer.Write(a);
  3681.                             if (member.Source[member.Source.Length - 1] == '{')
  3682.                                 Writer.WriteLine("});");
  3683.                             else
  3684.                                 Writer.WriteLine(");");
  3685.                         }
  3686.                         else {
  3687.                             if (member.IsList && !member.Mapping.ReadOnly && member.Mapping.TypeDesc.IsNullable) {
  3688.                                 // we need to new the Collections and ArrayLists
  3689.                                 Writer.Write("if ((object)(");
  3690.                                 Writer.Write(member.Source);
  3691.                                 Writer.Write(") == null) ");
  3692.                                 if (!member.Mapping.TypeDesc.HasDefaultConstructor) {
  3693.                                     Writer.Write("throw CreateReadOnlyCollectionException(");
  3694.                                     WriteQuotedCSharpString(member.Mapping.TypeDesc.CSharpName);
  3695.                                     Writer.WriteLine(");");
  3696.                                 }
  3697.                                 else {
  3698.                                     Writer.Write(member.Source);
  3699.                                     Writer.Write(" = ");
  3700.                                     Writer.Write(RaCodeGen.GetStringForCreateInstance(typeDescFullName, useReflection, typeDesc.CannotNew, true));
  3701.                                     Writer.WriteLine(";");
  3702.                                 }
  3703.                             }
  3704.                             WriteLocalDecl(typeDescFullName, a, member.Source, useReflection);
  3705.                         }
  3706.                     }
  3707.                 }
  3708.             }
  3709.         }
  3710.        
  3711.         string ExpectedElements(Member[] members)
  3712.         {
  3713.             if (IsSequence(members))
  3714.                 return "null";
  3715.             string qnames = string.Empty;
  3716.             bool firstElement = true;
  3717.             for (int i = 0; i < members.Length; i++) {
  3718.                 Member member = (Member)members[i];
  3719.                 if (member.Mapping.Xmlns != null)
  3720.                     continue;
  3721.                 if (member.Mapping.Ignore)
  3722.                     continue;
  3723.                 if (member.Mapping.IsText || member.Mapping.IsAttribute)
  3724.                     continue;
  3725.                
  3726.                 ElementAccessor[] elements = member.Mapping.Elements;
  3727.                
  3728.                 for (int j = 0; j < elements.Length; j++) {
  3729.                     ElementAccessor e = elements[j];
  3730.                     string ns = e.Form == XmlSchemaForm.Qualified ? e.Namespace : "";
  3731.                     if (e.Any && (e.Name == null || e.Name.Length == 0))
  3732.                         continue;
  3733.                    
  3734.                     if (!firstElement)
  3735.                         qnames += ", ";
  3736.                     qnames += ns + ":" + e.Name;
  3737.                     firstElement = false;
  3738.                 }
  3739.             }
  3740.             StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
  3741.             ReflectionAwareCodeGen.WriteQuotedCSharpString(new IndentedWriter(writer, true), qnames);
  3742.             return writer.ToString();
  3743.         }
  3744.        
  3745.         void WriteMemberElements(Member[] members, string elementElseString, string elseString, Member anyElement, Member anyText, string checkTypeHrefsSource)
  3746.         {
  3747.             bool checkType = (checkTypeHrefsSource != null && checkTypeHrefsSource.Length > 0);
  3748.            
  3749.             if (anyText != null) {
  3750.                 Writer.WriteLine("string tmp = null;");
  3751.             }
  3752.            
  3753.             Writer.Write("if (Reader.NodeType == ");
  3754.             Writer.Write(typeof(XmlNodeType).FullName);
  3755.             Writer.WriteLine(".Element) {");
  3756.             Writer.Indent++;
  3757.            
  3758.             if (checkType) {
  3759.                 WriteIfNotSoapRoot(elementElseString + " continue;");
  3760.                 WriteMemberElementsCheckType(checkTypeHrefsSource);
  3761.             }
  3762.             else {
  3763.                 WriteMemberElementsIf(members, anyElement, elementElseString, null);
  3764.             }
  3765.            
  3766.             Writer.Indent--;
  3767.             Writer.WriteLine("}");
  3768.            
  3769.             if (anyText != null)
  3770.                 WriteMemberText(anyText, elseString);
  3771.            
  3772.             Writer.WriteLine("else {");
  3773.             Writer.Indent++;
  3774.             Writer.WriteLine(elseString);
  3775.             Writer.Indent--;
  3776.             Writer.WriteLine("}");
  3777.         }
  3778.        
  3779.         void WriteMemberText(Member anyText, string elseString)
  3780.         {
  3781.             Writer.Write("else if (Reader.NodeType == ");
  3782.             Writer.Write(typeof(XmlNodeType).FullName);
  3783.             Writer.WriteLine(".Text || ");
  3784.             Writer.Write("Reader.NodeType == ");
  3785.             Writer.Write(typeof(XmlNodeType).FullName);
  3786.             Writer.WriteLine(".CDATA || ");
  3787.             Writer.Write("Reader.NodeType == ");
  3788.             Writer.Write(typeof(XmlNodeType).FullName);
  3789.             Writer.WriteLine(".Whitespace || ");
  3790.             Writer.Write("Reader.NodeType == ");
  3791.             Writer.Write(typeof(XmlNodeType).FullName);
  3792.             Writer.WriteLine(".SignificantWhitespace) {");
  3793.             Writer.Indent++;
  3794.            
  3795.             if (anyText != null) {
  3796.                 WriteText(anyText);
  3797.             }
  3798.             else {
  3799.                 Writer.Write(elseString);
  3800.                 Writer.WriteLine(";");
  3801.             }
  3802.             Writer.Indent--;
  3803.             Writer.WriteLine("}");
  3804.         }
  3805.        
  3806.         void WriteText(Member member)
  3807.         {
  3808.            
  3809.             TextAccessor text = member.Mapping.Text;
  3810.            
  3811.             if (text.Mapping is SpecialMapping) {
  3812.                 SpecialMapping special = (SpecialMapping)text.Mapping;
  3813.                 WriteSourceBeginTyped(member.ArraySource, special.TypeDesc);
  3814.                 switch (special.TypeDesc.Kind) {
  3815.                     case TypeKind.Node:
  3816.                         Writer.Write("Document.CreateTextNode(Reader.ReadString())");
  3817.                         break;
  3818.                     default:
  3819.                         throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
  3820.                         break;
  3821.                 }
  3822.                 WriteSourceEnd(member.ArraySource);
  3823.             }
  3824.             else {
  3825.                 if (member.IsArrayLike) {
  3826.                     WriteSourceBegin(member.ArraySource);
  3827.                     if (text.Mapping.TypeDesc.CollapseWhitespace) {
  3828.                         Writer.Write("CollapseWhitespace(Reader.ReadString())");
  3829.                     }
  3830.                     else {
  3831.                         Writer.Write("Reader.ReadString()");
  3832.                     }
  3833.                 }
  3834.                 else {
  3835.                     if (text.Mapping.TypeDesc == StringTypeDesc || text.Mapping.TypeDesc.FormatterName == "String") {
  3836.                         Writer.Write("tmp = ReadString(tmp, ");
  3837.                         if (text.Mapping.TypeDesc.CollapseWhitespace)
  3838.                             Writer.WriteLine("true);");
  3839.                         else
  3840.                             Writer.WriteLine("false);");
  3841.                        
  3842.                         WriteSourceBegin(member.ArraySource);
  3843.                         Writer.Write("tmp");
  3844.                     }
  3845.                     else {
  3846.                         WriteSourceBegin(member.ArraySource);
  3847.                         WritePrimitive(text.Mapping, "Reader.ReadString()");
  3848.                     }
  3849.                 }
  3850.                 WriteSourceEnd(member.ArraySource);
  3851.             }
  3852.            
  3853.             Writer.WriteLine(";");
  3854.         }
  3855.        
  3856.         void WriteMemberElementsCheckType(string checkTypeHrefsSource)
  3857.         {
  3858.             Writer.WriteLine("string refElemId = null;");
  3859.             Writer.WriteLine("object refElem = ReadReferencingElement(null, null, true, out refElemId);");
  3860.            
  3861.             Writer.WriteLine("if (refElemId != null) {");
  3862.             Writer.Indent++;
  3863.             Writer.Write(checkTypeHrefsSource);
  3864.             Writer.WriteLine(".Add(refElemId);");
  3865.             Writer.Write(checkTypeHrefsSource);
  3866.             Writer.WriteLine("IsObject.Add(false);");
  3867.             Writer.Indent--;
  3868.             Writer.WriteLine("}");
  3869.             Writer.WriteLine("else if (refElem != null) {");
  3870.             Writer.Indent++;
  3871.             Writer.Write(checkTypeHrefsSource);
  3872.             Writer.WriteLine(".Add(refElem);");
  3873.             Writer.Write(checkTypeHrefsSource);
  3874.             Writer.WriteLine("IsObject.Add(true);");
  3875.             Writer.Indent--;
  3876.             Writer.WriteLine("}");
  3877.         }
  3878.        
  3879.         void WriteMemberElementsElse(Member anyElement, string elementElseString)
  3880.         {
  3881.             if (anyElement != null) {
  3882.                 ElementAccessor[] elements = anyElement.Mapping.Elements;
  3883.                 for (int i = 0; i < elements.Length; i++) {
  3884.                     ElementAccessor element = elements[i];
  3885.                     if (element.Any && element.Name.Length == 0) {
  3886.                         WriteElement(anyElement.ArraySource, anyElement.ArrayName, anyElement.ChoiceArraySource, element, anyElement.Mapping.ChoiceIdentifier, null, false, false, -1, i
  3887.                         );
  3888.                         break;
  3889.                     }
  3890.                 }
  3891.             }
  3892.             else {
  3893.                 Writer.WriteLine(elementElseString);
  3894.             }
  3895.         }
  3896.        
  3897.         bool IsSequence(Member[] members)
  3898.         {
  3899.             for (int i = 0; i < members.Length; i++) {
  3900.                 if (members[i].Mapping.IsParticle && members[i].Mapping.IsSequence)
  3901.                     return true;
  3902.             }
  3903.             return false;
  3904.         }
  3905.         void WriteMemberElementsIf(Member[] members, Member anyElement, string elementElseString, string checkTypeSource)
  3906.         {
  3907.             bool checkType = checkTypeSource != null && checkTypeSource.Length > 0;
  3908.             //int count = checkType ? 1 : 0;
  3909.             int count = 0;
  3910.            
  3911.             bool isSequence = IsSequence(members);
  3912.             if (isSequence) {
  3913.                 Writer.WriteLine("switch (state) {");
  3914.             }
  3915.             int cases = 0;
  3916.            
  3917.             for (int i = 0; i < members.Length; i++) {
  3918.                 Member member = (Member)members[i];
  3919.                 if (member.Mapping.Xmlns != null)
  3920.                     continue;
  3921.                 if (member.Mapping.Ignore)
  3922.                     continue;
  3923.                 if (isSequence && (member.Mapping.IsText || member.Mapping.IsAttribute))
  3924.                     continue;
  3925.                
  3926.                 bool firstElement = true;
  3927.                 ChoiceIdentifierAccessor choice = member.Mapping.ChoiceIdentifier;
  3928.                 ElementAccessor[] elements = member.Mapping.Elements;
  3929.                
  3930.                 for (int j = 0; j < elements.Length; j++) {
  3931.                     ElementAccessor e = elements[j];
  3932.                     string ns = e.Form == XmlSchemaForm.Qualified ? e.Namespace : "";
  3933.                     if (!isSequence && e.Any && (e.Name == null || e.Name.Length == 0))
  3934.                         continue;
  3935.                     if (!firstElement || (!isSequence && count > 0)) {
  3936.                         Writer.Write("else ");
  3937.                     }
  3938.                     else if (isSequence) {
  3939.                         Writer.Write("case ");
  3940.                         Writer.Write(cases.ToString(CultureInfo.InvariantCulture));
  3941.                         Writer.WriteLine(":");
  3942.                         Writer.Indent++;
  3943.                     }
  3944.                     count++;
  3945.                     firstElement = false;
  3946.                     Writer.Write("if (");
  3947.                     if (member.ParamsReadSource != null) {
  3948.                         Writer.Write("!");
  3949.                         Writer.Write(member.ParamsReadSource);
  3950.                         Writer.Write(" && ");
  3951.                     }
  3952.                     if (checkType) {
  3953.                         if (e.Mapping is NullableMapping) {
  3954.                             TypeDesc td = ((NullableMapping)e.Mapping).BaseMapping.TypeDesc;
  3955.                             Writer.Write(RaCodeGen.GetStringForTypeof(td.CSharpName, td.UseReflection));
  3956.                         }
  3957.                         else {
  3958.                             Writer.Write(RaCodeGen.GetStringForTypeof(e.Mapping.TypeDesc.CSharpName, e.Mapping.TypeDesc.UseReflection));
  3959.                         }
  3960.                         Writer.Write(".IsAssignableFrom(");
  3961.                         Writer.Write(checkTypeSource);
  3962.                         Writer.Write("Type)");
  3963.                     }
  3964.                     else {
  3965.                         if (member.Mapping.IsReturnValue)
  3966.                             Writer.Write("(IsReturnValue || ");
  3967.                         if (isSequence && e.Any && e.Namespace == null) {
  3968.                             Writer.Write("true");
  3969.                         }
  3970.                         else {
  3971.                             WriteXmlNodeEqual("Reader", e.Name, ns);
  3972.                         }
  3973.                         if (member.Mapping.IsReturnValue)
  3974.                             Writer.Write(")");
  3975.                     }
  3976.                     Writer.WriteLine(") {");
  3977.                     Writer.Indent++;
  3978.                     if (checkType) {
  3979.                         if (e.Mapping.TypeDesc.IsValueType || e.Mapping is NullableMapping) {
  3980.                             Writer.Write("if (");
  3981.                             Writer.Write(checkTypeSource);
  3982.                             Writer.WriteLine(" != null) {");
  3983.                             Writer.Indent++;
  3984.                         }
  3985.                         if (e.Mapping is NullableMapping) {
  3986.                             WriteSourceBegin(member.ArraySource);
  3987.                             TypeDesc td = ((NullableMapping)e.Mapping).BaseMapping.TypeDesc;
  3988.                             Writer.Write(RaCodeGen.GetStringForCreateInstance(e.Mapping.TypeDesc.CSharpName, e.Mapping.TypeDesc.UseReflection, false, true, "(" + td.CSharpName + ")" + checkTypeSource));
  3989.                         }
  3990.                         else {
  3991.                             WriteSourceBeginTyped(member.ArraySource, e.Mapping.TypeDesc);
  3992.                             Writer.Write(checkTypeSource);
  3993.                         }
  3994.                         WriteSourceEnd(member.ArraySource);
  3995.                         Writer.WriteLine(";");
  3996.                         if (e.Mapping.TypeDesc.IsValueType) {
  3997.                             Writer.Indent--;
  3998.                             Writer.WriteLine("}");
  3999.                         }
  4000.                         if (member.FixupIndex >= 0) {
  4001.                             Writer.Write("fixup.Ids[");
  4002.                             Writer.Write(member.FixupIndex.ToString(CultureInfo.InvariantCulture));
  4003.                             Writer.Write("] = ");
  4004.                             Writer.Write(checkTypeSource);
  4005.                             Writer.WriteLine("Id;");
  4006.                         }
  4007.                     }
  4008.                     else {
  4009.                         WriteElement(member.ArraySource, member.ArrayName, member.ChoiceArraySource, e, choice, member.Mapping.CheckSpecified ? member.CheckSpecifiedSource : null, member.IsList && member.Mapping.TypeDesc.IsNullable, member.Mapping.ReadOnly, member.FixupIndex, j
  4010.                         );
  4011.                     }
  4012.                     if (member.Mapping.IsReturnValue)
  4013.                         Writer.WriteLine("IsReturnValue = false;");
  4014.                     if (member.ParamsReadSource != null) {
  4015.                         Writer.Write(member.ParamsReadSource);
  4016.                         Writer.WriteLine(" = true;");
  4017.                     }
  4018.                     Writer.Indent--;
  4019.                     Writer.WriteLine("}");
  4020.                 }
  4021.                 if (isSequence) {
  4022.                     if (member.IsArrayLike) {
  4023.                         Writer.WriteLine("else {");
  4024.                         Writer.Indent++;
  4025.                     }
  4026.                     cases++;
  4027.                     Writer.Write("state = ");
  4028.                     Writer.Write(cases.ToString(CultureInfo.InvariantCulture));
  4029.                     Writer.WriteLine(";");
  4030.                     if (member.IsArrayLike) {
  4031.                         Writer.Indent--;
  4032.                         Writer.WriteLine("}");
  4033.                     }
  4034.                     Writer.WriteLine("break;");
  4035.                     Writer.Indent--;
  4036.                 }
  4037.             }
  4038.             if (count > 0) {
  4039.                 if (isSequence)
  4040.                     Writer.WriteLine("default:");
  4041.                 else
  4042.                     Writer.WriteLine("else {");
  4043.                 Writer.Indent++;
  4044.             }
  4045.             WriteMemberElementsElse(anyElement, elementElseString);
  4046.             if (count > 0) {
  4047.                 if (isSequence) {
  4048.                     Writer.WriteLine("break;");
  4049.                 }
  4050.                 Writer.Indent--;
  4051.                 Writer.WriteLine("}");
  4052.             }
  4053.         }
  4054.        
  4055.         string GetArraySource(TypeDesc typeDesc, string arrayName)
  4056.         {
  4057.             return GetArraySource(typeDesc, arrayName, false);
  4058.         }
  4059.         string GetArraySource(TypeDesc typeDesc, string arrayName, bool multiRef)
  4060.         {
  4061.             string a = arrayName;
  4062.             string c = "c" + a;
  4063.             string init = "";
  4064.            
  4065.             if (multiRef) {
  4066.                 init = "soap = (System.Object[])EnsureArrayIndex(soap, " + c + "+2, typeof(System.Object)); ";
  4067.             }
  4068.             bool useReflection = typeDesc.UseReflection;
  4069.             if (typeDesc.IsArray) {
  4070.                 string arrayTypeFullName = typeDesc.ArrayElementTypeDesc.CSharpName;
  4071.                 bool arrayUseReflection = typeDesc.ArrayElementTypeDesc.UseReflection;
  4072.                 string castString = useReflection ? "" : "(" + arrayTypeFullName + "[])";
  4073.                 init = init + a + " = " + castString + "EnsureArrayIndex(" + a + ", " + c + ", " + RaCodeGen.GetStringForTypeof(arrayTypeFullName, arrayUseReflection) + ");";
  4074.                 string arraySource = RaCodeGen.GetStringForArrayMember(a, c + "++", typeDesc);
  4075.                 if (multiRef) {
  4076.                     init = init + " soap[1] = " + a + ";";
  4077.                     init = init + " if (ReadReference(out soap[" + c + "+2])) " + arraySource + " = null; else ";
  4078.                 }
  4079.                 return init + arraySource;
  4080.             }
  4081.             else {
  4082.                 return RaCodeGen.GetStringForMethod(arrayName, typeDesc.CSharpName, "Add", useReflection);
  4083.                
  4084.             }
  4085.         }
  4086.        
  4087.        
  4088.         void WriteMemberEnd(Member[] members)
  4089.         {
  4090.             WriteMemberEnd(members, false);
  4091.         }
  4092.        
  4093.         void WriteMemberEnd(Member[] members, bool soapRefs)
  4094.         {
  4095.             for (int i = 0; i < members.Length; i++) {
  4096.                 Member member = (Member)members[i];
  4097.                
  4098.                 if (member.IsArrayLike) {
  4099.                    
  4100.                     TypeDesc typeDesc = member.Mapping.TypeDesc;
  4101.                    
  4102.                     if (typeDesc.IsArray) {
  4103.                        
  4104.                         WriteSourceBegin(member.Source);
  4105.                        
  4106.                         if (soapRefs)
  4107.                             Writer.Write(" soap[1] = ");
  4108.                        
  4109.                         string a = member.ArrayName;
  4110.                         string c = "c" + a;
  4111.                        
  4112.                         bool arrayUseReflection = typeDesc.ArrayElementTypeDesc.UseReflection;
  4113.                         string arrayTypeFullName = typeDesc.ArrayElementTypeDesc.CSharpName;
  4114.                         if (!arrayUseReflection)
  4115.                             Writer.Write("(" + arrayTypeFullName + "[])");
  4116.                         Writer.Write("ShrinkArray(");
  4117.                         Writer.Write(a);
  4118.                         Writer.Write(", ");
  4119.                         Writer.Write(c);
  4120.                         Writer.Write(", ");
  4121.                         Writer.Write(RaCodeGen.GetStringForTypeof(arrayTypeFullName, arrayUseReflection));
  4122.                         Writer.Write(", ");
  4123.                         WriteBooleanValue(member.IsNullable);
  4124.                         Writer.Write(")");
  4125.                         WriteSourceEnd(member.Source);
  4126.                         Writer.WriteLine(";");
  4127.                        
  4128.                         if (member.Mapping.ChoiceIdentifier != null) {
  4129.                             WriteSourceBegin(member.ChoiceSource);
  4130.                             a = member.ChoiceArrayName;
  4131.                             c = "c" + a;
  4132.                            
  4133.                             bool choiceUseReflection = member.Mapping.ChoiceIdentifier.Mapping.TypeDesc.UseReflection;
  4134.                             string choiceTypeName = member.Mapping.ChoiceIdentifier.Mapping.TypeDesc.CSharpName;
  4135.                             if (!choiceUseReflection)
  4136.                                 Writer.Write("(" + choiceTypeName + "[])");
  4137.                             Writer.Write("ShrinkArray(");
  4138.                             Writer.Write(a);
  4139.                             Writer.Write(", ");
  4140.                             Writer.Write(c);
  4141.                             Writer.Write(", ");
  4142.                             Writer.Write(RaCodeGen.GetStringForTypeof(choiceTypeName, choiceUseReflection));
  4143.                             Writer.Write(", ");
  4144.                             WriteBooleanValue(member.IsNullable);
  4145.                             Writer.Write(")");
  4146.                             WriteSourceEnd(member.ChoiceSource);
  4147.                             Writer.WriteLine(";");
  4148.                         }
  4149.                        
  4150.                     }
  4151.                     else if (typeDesc.IsValueType) {
  4152.                         Writer.Write(member.Source);
  4153.                         Writer.Write(" = ");
  4154.                         Writer.Write(member.ArrayName);
  4155.                         Writer.WriteLine(";");
  4156.                     }
  4157.                 }
  4158.             }
  4159.         }
  4160.        
  4161.         void WriteSourceBeginTyped(string source, TypeDesc typeDesc)
  4162.         {
  4163.             WriteSourceBegin(source);
  4164.             if (typeDesc != null && !typeDesc.UseReflection) {
  4165.                 Writer.Write("(");
  4166.                 Writer.Write(typeDesc.CSharpName);
  4167.                 Writer.Write(")");
  4168.             }
  4169.         }
  4170.        
  4171.         void WriteSourceBegin(string source)
  4172.         {
  4173.             Writer.Write(source);
  4174.             if (source[source.Length - 1] != '(' && source[source.Length - 1] != '{')
  4175.                 Writer.Write(" = ");
  4176.         }
  4177.        
  4178.         void WriteSourceEnd(string source)
  4179.         {
  4180.             // source could be of the form "var", "arrayVar[i]",
  4181.             // "collection.Add(" or "methodInfo.Invoke(collection, new object[] {"
  4182.             if (source[source.Length - 1] == '(')
  4183.                 Writer.Write(")");
  4184.             else if (source[source.Length - 1] == '{')
  4185.                 Writer.Write("})");
  4186.         }
  4187.        
  4188.         void WriteArray(string source, string arrayName, ArrayMapping arrayMapping, bool readOnly, bool isNullable, int fixupIndex)
  4189.         {
  4190.             if (arrayMapping.IsSoap) {
  4191.                 Writer.Write("object rre = ");
  4192.                 Writer.Write(fixupIndex >= 0 ? "ReadReferencingElement" : "ReadReferencedElement");
  4193.                 Writer.Write("(");
  4194.                 WriteID(arrayMapping.TypeName);
  4195.                 Writer.Write(", ");
  4196.                 WriteID(arrayMapping.Namespace);
  4197.                 if (fixupIndex >= 0) {
  4198.                     Writer.Write(", ");
  4199.                     Writer.Write("out fixup.Ids[");
  4200.                     Writer.Write((fixupIndex).ToString(CultureInfo.InvariantCulture));
  4201.                     Writer.Write("]");
  4202.                 }
  4203.                 Writer.WriteLine(");");
  4204.                
  4205.                 TypeDesc td = arrayMapping.TypeDesc;
  4206.                 if (td.IsEnumerable || td.IsCollection) {
  4207.                     Writer.WriteLine("if (rre != null) {");
  4208.                     Writer.Indent++;
  4209.                     WriteAddCollectionFixup(td, readOnly, source, "rre");
  4210.                     Writer.Indent--;
  4211.                     Writer.WriteLine("}");
  4212.                 }
  4213.                 else {
  4214.                     Writer.WriteLine("try {");
  4215.                     Writer.Indent++;
  4216.                     WriteSourceBeginTyped(source, arrayMapping.TypeDesc);
  4217.                     Writer.Write("rre");
  4218.                     WriteSourceEnd(source);
  4219.                     Writer.WriteLine(";");
  4220.                     WriteCatchCastException(arrayMapping.TypeDesc, "rre", null);
  4221.                 }
  4222.             }
  4223.             else {
  4224.                 Writer.WriteLine("if (!ReadNull()) {");
  4225.                 Writer.Indent++;
  4226.                
  4227.                 MemberMapping memberMapping = new MemberMapping();
  4228.                 memberMapping.Elements = arrayMapping.Elements;
  4229.                 memberMapping.TypeDesc = arrayMapping.TypeDesc;
  4230.                 memberMapping.ReadOnly = readOnly;
  4231.                 Member member = new Member(this, source, arrayName, 0, memberMapping, false);
  4232.                 member.IsNullable = false;
  4233.                 //Note, sowmys: IsNullable is set to false since null condition (xsi:nil) is already handled by 'ReadNull()'
  4234.                 Member[] members = new Member[] {member};
  4235.                 WriteMemberBegin(members);
  4236.                
  4237.                 if (readOnly) {
  4238.                     Writer.Write("if (((object)(");
  4239.                     Writer.Write(member.ArrayName);
  4240.                     Writer.Write(") == null) || ");
  4241.                 }
  4242.                 else {
  4243.                     Writer.Write("if (");
  4244.                 }
  4245.                 Writer.WriteLine("(Reader.IsEmptyElement)) {");
  4246.                 Writer.Indent++;
  4247.                 Writer.WriteLine("Reader.Skip();");
  4248.                 Writer.Indent--;
  4249.                 Writer.WriteLine("}");
  4250.                 Writer.WriteLine("else {");
  4251.                 Writer.Indent++;
  4252.                
  4253.                 Writer.WriteLine("Reader.ReadStartElement();");
  4254.                 int loopIndex = WriteWhileNotLoopStart();
  4255.                 Writer.Indent++;
  4256.                
  4257.                 string unknownNode = "UnknownNode(null, " + ExpectedElements(members) + ");";
  4258.                 WriteMemberElements(members, unknownNode, unknownNode, null, null, null);
  4259.                 Writer.WriteLine("Reader.MoveToContent();");
  4260.                
  4261.                 WriteWhileLoopEnd(loopIndex);
  4262.                 Writer.Indent--;
  4263.                 Writer.WriteLine("ReadEndElement();");
  4264.                 Writer.WriteLine("}");
  4265.                
  4266.                 WriteMemberEnd(members, false);
  4267.                
  4268.                 Writer.Indent--;
  4269.                 Writer.WriteLine("}");
  4270.                 if (isNullable) {
  4271.                     Writer.WriteLine("else {");
  4272.                     Writer.Indent++;
  4273.                     member.IsNullable = true;
  4274.                     WriteMemberBegin(members);
  4275.                     WriteMemberEnd(members);
  4276.                     Writer.Indent--;
  4277.                     Writer.WriteLine("}");
  4278.                 }
  4279.             }
  4280.         }
  4281.        
  4282.         void WriteElement(string source, string arrayName, string choiceSource, ElementAccessor element, ChoiceIdentifierAccessor choice, string checkSpecified, bool checkForNull, bool readOnly, int fixupIndex, int elementIndex
  4283.         )
  4284.         {
  4285.             if (element.Mapping is ArrayMapping) {
  4286.                 WriteArray(source, arrayName, (ArrayMapping)element.Mapping, readOnly, element.IsNullable, fixupIndex);
  4287.             }
  4288.             else if (element.Mapping is NullableMapping) {
  4289.                 string methodName = ReferenceMapping(element.Mapping);
  4290.                 #if DEBUG
  4291.                 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  4292.                 if (methodName == null)
  4293.                     throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, element.Mapping.TypeDesc.Name));
  4294.                 #endif
  4295.                 WriteSourceBegin(source);
  4296.                 Writer.Write(methodName);
  4297.                 Writer.Write("(true)");
  4298.                 WriteSourceEnd(source);
  4299.                 Writer.WriteLine(";");
  4300.             }
  4301.             else if (!element.Mapping.IsSoap && (element.Mapping is PrimitiveMapping)) {
  4302.                 if (element.IsNullable) {
  4303.                     Writer.WriteLine("if (ReadNull()) {");
  4304.                     Writer.Indent++;
  4305.                     WriteSourceBegin(source);
  4306.                     if (element.Mapping.TypeDesc.IsValueType) {
  4307.                         Writer.Write(RaCodeGen.GetStringForCreateInstance(element.Mapping.TypeDesc.CSharpName, element.Mapping.TypeDesc.UseReflection, false, false));
  4308.                     }
  4309.                     else {
  4310.                         Writer.Write("null");
  4311.                     }
  4312.                     WriteSourceEnd(source);
  4313.                     Writer.WriteLine(";");
  4314.                     if (checkSpecified != null && checkSpecified.Length > 0) {
  4315.                         Writer.Write(checkSpecified);
  4316.                         Writer.WriteLine(" = true;");
  4317.                     }
  4318.                     Writer.Indent--;
  4319.                     Writer.WriteLine("}");
  4320.                     Writer.Write("else ");
  4321.                 }
  4322.                 if (element.Default != null && element.Default != DBNull.Value && element.Mapping.TypeDesc.IsValueType) {
  4323.                     Writer.WriteLine("if (Reader.IsEmptyElement) {");
  4324.                     Writer.Indent++;
  4325.                     Writer.WriteLine("Reader.Skip();");
  4326.                     Writer.Indent--;
  4327.                     Writer.WriteLine("}");
  4328.                     Writer.WriteLine("else {");
  4329.                 }
  4330.                 else {
  4331.                     Writer.WriteLine("{");
  4332.                 }
  4333.                 Writer.Indent++;
  4334.                
  4335.                 WriteSourceBegin(source);
  4336.                 if (element.Mapping.TypeDesc == QnameTypeDesc)
  4337.                     Writer.Write("ReadElementQualifiedName()");
  4338.                 else {
  4339.                     string readFunc;
  4340.                     switch (element.Mapping.TypeDesc.FormatterName) {
  4341.                         case "ByteArrayBase64":
  4342.                         case "ByteArrayHex":
  4343.                             readFunc = "false";
  4344.                             break;
  4345.                         default:
  4346.                             readFunc = "Reader.ReadElementString()";
  4347.                             break;
  4348.                     }
  4349.                     WritePrimitive(element.Mapping, readFunc);
  4350.                 }
  4351.                
  4352.                 WriteSourceEnd(source);
  4353.                 Writer.WriteLine(";");
  4354.                 if (checkSpecified != null && checkSpecified.Length > 0) {
  4355.                     Writer.Write(checkSpecified);
  4356.                     Writer.WriteLine(" = true;");
  4357.                 }
  4358.                 Writer.Indent--;
  4359.                 Writer.WriteLine("}");
  4360.             }
  4361.             else if (element.Mapping is StructMapping || (element.Mapping.IsSoap && element.Mapping is PrimitiveMapping)) {
  4362.                 TypeMapping mapping = element.Mapping;
  4363.                 if (mapping.IsSoap) {
  4364.                     Writer.Write("object rre = ");
  4365.                     Writer.Write(fixupIndex >= 0 ? "ReadReferencingElement" : "ReadReferencedElement");
  4366.                     Writer.Write("(");
  4367.                     WriteID(mapping.TypeName);
  4368.                     Writer.Write(", ");
  4369.                     WriteID(mapping.Namespace);
  4370.                    
  4371.                     if (fixupIndex >= 0) {
  4372.                         Writer.Write(", out fixup.Ids[");
  4373.                         Writer.Write((fixupIndex).ToString(CultureInfo.InvariantCulture));
  4374.                         Writer.Write("]");
  4375.                     }
  4376.                     Writer.Write(")");
  4377.                     WriteSourceEnd(source);
  4378.                     Writer.WriteLine(";");
  4379.                    
  4380.                     if (mapping.TypeDesc.IsValueType) {
  4381.                         Writer.WriteLine("if (rre != null) {");
  4382.                         Writer.Indent++;
  4383.                     }
  4384.                    
  4385.                     Writer.WriteLine("try {");
  4386.                     Writer.Indent++;
  4387.                     WriteSourceBeginTyped(source, mapping.TypeDesc);
  4388.                     Writer.Write("rre");
  4389.                     WriteSourceEnd(source);
  4390.                     Writer.WriteLine(";");
  4391.                     WriteCatchCastException(mapping.TypeDesc, "rre", null);
  4392.                     Writer.Write("Referenced(");
  4393.                     Writer.Write(source);
  4394.                     Writer.WriteLine(");");
  4395.                     if (checkSpecified != null && checkSpecified.Length > 0) {
  4396.                         Writer.Write(checkSpecified);
  4397.                         Writer.WriteLine(" = true;");
  4398.                     }
  4399.                     if (mapping.TypeDesc.IsValueType) {
  4400.                         Writer.Indent--;
  4401.                         Writer.WriteLine("}");
  4402.                     }
  4403.                 }
  4404.                 else {
  4405.                     string methodName = ReferenceMapping(mapping);
  4406.                     #if DEBUG
  4407.                     // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  4408.                     if (methodName == null)
  4409.                         throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorMethod, mapping.TypeDesc.Name));
  4410.                     #endif
  4411.                    
  4412.                     if (checkForNull) {
  4413.                         Writer.Write("if ((object)(");
  4414.                         Writer.Write(arrayName);
  4415.                         Writer.Write(") == null) Reader.Skip(); else ");
  4416.                     }
  4417.                     WriteSourceBegin(source);
  4418.                     Writer.Write(methodName);
  4419.                     Writer.Write("(");
  4420.                     if (mapping.TypeDesc.IsNullable) {
  4421.                         WriteBooleanValue(element.IsNullable);
  4422.                         Writer.Write(", ");
  4423.                     }
  4424.                     Writer.Write("true");
  4425.                     Writer.Write(")");
  4426.                     WriteSourceEnd(source);
  4427.                     Writer.WriteLine(";");
  4428.                 }
  4429.             }
  4430.             else if (element.Mapping is SpecialMapping) {
  4431.                 SpecialMapping special = (SpecialMapping)element.Mapping;
  4432.                 switch (special.TypeDesc.Kind) {
  4433.                     case TypeKind.Node:
  4434.                         bool isDoc = special.TypeDesc.FullName == typeof(XmlDocument).FullName;
  4435.                         WriteSourceBeginTyped(source, special.TypeDesc);
  4436.                         Writer.Write(isDoc ? "ReadXmlDocument(" : "ReadXmlNode(");
  4437.                         Writer.Write(element.Any ? "false" : "true");
  4438.                         Writer.Write(")");
  4439.                         WriteSourceEnd(source);
  4440.                         Writer.WriteLine(";");
  4441.                         break;
  4442.                     case TypeKind.Serializable:
  4443.                         SerializableMapping sm = (SerializableMapping)element.Mapping;
  4444.                         // check to see if we need to do the derivation
  4445.                         if (sm.DerivedMappings != null) {
  4446.                             Writer.Write(typeof(XmlQualifiedName).FullName);
  4447.                             Writer.WriteLine(" tser = GetXsiType();");
  4448.                             Writer.Write("if (tser == null");
  4449.                             Writer.Write(" || ");
  4450.                             WriteQNameEqual("tser", sm.XsiType.Name, sm.XsiType.Namespace);
  4451.                            
  4452.                             Writer.WriteLine(") {");
  4453.                             Writer.Indent++;
  4454.                         }
  4455.                        
  4456.                         WriteSourceBeginTyped(source, sm.TypeDesc);
  4457.                         Writer.Write("ReadSerializable(( ");
  4458.                         Writer.Write(typeof(IXmlSerializable).FullName);
  4459.                         Writer.Write(")");
  4460.                         Writer.Write(RaCodeGen.GetStringForCreateInstance(sm.TypeDesc.CSharpName, sm.TypeDesc.UseReflection, sm.TypeDesc.CannotNew, false));
  4461.                         Writer.Write(")");
  4462.                         WriteSourceEnd(source);
  4463.                         Writer.WriteLine(";");
  4464.                         if (sm.DerivedMappings != null) {
  4465.                             Writer.Indent--;
  4466.                             Writer.WriteLine("}");
  4467.                             WriteDerivedSerializable(sm, sm, source);
  4468.                             WriteUnknownNode("UnknownNode", "null", null, true);
  4469.                         }
  4470.                         break;
  4471.                     default:
  4472.                         throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
  4473.                         break;
  4474.                 }
  4475.             }
  4476.             else {
  4477.                 throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
  4478.             }
  4479.             if (choice != null) {
  4480.                 #if DEBUG
  4481.                 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
  4482.                 if (choiceSource == null)
  4483.                     throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "need parent for the " + source));
  4484.                 #endif
  4485.                
  4486.                 string enumTypeName = choice.Mapping.TypeDesc.CSharpName;
  4487.                 Writer.Write(choiceSource);
  4488.                 Writer.Write(" = ");
  4489.                 CodeIdentifier.CheckValidIdentifier(choice.MemberIds[elementIndex]);
  4490.                 Writer.Write(RaCodeGen.GetStringForEnumMember(enumTypeName, choice.MemberIds[elementIndex], choice.Mapping.TypeDesc.UseReflection));
  4491.                 Writer.WriteLine(";");
  4492.             }
  4493.         }
  4494.        
  4495.         void WriteDerivedSerializable(SerializableMapping head, SerializableMapping mapping, string source)
  4496.         {
  4497.             if (mapping == null)
  4498.                 return;
  4499.             for (SerializableMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping) {
  4500.                 Writer.Write("else if (tser == null");
  4501.                 Writer.Write(" || ");
  4502.                 WriteQNameEqual("tser", derived.XsiType.Name, derived.XsiType.Namespace);
  4503.                
  4504.                 Writer.WriteLine(") {");
  4505.                 Writer.Indent++;
  4506.                
  4507.                 if (derived.Type != null) {
  4508.                     if (head.Type.IsAssignableFrom(derived.Type)) {
  4509.                        
  4510.                         WriteSourceBeginTyped(source, head.TypeDesc);
  4511.                         Writer.Write("ReadSerializable(( ");
  4512.                         Writer.Write(typeof(IXmlSerializable).FullName);
  4513.                         Writer.Write(")");
  4514.                         Writer.Write(RaCodeGen.GetStringForCreateInstance(derived.TypeDesc.CSharpName, derived.TypeDesc.UseReflection, derived.TypeDesc.CannotNew, false));
  4515.                         Writer.Write(")");
  4516.                         WriteSourceEnd(source);
  4517.                         Writer.WriteLine(";");
  4518.                     }
  4519.                     else {
  4520.                         Writer.Write("throw CreateBadDerivationException(");
  4521.                         WriteQuotedCSharpString(derived.XsiType.Name);
  4522.                         Writer.Write(", ");
  4523.                         WriteQuotedCSharpString(derived.XsiType.Namespace);
  4524.                         Writer.Write(", ");
  4525.                         WriteQuotedCSharpString(head.XsiType.Name);
  4526.                         Writer.Write(", ");
  4527.                         WriteQuotedCSharpString(head.XsiType.Namespace);
  4528.                         Writer.Write(", ");
  4529.                         WriteQuotedCSharpString(derived.Type.FullName);
  4530.                         Writer.Write(", ");
  4531.                         WriteQuotedCSharpString(head.Type.FullName);
  4532.                         Writer.WriteLine(");");
  4533.                     }
  4534.                 }
  4535.                 else {
  4536.                     Writer.WriteLine("// " + "missing real mapping for " + derived.XsiType);
  4537.                     Writer.Write("throw CreateMissingIXmlSerializableType(");
  4538.                     WriteQuotedCSharpString(derived.XsiType.Name);
  4539.                     Writer.Write(", ");
  4540.                     WriteQuotedCSharpString(derived.XsiType.Namespace);
  4541.                     Writer.Write(", ");
  4542.                     WriteQuotedCSharpString(head.Type.FullName);
  4543.                     Writer.WriteLine(");");
  4544.                 }
  4545.                
  4546.                 Writer.Indent--;
  4547.                 Writer.WriteLine("}");
  4548.                
  4549.                 WriteDerivedSerializable(head, derived, source);
  4550.             }
  4551.         }
  4552.        
  4553.         int WriteWhileNotLoopStart()
  4554.         {
  4555.             Writer.WriteLine("Reader.MoveToContent();");
  4556.             int loopIndex = WriteWhileLoopStartCheck();
  4557.             Writer.Write("while (Reader.NodeType != ");
  4558.             Writer.Write(typeof(XmlNodeType).FullName);
  4559.             Writer.Write(".EndElement && Reader.NodeType != ");
  4560.             Writer.Write(typeof(XmlNodeType).FullName);
  4561.             Writer.WriteLine(".None) {");
  4562.             return loopIndex;
  4563.         }
  4564.        
  4565.         void WriteWhileLoopEnd(int loopIndex)
  4566.         {
  4567.             WriteWhileLoopEndCheck(loopIndex);
  4568.             Writer.Indent--;
  4569.             Writer.WriteLine("}");
  4570.         }
  4571.        
  4572.         int WriteWhileLoopStartCheck()
  4573.         {
  4574.             Writer.WriteLine(String.Format(CultureInfo.InvariantCulture, "int whileIterations{0} = 0;", nextWhileLoopIndex));
  4575.             Writer.WriteLine(String.Format(CultureInfo.InvariantCulture, "int readerCount{0} = ReaderCount;", nextWhileLoopIndex));
  4576.             return nextWhileLoopIndex++;
  4577.         }
  4578.        
  4579.         void WriteWhileLoopEndCheck(int loopIndex)
  4580.         {
  4581.             Writer.WriteLine(String.Format(CultureInfo.InvariantCulture, "CheckReaderCount(ref whileIterations{0}, ref readerCount{1});", loopIndex, loopIndex));
  4582.         }
  4583.        
  4584.         void WriteParamsRead(int length)
  4585.         {
  4586.             Writer.Write("bool[] paramsRead = new bool[");
  4587.             Writer.Write(length.ToString(CultureInfo.InvariantCulture));
  4588.             Writer.WriteLine("];");
  4589.         }
  4590.        
  4591.         void WriteReadNonRoots()
  4592.         {
  4593.             Writer.WriteLine("Reader.MoveToContent();");
  4594.             int loopIndex = WriteWhileLoopStartCheck();
  4595.             Writer.Write("while (Reader.NodeType == ");
  4596.             Writer.Write(typeof(XmlNodeType).FullName);
  4597.             Writer.WriteLine(".Element) {");
  4598.             Writer.Indent++;
  4599.             Writer.Write("string root = Reader.GetAttribute(\"root\", \"");
  4600.             Writer.Write(Soap.Encoding);
  4601.             Writer.WriteLine("\");");
  4602.             Writer.Write("if (root == null || ");
  4603.             Writer.Write(typeof(XmlConvert).FullName);
  4604.             Writer.WriteLine(".ToBoolean(root)) break;");
  4605.             Writer.WriteLine("ReadReferencedElement();");
  4606.             Writer.WriteLine("Reader.MoveToContent();");
  4607.             WriteWhileLoopEnd(loopIndex);
  4608.         }
  4609.        
  4610.         void WriteBooleanValue(bool value)
  4611.         {
  4612.             Writer.Write(value ? "true" : "false");
  4613.         }
  4614.        
  4615.         void WriteInitCheckTypeHrefList(string source)
  4616.         {
  4617.             Writer.Write(typeof(ArrayList).FullName);
  4618.             Writer.Write(" ");
  4619.             Writer.Write(source);
  4620.             Writer.Write(" = new ");
  4621.             Writer.Write(typeof(ArrayList).FullName);
  4622.             Writer.WriteLine("();");
  4623.            
  4624.             Writer.Write(typeof(ArrayList).FullName);
  4625.             Writer.Write(" ");
  4626.             Writer.Write(source);
  4627.             Writer.Write("IsObject = new ");
  4628.             Writer.Write(typeof(ArrayList).FullName);
  4629.             Writer.WriteLine("();");
  4630.         }
  4631.        
  4632.         void WriteHandleHrefList(Member[] members, string listSource)
  4633.         {
  4634.             Writer.WriteLine("int isObjectIndex = 0;");
  4635.             Writer.Write("foreach (object obj in ");
  4636.             Writer.Write(listSource);
  4637.             Writer.WriteLine(") {");
  4638.             Writer.Indent++;
  4639.             Writer.WriteLine("bool isReferenced = true;");
  4640.             Writer.Write("bool isObject = (bool)");
  4641.             Writer.Write(listSource);
  4642.             Writer.WriteLine("IsObject[isObjectIndex++];");
  4643.             Writer.WriteLine("object refObj = isObject ? obj : GetTarget((string)obj);");
  4644.             Writer.WriteLine("if (refObj == null) continue;");
  4645.             Writer.Write(typeof(Type).FullName);
  4646.             Writer.WriteLine(" refObjType = refObj.GetType();");
  4647.             Writer.WriteLine("string refObjId = null;");
  4648.            
  4649.             WriteMemberElementsIf(members, null, "isReferenced = false;", "refObj");
  4650.            
  4651.             Writer.WriteLine("if (isObject && isReferenced) Referenced(refObj); // need to mark this obj as ref'd since we didn't do GetTarget");
  4652.             Writer.Indent--;
  4653.             Writer.WriteLine("}");
  4654.         }
  4655.        
  4656.         void WriteIfNotSoapRoot(string source)
  4657.         {
  4658.             Writer.Write("if (Reader.GetAttribute(\"root\", \"");
  4659.             Writer.Write(Soap.Encoding);
  4660.             Writer.WriteLine("\") == \"0\") {");
  4661.             Writer.Indent++;
  4662.             Writer.WriteLine(source);
  4663.             Writer.Indent--;
  4664.             Writer.WriteLine("}");
  4665.         }
  4666.        
  4667.         void WriteCreateMapping(TypeMapping mapping, string local)
  4668.         {
  4669.             string fullTypeName = mapping.TypeDesc.CSharpName;
  4670.             bool useReflection = mapping.TypeDesc.UseReflection;
  4671.             bool ctorInaccessible = mapping.TypeDesc.CannotNew;
  4672.            
  4673.             Writer.Write(useReflection ? "object" : fullTypeName);
  4674.             Writer.Write(" ");
  4675.             Writer.Write(local);
  4676.             Writer.WriteLine(";");
  4677.            
  4678.             if (ctorInaccessible) {
  4679.                 Writer.WriteLine("try {");
  4680.                 Writer.Indent++;
  4681.             }
  4682.             Writer.Write(local);
  4683.             Writer.Write(" = ");
  4684.             Writer.Write(RaCodeGen.GetStringForCreateInstance(fullTypeName, useReflection, mapping.TypeDesc.CannotNew, true));
  4685.             Writer.WriteLine(";");
  4686.             if (ctorInaccessible) {
  4687.                 WriteCatchException(typeof(MissingMethodException));
  4688.                 Writer.Indent++;
  4689.                 Writer.Write("throw CreateInaccessibleConstructorException(");
  4690.                 WriteQuotedCSharpString(fullTypeName);
  4691.                 Writer.WriteLine(");");
  4692.                
  4693.                 WriteCatchException(typeof(SecurityException));
  4694.                 Writer.Indent++;
  4695.                
  4696.                 Writer.Write("throw CreateCtorHasSecurityException(");
  4697.                 WriteQuotedCSharpString(fullTypeName);
  4698.                 Writer.WriteLine(");");
  4699.                
  4700.                 Writer.Indent--;
  4701.                 Writer.WriteLine("}");
  4702.             }
  4703.         }
  4704.        
  4705.         void WriteCatchException(Type exceptionType)
  4706.         {
  4707.             Writer.Indent--;
  4708.             Writer.WriteLine("}");
  4709.             Writer.Write("catch (");
  4710.             Writer.Write(exceptionType.FullName);
  4711.             Writer.WriteLine(") {");
  4712.         }
  4713.        
  4714.         void WriteCatchCastException(TypeDesc typeDesc, string source, string id)
  4715.         {
  4716.             WriteCatchException(typeof(InvalidCastException));
  4717.             Writer.Indent++;
  4718.             Writer.Write("throw CreateInvalidCastException(");
  4719.             Writer.Write(RaCodeGen.GetStringForTypeof(typeDesc.CSharpName, typeDesc.UseReflection));
  4720.             Writer.Write(", ");
  4721.             Writer.Write(source);
  4722.             if (id == null)
  4723.                 Writer.WriteLine(", null);");
  4724.             else {
  4725.                 Writer.Write(", (string)");
  4726.                 Writer.Write(id);
  4727.                 Writer.WriteLine(");");
  4728.             }
  4729.             Writer.Indent--;
  4730.             Writer.WriteLine("}");
  4731.         }
  4732.         void WriteArrayLocalDecl(string typeName, string variableName, string initValue, TypeDesc arrayTypeDesc)
  4733.         {
  4734.             RaCodeGen.WriteArrayLocalDecl(typeName, variableName, initValue, arrayTypeDesc);
  4735.         }
  4736.         void WriteCreateInstance(string escapedName, string source, bool useReflection, bool ctorInaccessible)
  4737.         {
  4738.             RaCodeGen.WriteCreateInstance(escapedName, source, useReflection, ctorInaccessible);
  4739.         }
  4740.         void WriteLocalDecl(string typeFullName, string variableName, string initValue, bool useReflection)
  4741.         {
  4742.             RaCodeGen.WriteLocalDecl(typeFullName, variableName, initValue, useReflection);
  4743.         }
  4744.     }
  4745. }

Developer Fusion