CodeExporter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / Serialization / System / Runtime / Serialization / CodeExporter.cs / 1 / CodeExporter.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Runtime.Serialization 
{
    using System; 
    using System.ServiceModel; 
    using System.ComponentModel;
    using System.Xml; 
    using System.Xml.Schema;
    using System.Collections;
    using System.Collections.Generic;
    using System.Reflection; 
    using System.IO;
    using System.CodeDom; 
    using System.CodeDom.Compiler; 
    using System.Globalization;
    using System.Text; 
    using DataContractDictionary=System.Collections.Generic.Dictionary;
    using System.Security;

    internal class CodeExporter 
    {
        DataContractSet dataContractSet; 
        CodeCompileUnit codeCompileUnit; 
        ImportOptions options;
        Dictionary namespaces; 
        Dictionary clrNamespaces;
        /// 
        /// Review - Static fields are marked SecurityCritical or readonly to prevent
        ///          data from being modified or leaked to other components in appdomain. 
        /// 
        [SecurityRequiresReview] 
        static readonly string wildcardNamespaceMapping = "*"; 
        /// 
        /// Review - Static fields are marked SecurityCritical or readonly to prevent 
        ///          data from being modified or leaked to other components in appdomain.
        /// 
        [SecurityRequiresReview]
        static readonly string typeNameFieldName = "typeName"; 
        /// 
        /// Review - Static fields are marked SecurityCritical or readonly to prevent 
        ///          data from being modified or leaked to other components in appdomain. 
        /// 
        [SecurityRequiresReview] 
        static readonly object codeUserDataActualTypeKey = new object();
        /// 
        /// Review - Static fields are marked SecurityCritical or readonly to prevent
        ///          data from being modified or leaked to other components in appdomain. 
        /// 
        [SecurityRequiresReview] 
        static readonly object surrogateDataKey = typeof(IDataContractSurrogate); 
        const int MaxIdentifierLength = 511;
 
        internal CodeExporter(DataContractSet dataContractSet, ImportOptions options, CodeCompileUnit codeCompileUnit)
        {
            this.dataContractSet = dataContractSet;
            this.codeCompileUnit = codeCompileUnit; 
            AddReferencedAssembly(Assembly.GetExecutingAssembly());
            this.options = options; 
            this.namespaces = new Dictionary(); 
            this.clrNamespaces = new Dictionary(StringComparer.OrdinalIgnoreCase);
 
            // Update namespace tables for DataContract(s) that are already processed
            foreach (KeyValuePair pair in dataContractSet)
            {
                DataContract dataContract = pair.Value; 
                if (!(dataContract.IsBuiltInDataContract || dataContract is CollectionDataContract))
                { 
                    ContractCodeDomInfo contractCodeDomInfo = GetContractCodeDomInfo(dataContract); 
                    if (contractCodeDomInfo.IsProcessed && !contractCodeDomInfo.UsesWildcardNamespace)
                    { 
                        string clrNamespace = contractCodeDomInfo.ClrNamespace;
                        if (clrNamespace != null && !this.clrNamespaces.ContainsKey(clrNamespace))
                        {
                            this.clrNamespaces.Add(clrNamespace, dataContract.StableName.Namespace); 
                            this.namespaces.Add(dataContract.StableName.Namespace, clrNamespace);
                        } 
                    } 
                }
            } 

            // Copy options.Namespaces to namespace tables
            if (this.options != null)
            { 
                foreach (KeyValuePair pair in options.Namespaces)
                { 
                    string dataContractNamespace = pair.Key; 
                    string clrNamespace = pair.Value;
                    if (clrNamespace == null) 
                        clrNamespace = String.Empty;

                    string currentDataContractNamespace;
                    if (this.clrNamespaces.TryGetValue(clrNamespace, out currentDataContractNamespace)) 
                    {
                        if (dataContractNamespace != currentDataContractNamespace) 
                            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CLRNamespaceMappedMultipleTimes, currentDataContractNamespace, dataContractNamespace, clrNamespace))); 
                    }
                    else 
                        this.clrNamespaces.Add(clrNamespace, dataContractNamespace);

                    string currentClrNamespace;
                    if (this.namespaces.TryGetValue(dataContractNamespace, out currentClrNamespace)) 
                    {
                        if (clrNamespace != currentClrNamespace) 
                        { 
                            this.namespaces.Remove(dataContractNamespace);
                            this.namespaces.Add(dataContractNamespace, clrNamespace); 
                        }
                    }
                    else
                        this.namespaces.Add(dataContractNamespace, clrNamespace); 
                }
            } 
 
            // Update namespace tables for pre-existing namespaces in CodeCompileUnit
            foreach (CodeNamespace codeNS in codeCompileUnit.Namespaces) 
            {
                string ns = codeNS.Name ?? string.Empty;
                if (!this.clrNamespaces.ContainsKey(ns))
                { 
                    this.clrNamespaces.Add(ns, null);
                } 
                if (ns.Length == 0) 
                {
                    foreach (CodeTypeDeclaration codeTypeDecl in codeNS.Types) 
                    {
                        AddGlobalTypeName(codeTypeDecl.Name);
                    }
                } 
            }
 
        } 

        void AddReferencedAssembly(Assembly assembly) 
        {
            string assemblyName = System.IO.Path.GetFileName(assembly.Location);
            bool alreadyExisting = false;
            foreach (string existingName in this.codeCompileUnit.ReferencedAssemblies) 
            {
                if (String.Compare(existingName, assemblyName, StringComparison.OrdinalIgnoreCase) == 0) 
                { 
                    alreadyExisting = true;
                    break; 
                }
            }
            if (!alreadyExisting)
                this.codeCompileUnit.ReferencedAssemblies.Add(assemblyName); 

        } 
 
        bool GenerateSerializableTypes
        { 
            get { return (options == null) ? false : options.GenerateSerializable; }
        }

        bool GenerateInternalTypes 
        {
            get { return (options == null) ? false : options.GenerateInternal; } 
        } 

        bool EnableDataBinding 
        {
            get { return (options == null) ? false : options.EnableDataBinding; }
        }
 
        CodeDomProvider CodeProvider
        { 
            get { return (options == null) ? null : options.CodeProvider; } 
        }
 
        bool SupportsDeclareEvents
        {
            get { return (CodeProvider == null) ? true : CodeProvider.Supports(GeneratorSupport.DeclareEvents); }
        } 

        bool SupportsDeclareValueTypes 
        { 
            get { return (CodeProvider == null) ? true : CodeProvider.Supports(GeneratorSupport.DeclareValueTypes); }
        } 

        bool SupportsGenericTypeReference
        {
            get { return (CodeProvider == null) ? true : CodeProvider.Supports(GeneratorSupport.GenericTypeReference); } 
        }
 
        bool SupportsAssemblyAttributes 
        {
            get { return (CodeProvider == null) ? true : CodeProvider.Supports(GeneratorSupport.AssemblyAttributes); } 
        }

        bool SupportsPartialTypes
        { 
            get { return (CodeProvider == null) ? true : CodeProvider.Supports(GeneratorSupport.PartialTypes); }
        } 
 
        bool SupportsNestedTypes
        { 
            get { return (CodeProvider == null) ? true : CodeProvider.Supports(GeneratorSupport.NestedTypes); }
        }

        string FileExtension 
        {
            get { return (CodeProvider == null) ? String.Empty : CodeProvider.FileExtension; } 
        } 

        Dictionary Namespaces 
        {
            get { return namespaces; }
        }
 
        Dictionary ClrNamespaces
        { 
            get { return clrNamespaces; } 
        }
 

        bool TryGetReferencedType(XmlQualifiedName stableName, DataContract dataContract, out Type type)
        {
            if (dataContract == null) 
            {
                if (dataContractSet.TryGetReferencedCollectionType(stableName, dataContract, out type)) 
                    return true; 
                if (dataContractSet.TryGetReferencedType(stableName, dataContract, out type))
                { 
                    // enforce that collection types only be specified via ReferencedCollectionTypes
                    if (CollectionDataContract.IsCollection(type))
                    {
                        type = null; 
                        return false;
                    } 
                    return true; 
                }
                return false; 
            }
            else if (dataContract is CollectionDataContract)
                return dataContractSet.TryGetReferencedCollectionType(stableName, dataContract, out type);
            else 
            {
                XmlDataContract xmlDataContract = dataContract as XmlDataContract; 
                if (xmlDataContract != null && xmlDataContract.IsAnonymous) 
                {
                    stableName = SchemaImporter.ImportActualType(xmlDataContract.XsdType.Annotation, stableName, dataContract.StableName); 
                }
                return dataContractSet.TryGetReferencedType(stableName, dataContract, out type);
            }
        } 

 
        internal void Export() 
        {
            try 
            {
                foreach (KeyValuePair pair in dataContractSet)
                {
                    DataContract dataContract = pair.Value; 
                    if (dataContract.IsBuiltInDataContract)
                        continue; 
 
                    ContractCodeDomInfo contractCodeDomInfo = GetContractCodeDomInfo(dataContract);
                    if (!contractCodeDomInfo.IsProcessed) 
                    {
                        if (dataContract is ClassDataContract)
                        {
                            ClassDataContract classDataContract = (ClassDataContract)dataContract; 
                            if (classDataContract.IsISerializable)
                                ExportISerializableDataContract(classDataContract, contractCodeDomInfo); 
                            else 
                                ExportClassDataContractHierarchy(classDataContract.StableName, classDataContract, contractCodeDomInfo, new Dictionary());
                        } 
                        else if (dataContract is CollectionDataContract)
                            ExportCollectionDataContract((CollectionDataContract)dataContract, contractCodeDomInfo);
                        else if (dataContract is EnumDataContract)
                            ExportEnumDataContract((EnumDataContract)dataContract, contractCodeDomInfo); 
                        else if (dataContract is XmlDataContract)
                            ExportXmlDataContract((XmlDataContract)dataContract, contractCodeDomInfo); 
                        else 
                            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.UnexpectedContractType, DataContract.GetClrTypeFullName(dataContract.GetType()), DataContract.GetClrTypeFullName(dataContract.UnderlyingType))));
                        contractCodeDomInfo.IsProcessed = true; 
                    }
                }
                if (dataContractSet.DataContractSurrogate != null)
                { 
                    CodeNamespace[] namespaces = new CodeNamespace[codeCompileUnit.Namespaces.Count];
                    codeCompileUnit.Namespaces.CopyTo(namespaces, 0); 
                    foreach (CodeNamespace codeNamespace in namespaces) 
                        InvokeProcessImportedType(codeNamespace.Types);
                } 
            }
            finally
            {
                System.CodeDom.Compiler.CodeGenerator.ValidateIdentifiers(codeCompileUnit); 
            }
        } 
 
        void ExportClassDataContractHierarchy(XmlQualifiedName typeName, ClassDataContract classContract, ContractCodeDomInfo contractCodeDomInfo, Dictionary contractNamesInHierarchy)
        { 
            if (contractNamesInHierarchy.ContainsKey(classContract.StableName))
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.TypeCannotBeImported, typeName.Name, typeName.Namespace, SR.GetString(SR.CircularTypeReference, classContract.StableName.Name, classContract.StableName.Namespace))));
            contractNamesInHierarchy.Add(classContract.StableName, null);
 
            ClassDataContract baseContract = classContract.BaseContract;
            if (baseContract != null) 
            { 
                ContractCodeDomInfo baseContractCodeDomInfo = GetContractCodeDomInfo(baseContract);
                if (!baseContractCodeDomInfo.IsProcessed) 
                {
                    ExportClassDataContractHierarchy(typeName, baseContract, baseContractCodeDomInfo, contractNamesInHierarchy);
                    baseContractCodeDomInfo.IsProcessed = true;
                } 
            }
            ExportClassDataContract(classContract, contractCodeDomInfo); 
        } 

        void InvokeProcessImportedType(CollectionBase collection) 
        {
            object[] objects = new object[collection.Count];
            ((ICollection)collection).CopyTo(objects, 0);
            foreach (object obj in objects) 
            {
                CodeTypeDeclaration codeTypeDeclaration = obj as CodeTypeDeclaration; 
                if (codeTypeDeclaration == null) 
                    continue;
 
                CodeTypeDeclaration newCodeTypeDeclaration = DataContractSurrogateCaller.ProcessImportedType(
                                                                   dataContractSet.DataContractSurrogate,
                                                                   codeTypeDeclaration,
                                                                   codeCompileUnit); 
                if (newCodeTypeDeclaration != codeTypeDeclaration)
                { 
                    ((IList)collection).Remove(codeTypeDeclaration); 
                    if (newCodeTypeDeclaration != null)
                        ((IList)collection).Add(newCodeTypeDeclaration); 
                }
                if(newCodeTypeDeclaration != null)
                    InvokeProcessImportedType(newCodeTypeDeclaration.Members);
            } 
        }
 
        internal CodeTypeReference GetCodeTypeReference(DataContract dataContract) 
        {
            if (dataContract.IsBuiltInDataContract) 
                return GetCodeTypeReference(dataContract.UnderlyingType);

            ContractCodeDomInfo contractCodeDomInfo = GetContractCodeDomInfo(dataContract);
            GenerateType(dataContract, contractCodeDomInfo); 
            return contractCodeDomInfo.TypeReference;
        } 
 
        CodeTypeReference GetCodeTypeReference(Type type)
        { 
            AddReferencedAssembly(type.Assembly);
            return new CodeTypeReference(type);
        }
 
        internal CodeTypeReference GetElementTypeReference(DataContract dataContract, bool isElementTypeNullable)
        { 
            CodeTypeReference elementTypeReference = GetCodeTypeReference(dataContract); 
            if (dataContract.IsValueType && isElementTypeNullable)
                elementTypeReference = WrapNullable(elementTypeReference); 
            return elementTypeReference;
        }

        XmlQualifiedName GenericListName 
        {
            get { return DataContract.GetStableName(Globals.TypeOfListGeneric); } 
        } 

        CollectionDataContract GenericListContract 
        {
            get { return dataContractSet.GetDataContract(Globals.TypeOfListGeneric) as CollectionDataContract; }
        }
 
        XmlQualifiedName GenericDictionaryName
        { 
            get { return DataContract.GetStableName(Globals.TypeOfDictionaryGeneric); } 
        }
 
        CollectionDataContract GenericDictionaryContract
        {
            get { return dataContractSet.GetDataContract(Globals.TypeOfDictionaryGeneric) as CollectionDataContract; }
        } 

        ContractCodeDomInfo GetContractCodeDomInfo(DataContract dataContract) 
        { 
            ContractCodeDomInfo contractCodeDomInfo = dataContractSet.GetContractCodeDomInfo(dataContract);
            if (contractCodeDomInfo == null) 
            {
                contractCodeDomInfo = new ContractCodeDomInfo();
                dataContractSet.SetContractCodeDomInfo(dataContract, contractCodeDomInfo);
            } 
            return contractCodeDomInfo;
        } 
 
        void GenerateType(DataContract dataContract, ContractCodeDomInfo contractCodeDomInfo)
        { 
            if (!contractCodeDomInfo.IsProcessed)
            {
                CodeTypeReference referencedType = GetReferencedType(dataContract);
                if (referencedType != null) 
                {
                    contractCodeDomInfo.TypeReference = referencedType; 
                    contractCodeDomInfo.ReferencedTypeExists = true; 
                }
                else 
                {
                    CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration;
                    if (type == null)
                    { 
                        string clrNamespace = GetClrNamespace(dataContract, contractCodeDomInfo);
                        CodeNamespace ns = GetCodeNamespace(clrNamespace, dataContract.StableName.Namespace, contractCodeDomInfo); 
                        type = GetNestedType(dataContract, contractCodeDomInfo); 
                        if (type == null)
                        { 
                            string typeName = XmlConvert.DecodeName(dataContract.StableName.Name);
                            typeName = GetClrIdentifier(typeName, Globals.DefaultTypeName);
                            if (NamespaceContainsType(ns, typeName) || GlobalTypeNameConflicts(clrNamespace, typeName))
                            { 
                                for (int i = 1; ; i++)
                                { 
                                    string uniqueName = AppendToValidClrIdentifier(typeName, i.ToString(NumberFormatInfo.InvariantInfo)); 
                                    if (!NamespaceContainsType(ns, uniqueName) && !GlobalTypeNameConflicts(clrNamespace, uniqueName))
                                    { 
                                        typeName = uniqueName;
                                         break;
                                    }
                                    if(i == Int32.MaxValue) 
                                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CannotComputeUniqueName, typeName)));
                                } 
                            } 

                            type = CreateTypeDeclaration(typeName, dataContract); 
                            ns.Types.Add(type);
                            if (string.IsNullOrEmpty(clrNamespace))
                            {
                                AddGlobalTypeName(typeName); 
                            }
                            contractCodeDomInfo.TypeReference = new CodeTypeReference((clrNamespace == null || clrNamespace.Length == 0) ? typeName : clrNamespace+"."+typeName); 
 
                            if (GenerateInternalTypes)
                                type.TypeAttributes = TypeAttributes.NotPublic; 
                            else
                                type.TypeAttributes = TypeAttributes.Public;
                        }
                        if (dataContractSet.DataContractSurrogate != null) 
                            type.UserData.Add(surrogateDataKey, dataContractSet.GetSurrogateData(dataContract));
 
                        contractCodeDomInfo.TypeDeclaration = type; 
                    }
                } 
            }
        }

        CodeTypeDeclaration GetNestedType(DataContract dataContract, ContractCodeDomInfo contractCodeDomInfo) 
        {
            if (!SupportsNestedTypes) 
                return null; 
            string originalName = dataContract.StableName.Name;
            int nestedTypeIndex = originalName.LastIndexOf('.'); 
            if (nestedTypeIndex <= 0)
                return null;
            string containingTypeName = originalName.Substring(0, nestedTypeIndex);
            DataContract containingDataContract = dataContractSet[new XmlQualifiedName(containingTypeName, dataContract.StableName.Namespace)]; 
            if (containingDataContract == null)
                return null; 
            string nestedTypeName = XmlConvert.DecodeName(originalName.Substring(nestedTypeIndex+1)); 
            nestedTypeName = GetClrIdentifier(nestedTypeName, Globals.DefaultTypeName);
 
            ContractCodeDomInfo containingContractCodeDomInfo = GetContractCodeDomInfo(containingDataContract);
            GenerateType(containingDataContract, containingContractCodeDomInfo);
            if (containingContractCodeDomInfo.ReferencedTypeExists)
                return null; 

            CodeTypeDeclaration containingType = containingContractCodeDomInfo.TypeDeclaration; 
            if (TypeContainsNestedType(containingType, nestedTypeName)) 
            {
                for (int i = 1; ; i++) 
                {
                    string uniqueName = AppendToValidClrIdentifier(nestedTypeName, i.ToString(NumberFormatInfo.InvariantInfo));
                    if (!TypeContainsNestedType(containingType, uniqueName))
                    { 
                        nestedTypeName = uniqueName;
                        break; 
                    } 
                }
            } 

            CodeTypeDeclaration type = CreateTypeDeclaration(nestedTypeName, dataContract);
            containingType.Members.Add(type);
            contractCodeDomInfo.TypeReference = new CodeTypeReference(containingContractCodeDomInfo.TypeReference.BaseType + "+" + nestedTypeName); 

            if (GenerateInternalTypes) 
                type.TypeAttributes = TypeAttributes.NestedAssembly; 
            else
                type.TypeAttributes = TypeAttributes.NestedPublic; 
            return type;
        }

        static CodeTypeDeclaration CreateTypeDeclaration(string typeName, DataContract dataContract) 
        {
            CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(typeName); 
            CodeAttributeDeclaration debuggerStepThroughAttribute = new CodeAttributeDeclaration(typeof(System.Diagnostics.DebuggerStepThroughAttribute).FullName); 
            CodeAttributeDeclaration generatedCodeAttribute = new CodeAttributeDeclaration(typeof(GeneratedCodeAttribute).FullName);
 
            AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName();
            generatedCodeAttribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(assemblyName.Name)));
            generatedCodeAttribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(assemblyName.Version.ToString())));
 
            // System.Diagnostics.DebuggerStepThroughAttribute not allowed on enums
            // ensure that the attribute is only generated on types that are not enums 
            EnumDataContract enumDataContract = dataContract as EnumDataContract; 
            if (enumDataContract == null)
            { 
                typeDecl.CustomAttributes.Add(debuggerStepThroughAttribute);
            }
            typeDecl.CustomAttributes.Add(generatedCodeAttribute);
            return typeDecl; 
        }
 
        ///  
        /// Critical - sets critical properties on internal XmlDataContract
        /// Safe - called during schema import/code generation 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        CodeTypeReference GetReferencedType(DataContract dataContract)
        { 
            Type type = null;
            CodeTypeReference typeReference = GetSurrogatedTypeReference(dataContract); 
            if(typeReference != null) 
                return typeReference;
 
            if (TryGetReferencedType(dataContract.StableName, dataContract, out type)
                && !type.IsGenericTypeDefinition && !type.ContainsGenericParameters)
            {
                if (dataContract is XmlDataContract) 
                {
                    if (Globals.TypeOfIXmlSerializable.IsAssignableFrom(type)) 
                    { 
                        XmlDataContract xmlContract = (XmlDataContract)dataContract;
                        if(xmlContract.IsTypeDefinedOnImport) 
                        {
                            if(!xmlContract.Equals(dataContractSet.GetDataContract(type)))
                                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ReferencedTypeDoesNotMatch, type.AssemblyQualifiedName, dataContract.StableName.Name, dataContract.StableName.Namespace)));
                        } 
                        else
                        { 
                            xmlContract.IsValueType = type.IsValueType; 
                            xmlContract.IsTypeDefinedOnImport = true;
                        } 
                        return GetCodeTypeReference(type);
                    }
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.TypeMustBeIXmlSerializable, DataContract.GetClrTypeFullName(type), DataContract.GetClrTypeFullName(Globals.TypeOfIXmlSerializable), dataContract.StableName.Name, dataContract.StableName.Namespace)));
                } 
                DataContract referencedContract = dataContractSet.GetDataContract(type);
                if (referencedContract.Equals(dataContract)) 
                { 
                    typeReference =  GetCodeTypeReference(type);
                    typeReference.UserData.Add(codeUserDataActualTypeKey, type); 
                    return typeReference;
                }
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ReferencedTypeDoesNotMatch, type.AssemblyQualifiedName, dataContract.StableName.Name, dataContract.StableName.Namespace)));
            } 
            else if (dataContract.GenericInfo != null)
            { 
                DataContract referencedContract; 
                XmlQualifiedName genericStableName = dataContract.GenericInfo.GetExpandedStableName();
                if(genericStableName != dataContract.StableName) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericTypeNameMismatch, dataContract.StableName.Name, dataContract.StableName.Namespace, genericStableName.Name, genericStableName.Namespace)));

                typeReference = GetReferencedGenericType(dataContract.GenericInfo, out referencedContract);
                if (referencedContract != null && !referencedContract.Equals(dataContract)) 
                {
                    type = (Type)typeReference.UserData[codeUserDataActualTypeKey]; 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ReferencedTypeDoesNotMatch, 
 						type.AssemblyQualifiedName,
						referencedContract.StableName.Name, 
						referencedContract.StableName.Namespace)));
                }
                return typeReference;
            } 

            return GetReferencedCollectionType(dataContract as CollectionDataContract); 
        } 

        CodeTypeReference GetReferencedCollectionType(CollectionDataContract collectionContract) 
        {
            if (collectionContract == null)
                return null;
 
            if (HasDefaultCollectionNames(collectionContract))
            { 
                CodeTypeReference typeReference; 
                if (!TryGetReferencedDictionaryType(collectionContract, out typeReference))
                { 
                    DataContract itemContract = collectionContract.ItemContract;
                    if (collectionContract.IsDictionary)
                    {
                        GenerateKeyValueType(itemContract as ClassDataContract); 
                    }
                    bool isItemTypeNullable = collectionContract.IsItemTypeNullable; 
                    if (!TryGetReferencedListType(itemContract, isItemTypeNullable, out typeReference)) 
                        typeReference = new CodeTypeReference(GetElementTypeReference(itemContract, isItemTypeNullable), 1);
                } 
                return typeReference;
            }
            return null;
        } 

        bool HasDefaultCollectionNames(CollectionDataContract collectionContract) 
        { 
            DataContract itemContract = collectionContract.ItemContract;
            if (collectionContract.ItemName != itemContract.StableName.Name) 
                return false;

            if (collectionContract.IsDictionary &&
                (collectionContract.KeyName != Globals.KeyLocalName || collectionContract.ValueName != Globals.ValueLocalName)) 
                return false;
 
            XmlQualifiedName expectedType = itemContract.GetArrayTypeName(collectionContract.IsItemTypeNullable); 
            return (collectionContract.StableName.Name == expectedType.Name && collectionContract.StableName.Namespace == expectedType.Namespace);
        } 

        bool TryGetReferencedDictionaryType(CollectionDataContract collectionContract, out CodeTypeReference typeReference)
        {
            // Check if it is a dictionary and use referenced dictionary type if present 
            if (collectionContract.IsDictionary
                && SupportsGenericTypeReference) 
            { 
                Type type;
                if (!TryGetReferencedType(GenericDictionaryName, GenericDictionaryContract, out type)) 
                    type = Globals.TypeOfDictionaryGeneric;
                ClassDataContract itemContract = collectionContract.ItemContract as ClassDataContract;
                DataMember keyMember = itemContract.Members[0];
                DataMember valueMember = itemContract.Members[1]; 
                CodeTypeReference keyTypeReference = GetElementTypeReference(keyMember.MemberTypeContract, keyMember.IsNullable);
                CodeTypeReference valueTypeReference = GetElementTypeReference(valueMember.MemberTypeContract, valueMember.IsNullable); 
                if (keyTypeReference != null && valueTypeReference != null) 
                {
                    typeReference = GetCodeTypeReference(type); 
                    typeReference.TypeArguments.Add(keyTypeReference);
                    typeReference.TypeArguments.Add(valueTypeReference);
                    return true;
                } 
            }
            typeReference = null; 
            return false; 
        }
 
        bool TryGetReferencedListType(DataContract itemContract, bool isItemTypeNullable, out CodeTypeReference typeReference)
        {
            Type type;
            if (SupportsGenericTypeReference && TryGetReferencedType(GenericListName, GenericListContract, out type)) 
            {
                typeReference = GetCodeTypeReference(type); 
                typeReference.TypeArguments.Add(GetElementTypeReference(itemContract, isItemTypeNullable)); 
                return true;
            } 
            typeReference = null;
            return false;
        }
 
        CodeTypeReference GetSurrogatedTypeReference(DataContract dataContract)
        { 
            IDataContractSurrogate dataContractSurrogate = this.dataContractSet.DataContractSurrogate; 
            if (dataContractSurrogate != null)
            { 
                Type type = DataContractSurrogateCaller.GetReferencedTypeOnImport(
                        dataContractSurrogate,
                        dataContract.StableName.Name,
                        dataContract.StableName.Namespace, 
                        dataContractSet.GetSurrogateData(dataContract));
                if (type != null) 
                { 
                    CodeTypeReference typeReference =  GetCodeTypeReference(type);
                    typeReference.UserData.Add(codeUserDataActualTypeKey, type); 
                    return typeReference;
                }
            }
            return null; 
        }
 
        CodeTypeReference GetReferencedGenericType(GenericInfo genInfo, out DataContract dataContract) 
        {
            dataContract = null; 

            if (!SupportsGenericTypeReference)
                return null;
 
            Type type;
            if (!TryGetReferencedType(genInfo.StableName, null, out type)) 
            { 
                if(genInfo.Parameters != null)
                    return null; 
                dataContract = dataContractSet[genInfo.StableName];
                if (dataContract == null)
                    return null;
                if (dataContract.GenericInfo != null) 
                    return null;
                return GetCodeTypeReference(dataContract); 
            } 

            bool enableStructureCheck = (type != Globals.TypeOfNullable); 
            CodeTypeReference typeReference = GetCodeTypeReference(type);
            typeReference.UserData.Add(codeUserDataActualTypeKey, type);
            if (genInfo.Parameters != null)
            { 
                DataContract[] paramContracts = new DataContract[genInfo.Parameters.Count];
                for(int i=0;i());
            } 
            return typeReference;
        }

        bool NamespaceContainsType(CodeNamespace ns, string typeName) 
        {
            foreach (CodeTypeDeclaration type in ns.Types) 
            { 
                if (String.Compare(typeName, type.Name, StringComparison.OrdinalIgnoreCase) == 0)
                    return true; 
            }
            return false;
        }
 
        bool GlobalTypeNameConflicts(string clrNamespace, string typeName)
        { 
            return (string.IsNullOrEmpty(clrNamespace) && this.clrNamespaces.ContainsKey(typeName)); 
        }
 
        void AddGlobalTypeName(string typeName)
        {
            if (!this.clrNamespaces.ContainsKey(typeName))
            { 
                this.clrNamespaces.Add(typeName, null);
            } 
        } 

        bool TypeContainsNestedType(CodeTypeDeclaration containingType, string typeName) 
        {
            foreach (CodeTypeMember member in containingType.Members)
            {
                if (member is CodeTypeDeclaration) 
                {
                    if (String.Compare(typeName, ((CodeTypeDeclaration)member).Name, StringComparison.OrdinalIgnoreCase) == 0) 
                        return true; 
                }
            } 
            return false;
        }

        string GetNameForAttribute(string name) 
        {
            string decodedName = XmlConvert.DecodeName(name); 
            if (string.CompareOrdinal(name, decodedName) == 0) 
                return name;
            string reencodedName = DataContract.EncodeLocalName(decodedName); 
            return (string.CompareOrdinal(name, reencodedName) == 0) ? decodedName : name;
        }

        void AddSerializableAttribute(bool generateSerializable, CodeTypeDeclaration type, ContractCodeDomInfo contractCodeDomInfo) 
        {
            if (generateSerializable) 
            { 
                type.CustomAttributes.Add(SerializableAttribute);
                AddImportStatement(Globals.TypeOfSerializableAttribute.Namespace, contractCodeDomInfo.CodeNamespace); 
            }
        }

        void ExportClassDataContract(ClassDataContract classDataContract, ContractCodeDomInfo contractCodeDomInfo) 
        {
            GenerateType(classDataContract, contractCodeDomInfo); 
            if (contractCodeDomInfo.ReferencedTypeExists) 
                return;
 
            CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration;
            if (SupportsPartialTypes)
                type.IsPartial = true;
            if (classDataContract.IsValueType && SupportsDeclareValueTypes) 
                type.IsStruct = true;
            else 
                type.IsClass = true; 

            string dataContractName = GetNameForAttribute(classDataContract.StableName.Name); 
            CodeAttributeDeclaration dataContractAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfDataContractAttribute));
            dataContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NameProperty, new CodePrimitiveExpression(dataContractName)));
            dataContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NamespaceProperty, new CodePrimitiveExpression(classDataContract.StableName.Namespace)));
            if (classDataContract.IsReference != Globals.DefaultIsReference) 
                dataContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.IsReferenceProperty, new CodePrimitiveExpression(classDataContract.IsReference)));
            type.CustomAttributes.Add(dataContractAttribute); 
            AddImportStatement(Globals.TypeOfDataContractAttribute.Namespace, contractCodeDomInfo.CodeNamespace); 

            AddSerializableAttribute(GenerateSerializableTypes, type, contractCodeDomInfo); 

            AddKnownTypes(classDataContract, contractCodeDomInfo);

            if (classDataContract.BaseContract == null) 
            {
                if (!type.IsStruct) 
                    type.BaseTypes.Add(Globals.TypeOfObject); 
                AddExtensionData(contractCodeDomInfo);
                AddPropertyChangedNotifier(contractCodeDomInfo, type.IsStruct); 
            }
            else
            {
                ContractCodeDomInfo baseContractCodeDomInfo = GetContractCodeDomInfo(classDataContract.BaseContract); 
                if (!(baseContractCodeDomInfo.IsProcessed))
                { 
                    DiagnosticUtility.DebugAssert("Cannot generate code for type if code for base type has not been generated"); 
                }
                type.BaseTypes.Add(baseContractCodeDomInfo.TypeReference); 
                AddBaseMemberNames(baseContractCodeDomInfo, contractCodeDomInfo);
                if (baseContractCodeDomInfo.ReferencedTypeExists)
                {
                    Type actualType = (Type)baseContractCodeDomInfo.TypeReference.UserData[codeUserDataActualTypeKey]; 
                    ThrowIfReferencedBaseTypeSealed(actualType, classDataContract);
                    if(!Globals.TypeOfIExtensibleDataObject.IsAssignableFrom(actualType)) 
                        AddExtensionData(contractCodeDomInfo); 
                    AddPropertyChangedNotifier(contractCodeDomInfo, type.IsStruct);
                } 
            }

            if (classDataContract.Members != null)
            { 
                for (int i=0; i < classDataContract.Members.Count; i++)
                { 
                    DataMember dataMember = classDataContract.Members[i]; 

                    CodeTypeReference memberType = GetElementTypeReference(dataMember.MemberTypeContract, 
                        (dataMember.IsNullable && dataMember.MemberTypeContract.IsValueType));

                    string dataMemberName = GetNameForAttribute(dataMember.Name);
                    string propertyName = GetMemberName(dataMemberName, contractCodeDomInfo); 
                    string fieldName = GetMemberName(AppendToValidClrIdentifier(propertyName, Globals.DefaultFieldSuffix), contractCodeDomInfo);
 
                    CodeMemberField field = new CodeMemberField(); 
                    field.Type = memberType;
                    field.Name = fieldName; 
                    field.Attributes = MemberAttributes.Private;

                    CodeMemberProperty property = CreateProperty(memberType, propertyName, fieldName, dataMember.MemberTypeContract.IsValueType && SupportsDeclareValueTypes);
                    if (dataContractSet.DataContractSurrogate != null) 
                        property.UserData.Add(surrogateDataKey, dataContractSet.GetSurrogateData(dataMember));
 
                    CodeAttributeDeclaration dataMemberAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfDataMemberAttribute)); 
                    if (dataMemberName != property.Name)
                        dataMemberAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NameProperty, new CodePrimitiveExpression(dataMemberName))); 
                    if (dataMember.IsRequired != Globals.DefaultIsRequired)
                        dataMemberAttribute.Arguments.Add(new CodeAttributeArgument(Globals.IsRequiredProperty, new CodePrimitiveExpression(dataMember.IsRequired)));
                    if (dataMember.EmitDefaultValue!= Globals.DefaultEmitDefaultValue)
                        dataMemberAttribute.Arguments.Add(new CodeAttributeArgument(Globals.EmitDefaultValueProperty, new CodePrimitiveExpression(dataMember.EmitDefaultValue))); 
                    if (dataMember.Order != Globals.DefaultOrder)
                        dataMemberAttribute.Arguments.Add(new CodeAttributeArgument(Globals.OrderProperty, new CodePrimitiveExpression(dataMember.Order))); 
                    property.CustomAttributes.Add(dataMemberAttribute); 

                    if (GenerateSerializableTypes && !dataMember.IsRequired) 
                    {
                        CodeAttributeDeclaration optionalFieldAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfOptionalFieldAttribute));
                        field.CustomAttributes.Add(optionalFieldAttribute);
                    } 

                    type.Members.Add(field); 
                    type.Members.Add(property); 
                }
            } 
        }

        bool CanDeclareAssemblyAttribute(ContractCodeDomInfo contractCodeDomInfo)
        { 
            return SupportsAssemblyAttributes && !contractCodeDomInfo.UsesWildcardNamespace;
        } 
 
        bool NeedsExplicitNamespace(string dataContractNamespace, string clrNamespace)
        { 
            return (DataContract.GetDefaultStableNamespace(clrNamespace) != dataContractNamespace);
        }

        internal ICollection GetKnownTypeReferences(DataContract dataContract) 
        {
            DataContractDictionary knownTypeDictionary = GetKnownTypeContracts(dataContract); 
            if (knownTypeDictionary == null) 
                return null;
 
            ICollection knownTypeContracts = knownTypeDictionary.Values;
            if (knownTypeContracts == null || knownTypeContracts.Count == 0)
                return null;
 
            List knownTypeReferences = new List();
            foreach (DataContract knownTypeContract in knownTypeContracts) 
            { 
                knownTypeReferences.Add(GetCodeTypeReference(knownTypeContract));
            } 
            return knownTypeReferences;
        }

        DataContractDictionary GetKnownTypeContracts(DataContract dataContract) 
        {
            if (dataContractSet.KnownTypesForObject != null && SchemaImporter.IsObjectContract(dataContract)) 
            { 
                return dataContractSet.KnownTypesForObject;
            } 
            else if (dataContract is ClassDataContract)
            {
                ContractCodeDomInfo contractCodeDomInfo = GetContractCodeDomInfo(dataContract);
                if (!contractCodeDomInfo.IsProcessed) 
                    GenerateType(dataContract, contractCodeDomInfo);
                if (contractCodeDomInfo.ReferencedTypeExists) 
                    return GetKnownTypeContracts((ClassDataContract)dataContract, new Dictionary()); 
            }
            return null; 
        }

        DataContractDictionary GetKnownTypeContracts(ClassDataContract dataContract, Dictionary handledContracts)
        { 
            if (handledContracts.ContainsKey(dataContract))
                return dataContract.KnownDataContracts; 
 
            handledContracts.Add(dataContract, null);
            if (dataContract.Members != null) 
            {
                bool objectMemberHandled = false;
                foreach (DataMember dataMember in dataContract.Members)
                { 
                    DataContract memberContract = dataMember.MemberTypeContract;
                    if (!objectMemberHandled && dataContractSet.KnownTypesForObject != null && SchemaImporter.IsObjectContract(memberContract)) 
                    { 
                        AddKnownTypeContracts(dataContract, dataContractSet.KnownTypesForObject);
                        objectMemberHandled = true; 
                    }
                    else if (memberContract is ClassDataContract)
                    {
                        ContractCodeDomInfo memberCodeDomInfo = GetContractCodeDomInfo(memberContract); 
                        if (!memberCodeDomInfo.IsProcessed)
                            GenerateType(memberContract, memberCodeDomInfo); 
                        if (memberCodeDomInfo.ReferencedTypeExists) 
                        {
                            AddKnownTypeContracts(dataContract, GetKnownTypeContracts((ClassDataContract)memberContract, handledContracts)); 
                        }
                    }
                }
            } 

            return dataContract.KnownDataContracts; 
        } 

        ///  
        /// Critical - sets critical properties on internal DataContract
        /// Safe - called during schema import/code generation
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        void AddKnownTypeContracts(ClassDataContract dataContract, DataContractDictionary knownContracts)
        { 
            if (knownContracts == null || knownContracts.Count == 0) 
                return;
 
            if (dataContract.KnownDataContracts == null)
                dataContract.KnownDataContracts = new DataContractDictionary();

            foreach (KeyValuePair pair in knownContracts) 
            {
                if (dataContract.StableName != pair.Key && !dataContract.KnownDataContracts.ContainsKey(pair.Key) && !pair.Value.IsBuiltInDataContract) 
                    dataContract.KnownDataContracts.Add(pair.Key, pair.Value); 
            }
        } 

        void AddKnownTypes(ClassDataContract dataContract, ContractCodeDomInfo contractCodeDomInfo)
        {
            DataContractDictionary knownContractDictionary = GetKnownTypeContracts(dataContract, new Dictionary()); 
            if (knownContractDictionary == null || knownContractDictionary.Count == 0)
                return; 
 
            ICollection knownTypeContracts = knownContractDictionary.Values;
            foreach (DataContract knownTypeContract in knownTypeContracts) 
            {
                CodeAttributeDeclaration knownTypeAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfKnownTypeAttribute));
                knownTypeAttribute.Arguments.Add(new CodeAttributeArgument(new CodeTypeOfExpression(GetCodeTypeReference(knownTypeContract))));
                contractCodeDomInfo.TypeDeclaration.CustomAttributes.Add(knownTypeAttribute); 
            }
            AddImportStatement(Globals.TypeOfKnownTypeAttribute.Namespace, contractCodeDomInfo.CodeNamespace); 
        } 

        CodeTypeReference WrapNullable(CodeTypeReference memberType) 
        {
            if (!SupportsGenericTypeReference)
                return memberType;
 
            CodeTypeReference nullableOfMemberType = GetCodeTypeReference(Globals.TypeOfNullable);
            nullableOfMemberType.TypeArguments.Add(memberType); 
            return nullableOfMemberType; 
        }
 
        void AddExtensionData(ContractCodeDomInfo contractCodeDomInfo)
        {
            if(contractCodeDomInfo != null && contractCodeDomInfo.TypeDeclaration != null)
            { 
                CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration;
                type.BaseTypes.Add(DataContract.GetClrTypeFullName(Globals.TypeOfIExtensibleDataObject)); 
                CodeMemberField extensionDataObjectField = ExtensionDataObjectField; 
                if (GenerateSerializableTypes)
                { 
                    CodeAttributeDeclaration nonSerializedAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfNonSerializedAttribute));
                    extensionDataObjectField.CustomAttributes.Add(nonSerializedAttribute);
                }
                type.Members.Add(extensionDataObjectField); 
                contractCodeDomInfo.GetMemberNames().Add(extensionDataObjectField.Name, null);
                CodeMemberProperty extensionDataObjectProperty = ExtensionDataObjectProperty; 
                type.Members.Add(extensionDataObjectProperty); 
                contractCodeDomInfo.GetMemberNames().Add(extensionDataObjectProperty.Name, null);
            } 
        }

        void AddPropertyChangedNotifier(ContractCodeDomInfo contractCodeDomInfo, bool isValueType)
        { 
            if(EnableDataBinding && SupportsDeclareEvents && contractCodeDomInfo != null && contractCodeDomInfo.TypeDeclaration != null)
            { 
                CodeTypeDeclaration codeTypeDeclaration = contractCodeDomInfo.TypeDeclaration; 
                codeTypeDeclaration.BaseTypes.Add(CodeTypeIPropertyChange);
                CodeMemberEvent memberEvent = PropertyChangedEvent; 
                codeTypeDeclaration.Members.Add(memberEvent);
                CodeMemberMethod raisePropertyChangedEventMethod = RaisePropertyChangedEventMethod;
                if (!isValueType)
                    raisePropertyChangedEventMethod.Attributes |= MemberAttributes.Family; 
                codeTypeDeclaration.Members.Add(raisePropertyChangedEventMethod);
                contractCodeDomInfo.GetMemberNames().Add(memberEvent.Name, null); 
                contractCodeDomInfo.GetMemberNames().Add(raisePropertyChangedEventMethod.Name, null); 
            }
        } 

        void ThrowIfReferencedBaseTypeSealed(Type baseType, DataContract dataContract)
        {
            if (baseType.IsSealed) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CannotDeriveFromSealedReferenceType, dataContract.StableName.Name, dataContract.StableName.Namespace, DataContract.GetClrTypeFullName(baseType))));
        } 
 
        void ExportEnumDataContract(EnumDataContract enumDataContract, ContractCodeDomInfo contractCodeDomInfo)
        { 
            GenerateType(enumDataContract, contractCodeDomInfo);
            if (contractCodeDomInfo.ReferencedTypeExists)
                return;
 
            CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration;
            type.IsEnum = true; 
            type.BaseTypes.Add(EnumDataContract.GetBaseType(enumDataContract.BaseContractName)); 
            if (enumDataContract.IsFlags)
            { 
                type.CustomAttributes.Add(new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfFlagsAttribute)));
                AddImportStatement(Globals.TypeOfFlagsAttribute.Namespace, contractCodeDomInfo.CodeNamespace);
            }
 
            string dataContractName = GetNameForAttribute(enumDataContract.StableName.Name);
            CodeAttributeDeclaration dataContractAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfDataContractAttribute)); 
            dataContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NameProperty, new CodePrimitiveExpression(dataContractName))); 
            dataContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NamespaceProperty, new CodePrimitiveExpression(enumDataContract.StableName.Namespace)));
            type.CustomAttributes.Add(dataContractAttribute); 
            AddImportStatement(Globals.TypeOfDataContractAttribute.Namespace, contractCodeDomInfo.CodeNamespace);

            if (enumDataContract.Members != null)
            { 
                for (int i=0; i < enumDataContract.Members.Count; i++)
                { 
                    string stringValue = enumDataContract.Members[i].Name; 
                    long longValue = enumDataContract.Values[i];
 
                    CodeMemberField enumMember = new CodeMemberField();
                    if (enumDataContract.IsULong)
                        enumMember.InitExpression  = new CodeSnippetExpression(enumDataContract.GetStringFromEnumValue(longValue));
                    else 
                        enumMember.InitExpression  = new CodePrimitiveExpression(longValue);
                    enumMember.Name = GetMemberName(stringValue, contractCodeDomInfo); 
                    CodeAttributeDeclaration enumMemberAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfEnumMemberAttribute)); 
                    if (enumMember.Name != stringValue)
                        enumMemberAttribute.Arguments.Add(new CodeAttributeArgument(Globals.ValueProperty, new CodePrimitiveExpression(stringValue))); 
                    enumMember.CustomAttributes.Add(enumMemberAttribute);
                    type.Members.Add(enumMember);
                }
            } 
        }
 
        void ExportISerializableDataContract(ClassDataContract dataContract, ContractCodeDomInfo contractCodeDomInfo) 
        {
            GenerateType(dataContract, contractCodeDomInfo); 
            if (contractCodeDomInfo.ReferencedTypeExists)
                return;

            if (DataContract.GetDefaultStableNamespace(contractCodeDomInfo.ClrNamespace) != dataContract.StableName.Namespace) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidClrNamespaceGeneratedForISerializable, dataContract.StableName.Name, dataContract.StableName.Namespace, DataContract.GetDataContractNamespaceFromUri(dataContract.StableName.Namespace), contractCodeDomInfo.ClrNamespace)));
            string dataContractName = GetNameForAttribute(dataContract.StableName.Name); 
            int nestedTypeIndex = dataContractName.LastIndexOf('.'); 
            string expectedName = (nestedTypeIndex <= 0 || nestedTypeIndex == dataContractName.Length-1) ? dataContractName : dataContractName.Substring(nestedTypeIndex+1);
            if (contractCodeDomInfo.TypeDeclaration.Name != expectedName) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidClrNameGeneratedForISerializable, dataContract.StableName.Name, dataContract.StableName.Namespace, contractCodeDomInfo.TypeDeclaration.Name)));

            CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration;
            if (SupportsPartialTypes) 
                type.IsPartial = true;
            if (dataContract.IsValueType && SupportsDeclareValueTypes) 
                type.IsStruct = true; 
            else
                type.IsClass = true; 

            AddSerializableAttribute(true /*generateSerializable*/, type, contractCodeDomInfo);

            AddKnownTypes(dataContract, contractCodeDomInfo); 

            if (dataContract.BaseContract == null) 
            { 
                if (!type.IsStruct)
                    type.BaseTypes.Add(Globals.TypeOfObject); 
                type.BaseTypes.Add(DataContract.GetClrTypeFullName(Globals.TypeOfISerializable));
                type.Members.Add(ISerializableBaseConstructor);
                type.Members.Add(SerializationInfoField);
                type.Members.Add(SerializationInfoProperty); 
                type.Members.Add(GetObjectDataMethod);
                AddPropertyChangedNotifier(contractCodeDomInfo, type.IsStruct); 
            } 
            else
            { 
                ContractCodeDomInfo baseContractCodeDomInfo = GetContractCodeDomInfo(dataContract.BaseContract);
                GenerateType(dataContract.BaseContract, baseContractCodeDomInfo);
                type.BaseTypes.Add(baseContractCodeDomInfo.TypeReference);
                if (baseContractCodeDomInfo.ReferencedTypeExists) 
                {
                    Type actualType = (Type)baseContractCodeDomInfo.TypeReference.UserData[codeUserDataActualTypeKey]; 
                    ThrowIfReferencedBaseTypeSealed(actualType, dataContract); 
                }
                type.Members.Add(ISerializableDerivedConstructor); 
            }
        }

        void GenerateKeyValueType(ClassDataContract keyValueContract) 
        {
            // Add code for KeyValue item type in the case where its usage is limited to dictionary 
            // and dictionary is not found in referenced types 
            if (keyValueContract != null && dataContractSet[keyValueContract.StableName] == null)
            { 
                ContractCodeDomInfo contractCodeDomInfo = dataContractSet.GetContractCodeDomInfo(keyValueContract);
                if (contractCodeDomInfo == null)
                {
                    contractCodeDomInfo = new ContractCodeDomInfo(); 
                    dataContractSet.SetContractCodeDomInfo(keyValueContract, contractCodeDomInfo);
                    ExportClassDataContract(keyValueContract, contractCodeDomInfo); 
                    contractCodeDomInfo.IsProcessed = true; 
                }
            } 
        }

        void ExportCollectionDataContract(CollectionDataContract collectionContract, ContractCodeDomInfo contractCodeDomInfo)
        { 
            GenerateType(collectionContract, contractCodeDomInfo);
            if (contractCodeDomInfo.ReferencedTypeExists) 
                return; 

            string dataContractName = GetNameForAttribute(collectionContract.StableName.Name); 

            // If type name is not expected, generate collection type that derives from referenced list type and uses [CollectionDataContract]
            if (!SupportsGenericTypeReference)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( 
                    SR.GetString(SR.CannotUseGenericTypeAsBase, dataContractName,
                    collectionContract.StableName.Namespace))); 
 
            DataContract itemContract = collectionContract.ItemContract;
            bool isItemTypeNullable = collectionContract.IsItemTypeNullable; 

            CodeTypeReference baseTypeReference;
            bool foundDictionaryBase = TryGetReferencedDictionaryType(collectionContract, out baseTypeReference);
            if (!foundDictionaryBase) 
            {
                if (collectionContract.IsDictionary) 
                { 
                    GenerateKeyValueType(collectionContract.ItemContract as ClassDataContract);
                } 
                if (!TryGetReferencedListType(itemContract, isItemTypeNullable, out baseTypeReference))
                {
                    if (SupportsGenericTypeReference)
                    { 
                        baseTypeReference = GetCodeTypeReference(Globals.TypeOfListGeneric);
                        baseTypeReference.TypeArguments.Add(GetElementTypeReference(itemContract, isItemTypeNullable)); 
                    } 
                    else
                    { 
                        string expectedTypeName = Globals.ArrayPrefix + itemContract.StableName.Name;
                        string expectedTypeNs = DataContract.GetCollectionNamespace(itemContract.StableName.Namespace);
                        throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ReferencedBaseTypeDoesNotExist,
                            dataContractName, collectionContract.StableName.Namespace, 
                            expectedTypeName, expectedTypeNs, DataContract.GetClrTypeFullName(Globals.TypeOfIListGeneric), DataContract.GetClrTypeFullName(Globals.TypeOfICollectionGeneric))));
                    } 
                } 
            }
 
            CodeTypeDeclaration generatedType = contractCodeDomInfo.TypeDeclaration;
            generatedType.BaseTypes.Add(baseTypeReference);
            CodeAttributeDeclaration collectionContractAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfCollectionDataContractAttribute));
            collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NameProperty, new CodePrimitiveExpression(dataContractName))); 
            collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NamespaceProperty, new CodePrimitiveExpression(collectionContract.StableName.Namespace)));
            if (collectionContract.IsReference != Globals.DefaultIsReference) 
                collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.IsReferenceProperty, new CodePrimitiveExpression(collectionContract.IsReference))); 
            collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.ItemNameProperty, new CodePrimitiveExpression(GetNameForAttribute(collectionContract.ItemName))));
            if (foundDictionaryBase) 
            {
                collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.KeyNameProperty, new CodePrimitiveExpression(GetNameForAttribute(collectionContract.KeyName))));
                collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.ValueNameProperty, new CodePrimitiveExpression(GetNameForAttribute(collectionContract.ValueName))));
            } 
            generatedType.CustomAttributes.Add(collectionContractAttribute);
            AddImportStatement(Globals.TypeOfCollectionDataContractAttribute.Namespace, contractCodeDomInfo.CodeNamespace); 
            AddSerializableAttribute(GenerateSerializableTypes, generatedType, contractCodeDomInfo); 
        }
 
        private void ExportXmlDataContract(XmlDataContract xmlDataContract, ContractCodeDomInfo contractCodeDomInfo)
        {
            GenerateType(xmlDataContract, contractCodeDomInfo);
            if (contractCodeDomInfo.ReferencedTypeExists) 
                return;
 
            CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration; 
            if (SupportsPartialTypes)
                type.IsPartial = true; 
            if(xmlDataContract.IsValueType)
                type.IsStruct = true;
            else
            { 
                type.IsClass = true;
                type.BaseTypes.Add(Globals.TypeOfObject); 
            } 
            AddSerializableAttribute(GenerateSerializableTypes, type, contractCodeDomInfo);
 
            type.BaseTypes.Add(DataContract.GetClrTypeFullName(Globals.TypeOfIXmlSerializable));

            type.Members.Add(NodeArrayField);
            type.Members.Add(NodeArrayProperty); 
            type.Members.Add(ReadXmlMethod);
            type.Members.Add(WriteXmlMethod); 
            type.Members.Add(GetSchemaMethod); 
            if (xmlDataContract.IsAnonymous && !xmlDataContract.HasRoot)
            { 
                type.CustomAttributes.Add(new CodeAttributeDeclaration(
                    DataContract.GetClrTypeFullName(Globals.TypeOfXmlSchemaProviderAttribute),
                    new CodeAttributeArgument(NullReference),
                    new CodeAttributeArgument(Globals.IsAnyProperty, new CodePrimitiveExpression(true))) 
                );
            } 
            else 
            {
                type.CustomAttributes.Add(new CodeAttributeDeclaration( 
                    DataContract.GetClrTypeFullName(Globals.TypeOfXmlSchemaProviderAttribute),
                    new CodeAttributeArgument(new CodePrimitiveExpression(Globals.ExportSchemaMethod)))
                );
 
                CodeMemberField typeNameField = new CodeMemberField(Globals.TypeOfXmlQualifiedName, typeNameFieldName);
                typeNameField.Attributes |= MemberAttributes.Static | MemberAttributes.Private; 
                XmlQualifiedName typeName = xmlDataContract.IsAnonymous 
                    ? SchemaImporter.ImportActualType(xmlDataContract.XsdType.Annotation, xmlDataContract.StableName, xmlDataContract.StableName)
                    : xmlDataContract.StableName; 
                typeNameField.InitExpression = new CodeObjectCreateExpression(Globals.TypeOfXmlQualifiedName, new CodePrimitiveExpression(typeName.Name), new CodePrimitiveExpression(typeName.Namespace));
                type.Members.Add(typeNameField);

                type.Members.Add(GetSchemaStaticMethod); 

                bool isElementNameDifferent = 
                    (xmlDataContract.TopLevelElementName != null && xmlDataContract.TopLevelElementName.Value != xmlDataContract.StableName.Name) || 
                    (xmlDataContract.TopLevelElementNamespace != null && xmlDataContract.TopLevelElementNamespace.Value != xmlDataContract.StableName.Namespace);
                if (isElementNameDifferent || xmlDataContract.IsTopLevelElementNullable == false) 
                {
                    CodeAttributeDeclaration xmlRootAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfXmlRootAttribute));
                    if (isElementNameDifferent)
                    { 
                        if (xmlDataContract.TopLevelElementName != null)
                        { 
                            xmlRootAttribute.Arguments.Add(new CodeAttributeArgument("ElementName", new CodePrimitiveExpression(xmlDataContract.TopLevelElementName.Value))); 
                        }
                        if (xmlDataContract.TopLevelElementNamespace != null) 
                        {
                            xmlRootAttribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(xmlDataContract.TopLevelElementNamespace.Value)));
                        }
                    } 
                    if (xmlDataContract.IsTopLevelElementNullable == false)
                        xmlRootAttribute.Arguments.Add(new CodeAttributeArgument("IsNullable", new CodePrimitiveExpression(false))); 
                    type.CustomAttributes.Add(xmlRootAttribute); 
                }
            } 
            AddPropertyChangedNotifier(contractCodeDomInfo, type.IsStruct);
        }

        CodeNamespace GetCodeNamespace(string clrNamespace, string dataContractNamespace, ContractCodeDomInfo contractCodeDomInfo) 
        {
            if (contractCodeDomInfo.CodeNamespace != null) 
                return contractCodeDomInfo.CodeNamespace; 

            CodeNamespaceCollection codeNamespaceCollection = codeCompileUnit.Namespaces; 
            foreach (CodeNamespace ns in codeNamespaceCollection)
            {
                if (ns.Name == clrNamespace)
                { 
                    contractCodeDomInfo.CodeNamespace = ns;
                    return ns; 
                } 
            }
 
            CodeNamespace codeNamespace = new CodeNamespace(clrNamespace);
            codeNamespaceCollection.Add(codeNamespace);

            if (CanDeclareAssemblyAttribute(contractCodeDomInfo) 
                && NeedsExplicitNamespace(dataContractNamespace, clrNamespace))
            { 
                CodeAttributeDeclaration namespaceAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfContractNamespaceAttribute)); 
                namespaceAttribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(dataContractNamespace)));
                namespaceAttribute.Arguments.Add(new CodeAttributeArgument(Globals.ClrNamespaceProperty, new CodePrimitiveExpression(clrNamespace))); 
                codeCompileUnit.AssemblyCustomAttributes.Add(namespaceAttribute);
            }
            contractCodeDomInfo.CodeNamespace = codeNamespace;
            return codeNamespace; 
        }
 
        string GetMemberName(string memberName, ContractCodeDomInfo contractCodeDomInfo) 
        {
            memberName = GetClrIdentifier(memberName, Globals.DefaultGeneratedMember); 

            if (memberName == contractCodeDomInfo.TypeDeclaration.Name)
                memberName = AppendToValidClrIdentifier(memberName, Globals.DefaultMemberSuffix);
 
            if (contractCodeDomInfo.GetMemberNames().ContainsKey(memberName))
            { 
                string uniqueMemberName = null; 
                for (int i = 1; ; i++)
                { 
                    uniqueMemberName = AppendToValidClrIdentifier(memberName, i.ToString(NumberFormatInfo.InvariantInfo));
                    if (!contractCodeDomInfo.GetMemberNames().ContainsKey(uniqueMemberName))
                    {
                        memberName = uniqueMemberName; 
                        break;
                    } 
                } 
            }
 
            contractCodeDomInfo.GetMemberNames().Add(memberName, null);
            return memberName;
        }
 
        void AddBaseMemberNames(ContractCodeDomInfo baseContractCodeDomInfo, ContractCodeDomInfo contractCodeDomInfo)
        { 
            if (!baseContractCodeDomInfo.ReferencedTypeExists) 
            {
                Dictionary baseMemberNames = baseContractCodeDomInfo.GetMemberNames(); 
                Dictionary memberNames = contractCodeDomInfo.GetMemberNames();
                foreach (KeyValuePair pair in baseMemberNames)
                {
                    memberNames.Add(pair.Key, pair.Value); 
                }
            } 
        } 

        static string GetClrIdentifier(string identifier, string defaultIdentifier) 
        {
            if (identifier.Length <= MaxIdentifierLength && System.CodeDom.Compiler.CodeGenerator.IsValidLanguageIndependentIdentifier(identifier))
                return identifier;
 
            bool isStart = true;
            StringBuilder builder = new StringBuilder(); 
            for (int i = 0; i < identifier.Length && builder.Length < MaxIdentifierLength; i++) 
            {
                char c = identifier[i]; 
                if (IsValid(c))
                {
                    if (isStart && !IsValidStart(c))
                        builder.Append("_"); 
                    builder.Append(c);
                    isStart = false; 
                } 
            }
            if (builder.Length == 0) 
                return defaultIdentifier;

            return builder.ToString();
        } 

        static string AppendToValidClrIdentifier(string identifier, string appendString) 
        { 
            int availableLength = MaxIdentifierLength - identifier.Length;
            int requiredLength = appendString.Length; 
            if (availableLength < requiredLength)
                identifier = identifier.Substring(0, MaxIdentifierLength - requiredLength);
            identifier += appendString;
            return identifier; 
        }
 
        string GetClrNamespace(DataContract dataContract, ContractCodeDomInfo contractCodeDomInfo) 
        {
            string clrNamespace = contractCodeDomInfo.ClrNamespace; 
            bool usesWildcardNamespace = false;
            if (clrNamespace == null)
            {
                if (!Namespaces.TryGetValue(dataContract.StableName.Namespace, out clrNamespace)) 
                {
                    if (Namespaces.TryGetValue(wildcardNamespaceMapping, out clrNamespace)) 
                    { 
                        usesWildcardNamespace = true;
                    } 
                    else
                    {
                        clrNamespace = GetClrNamespace(dataContract.StableName.Namespace);
                        if (ClrNamespaces.ContainsKey(clrNamespace)) 
                        {
                            string uniqueNamespace = null; 
                            for (int i = 1; ; i++) 
                            {
                                uniqueNamespace = ((clrNamespace.Length == 0) ? Globals.DefaultClrNamespace : clrNamespace) + i.ToString(NumberFormatInfo.InvariantInfo); 
                                if (!ClrNamespaces.ContainsKey(uniqueNamespace))
                                {
                                    clrNamespace = uniqueNamespace;
                                    break; 
                                }
                            } 
                        } 
                        AddNamespacePair(dataContract.StableName.Namespace, clrNamespace);
                    } 
                }
                contractCodeDomInfo.ClrNamespace = clrNamespace;
                contractCodeDomInfo.UsesWildcardNamespace = usesWildcardNamespace;
            } 
            return clrNamespace;
        } 
 
        void AddNamespacePair(string dataContractNamespace, string clrNamespace)
        { 
            Namespaces.Add(dataContractNamespace, clrNamespace);
            ClrNamespaces.Add(clrNamespace, dataContractNamespace);
        }
 
        void AddImportStatement(string clrNamespace, CodeNamespace codeNamespace)
        { 
            if (clrNamespace == codeNamespace.Name) 
                return;
 
            CodeNamespaceImportCollection importCollection = codeNamespace.Imports;
            foreach (CodeNamespaceImport import in importCollection)
            {
                if (import.Namespace == clrNamespace) 
                    return;
            } 
 
            importCollection.Add(new CodeNamespaceImport(clrNamespace));
        } 

        static string GetClrNamespace(string dataContractNamespace)
        {
            if (dataContractNamespace == null || dataContractNamespace.Length == 0) 
                return String.Empty;
 
            Uri uri = null; 
            StringBuilder builder = new StringBuilder();
            if (Uri.TryCreate(dataContractNamespace, UriKind.RelativeOrAbsolute, out uri)) 
            {
                Dictionary fragments = new Dictionary(StringComparer.OrdinalIgnoreCase);
                if (!uri.IsAbsoluteUri)
                    AddToNamespace(builder, uri.OriginalString, fragments); 
                else
                { 
                    string uriString = uri.AbsoluteUri; 
                    if (uriString.StartsWith(Globals.DataContractXsdBaseNamespace, StringComparison.Ordinal))
                        AddToNamespace(builder, uriString.Substring(Globals.DataContractXsdBaseNamespace.Length), fragments); 
                    else
                    {
                        string host = uri.Host;
                        if (host != null) 
                            AddToNamespace(builder, host, fragments);
                        string path = uri.PathAndQuery; 
                        if (path != null) 
                            AddToNamespace(builder, path, fragments);
                    } 
                }
            }

            if (builder.Length == 0) 
                return String.Empty;
 
            int length = builder.Length; 
            if (builder[builder.Length-1] == '.')
                length--; 
            length = Math.Min(MaxIdentifierLength, length);

            return builder.ToString(0, length);
        } 

        static void AddToNamespace(StringBuilder builder, string fragment, Dictionary fragments) 
        { 
            if (fragment == null)
                return; 
            bool isStart = true;
            int fragmentOffset = builder.Length;
            int fragmentLength = 0;
 
            for (int i = 0; i < fragment.Length && builder.Length < MaxIdentifierLength; i++)
            { 
                char c = fragment[i]; 

                if (IsValid(c)) 
                {
                    if (isStart && !IsValidStart(c))
                        builder.Append("_");
                    builder.Append(c); 
                    fragmentLength++;
                    isStart = false; 
                } 
                else if ((c == '.' || c == '/' || c == ':') && (builder.Length == 1
                    || (builder.Length > 1 && builder[builder.Length-1] != '.'))) 
                {
                    AddNamespaceFragment(builder, fragmentOffset, fragmentLength, fragments);
                    builder.Append('.');
                    fragmentOffset = builder.Length; 
                    fragmentLength = 0;
                    isStart = true; 
                } 
            }
            AddNamespaceFragment(builder, fragmentOffset, fragmentLength, fragments); 
        }

        static void AddNamespaceFragment(StringBuilder builder, int fragmentOffset,
            int fragmentLength, Dictionary fragments) 
        {
            if (fragmentLength == 0) 
                return; 

            string nsFragment = builder.ToString(fragmentOffset, fragmentLength); 
            if (fragments.ContainsKey(nsFragment))
            {
                for (int i = 1; ; i++)
                { 
                    string uniquifier = i.ToString(NumberFormatInfo.InvariantInfo);
                    string uniqueNsFragment = AppendToValidClrIdentifier(nsFragment, uniquifier); 
                    if (!fragments.ContainsKey(uniqueNsFragment)) 
                    {
                        builder.Append(uniquifier); 
                        nsFragment = uniqueNsFragment;
                        break;
                    }
                    if (i == Int32.MaxValue) 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CannotComputeUniqueName, nsFragment)));
                } 
            } 
            fragments.Add(nsFragment, null);
        } 

        static bool IsValidStart(char c)
        {
            return (Char.GetUnicodeCategory(c) != UnicodeCategory.DecimalDigitNumber); 
        }
 
        static bool IsValid(char c) 
        {
            UnicodeCategory uc = Char.GetUnicodeCategory(c); 

            // each char must be Lu, Ll, Lt, Lm, Lo, Nd, Mn, Mc, Pc

            switch (uc) 
            {
                case UnicodeCategory.UppercaseLetter:        // Lu 
                case UnicodeCategory.LowercaseLetter:        // Ll 
                case UnicodeCategory.TitlecaseLetter:        // Lt
                case UnicodeCategory.ModifierLetter:         // Lm 
                case UnicodeCategory.OtherLetter:            // Lo
                case UnicodeCategory.DecimalDigitNumber:     // Nd
                case UnicodeCategory.NonSpacingMark:         // Mn
                case UnicodeCategory.SpacingCombiningMark:   // Mc 
                case UnicodeCategory.ConnectorPunctuation:   // Pc
                    return true; 
                default: 
                    return false;
            } 
        }

        CodeTypeReference CodeTypeIPropertyChange
        { 
            get { return GetCodeTypeReference(typeof(System.ComponentModel.INotifyPropertyChanged)); }
        } 
 
        CodeThisReferenceExpression ThisReference
        { 
            get { return new CodeThisReferenceExpression(); }
        }

        CodePrimitiveExpression NullReference 
        {
            get { return new CodePrimitiveExpression(null); } 
        } 

        CodeParameterDeclarationExpression SerializationInfoParameter 
        {
            get { return new CodeParameterDeclarationExpression(GetCodeTypeReference(Globals.TypeOfSerializationInfo), Globals.SerializationInfoFieldName); }
        }
 
        CodeParameterDeclarationExpression StreamingContextParameter
        { 
            get { return new CodeParameterDeclarationExpression(GetCodeTypeReference(Globals.TypeOfStreamingContext), Globals.ContextFieldName); } 
        }
 
        CodeAttributeDeclaration SerializableAttribute
        {
            get { return new CodeAttributeDeclaration(GetCodeTypeReference(Globals.TypeOfSerializableAttribute)); }
        } 

        CodeMemberProperty NodeArrayProperty 
        { 
            get
            { 
                return CreateProperty(GetCodeTypeReference(Globals.TypeOfXmlNodeArray),Globals.NodeArrayPropertyName, Globals.NodeArrayFieldName, false/*isValueType*/);
            }
        }
 
        CodeMemberField NodeArrayField
        { 
            get 
            {
                CodeMemberField nodeArrayField = new CodeMemberField(); 
                nodeArrayField.Type = GetCodeTypeReference(Globals.TypeOfXmlNodeArray);
                nodeArrayField.Name = Globals.NodeArrayFieldName;
                nodeArrayField.Attributes = MemberAttributes.Private;
                return nodeArrayField; 
            }
        } 
        CodeMemberMethod ReadXmlMethod 
        {
            get 
            {
                CodeMemberMethod readXmlMethod = new CodeMemberMethod();
                readXmlMethod.Name = "ReadXml";
                CodeParameterDeclarationExpression readerArg = new CodeParameterDeclarationExpression(typeof(XmlReader), "reader"); 
                readXmlMethod.Parameters.Add(readerArg);
                readXmlMethod.Attributes =  MemberAttributes.Public | MemberAttributes.Final; 
                readXmlMethod.ImplementationTypes.Add(Globals.TypeOfIXmlSerializable); 
                CodeAssignStatement setNode = new CodeAssignStatement();
                setNode.Left = new CodeFieldReferenceExpression(ThisReference, Globals.NodeArrayFieldName); 
                setNode.Right = new CodeMethodInvokeExpression(
                                      new CodeTypeReferenceExpression(GetCodeTypeReference(Globals.TypeOfXmlSerializableServices)),
                                      XmlSerializableServices.ReadNodesMethodName,
                                      new CodeArgumentReferenceExpression(readerArg.Name) 
                                    );
                readXmlMethod.Statements.Add(setNode); 
                return readXmlMethod; 
            }
        } 
        CodeMemberMethod WriteXmlMethod
        {
            get
            { 
                CodeMemberMethod writeXmlMethod = new CodeMemberMethod();
                writeXmlMethod.Name = "WriteXml"; 
                CodeParameterDeclarationExpression writerArg = new CodeParameterDeclarationExpression(typeof(XmlWriter), "writer"); 
                writeXmlMethod.Parameters.Add(writerArg);
                writeXmlMethod.Attributes =  MemberAttributes.Public | MemberAttributes.Final; 
                writeXmlMethod.ImplementationTypes.Add(Globals.TypeOfIXmlSerializable);
                writeXmlMethod.Statements.Add(
                    new CodeMethodInvokeExpression(
                        new CodeTypeReferenceExpression(GetCodeTypeReference(Globals.TypeOfXmlSerializableServices)), 
                        XmlSerializableServices.WriteNodesMethodName,
                        new CodeArgumentReferenceExpression(writerArg.Name), 
                        new CodePropertyReferenceExpression(ThisReference, Globals.NodeArrayPropertyName) 
                    )
                ); 
                return writeXmlMethod;
            }
        }
 
        CodeMemberMethod GetSchemaMethod
        { 
            get 
            {
                CodeMemberMethod getSchemaMethod = new CodeMemberMethod(); 
                getSchemaMethod.Name = "GetSchema";
                getSchemaMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                getSchemaMethod.ImplementationTypes.Add(Globals.TypeOfIXmlSerializable);
                getSchemaMethod.ReturnType = GetCodeTypeReference(typeof(XmlSchema)); 
                getSchemaMethod.Statements.Add(new CodeMethodReturnStatement(NullReference));
                return getSchemaMethod; 
            } 
        }
 
        CodeMemberMethod GetSchemaStaticMethod
        {
            get
            { 
                CodeMemberMethod getSchemaStaticMethod = new CodeMemberMethod();
                getSchemaStaticMethod.Name = Globals.ExportSchemaMethod; 
                getSchemaStaticMethod.ReturnType = GetCodeTypeReference(Globals.TypeOfXmlQualifiedName); 
                CodeParameterDeclarationExpression paramDeclaration = new CodeParameterDeclarationExpression(Globals.TypeOfXmlSchemaSet, "schemas");
                getSchemaStaticMethod.Parameters.Add(paramDeclaration); 
                getSchemaStaticMethod.Attributes = MemberAttributes.Static | MemberAttributes.Public;
                getSchemaStaticMethod.Statements.Add(
                    new CodeMethodInvokeExpression(
                        new CodeTypeReferenceExpression(GetCodeTypeReference(typeof(XmlSerializableServices))), 
                        XmlSerializableServices.AddDefaultSchemaMethodName,
                        new CodeArgumentReferenceExpression(paramDeclaration.Name), 
                        new CodeFieldReferenceExpression(null, typeNameFieldName) 
                    )
                ); 
                getSchemaStaticMethod.Statements.Add(
                    new CodeMethodReturnStatement(
                        new CodeFieldReferenceExpression(null, typeNameFieldName)
                    ) 
                );
                return getSchemaStaticMethod; 
            } 
        }
 
        CodeConstructor ISerializableBaseConstructor
        {
            get
            { 
                CodeConstructor baseConstructor = new CodeConstructor();
                baseConstructor.Attributes = MemberAttributes.Public; 
                baseConstructor.Parameters.Add(SerializationInfoParameter); 
                baseConstructor.Parameters.Add(StreamingContextParameter);
                CodeAssignStatement setObjectData = new CodeAssignStatement(); 
                setObjectData.Left = new CodePropertyReferenceExpression(ThisReference, Globals.SerializationInfoFieldName);
                setObjectData.Right = new CodeArgumentReferenceExpression(Globals.SerializationInfoFieldName);
                baseConstructor.Statements.Add(setObjectData);
                // Special-cased check for vb here since CodeGeneratorOptions does not provide information indicating that VB cannot initialize event member 
                if (EnableDataBinding && SupportsDeclareEvents && String.CompareOrdinal(FileExtension, "vb") != 0)
                { 
                    baseConstructor.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(ThisReference, PropertyChangedEvent.Name), NullReference)); 
                }
                return baseConstructor; 
            }
        }

        CodeConstructor ISerializableDerivedConstructor 
        {
            get 
            { 
                CodeConstructor derivedConstructor = new CodeConstructor();
                derivedConstructor.Attributes = MemberAttributes.Public; 
                derivedConstructor.Parameters.Add(SerializationInfoParameter);
                derivedConstructor.Parameters.Add(StreamingContextParameter);
                derivedConstructor.BaseConstructorArgs.Add(new CodeVariableReferenceExpression(Globals.SerializationInfoFieldName));
                derivedConstructor.BaseConstructorArgs.Add(new CodeVariableReferenceExpression(Globals.ContextFieldName)); 
                return derivedConstructor;
            } 
        } 

        CodeMemberField SerializationInfoField 
        {
            get
            {
                CodeMemberField serializationInfoField = new CodeMemberField(); 
                serializationInfoField.Type = GetCodeTypeReference(Globals.TypeOfSerializationInfo);
                serializationInfoField.Name = Globals.SerializationInfoFieldName; 
                serializationInfoField.Attributes = MemberAttributes.Private; 
                return serializationInfoField;
            } 
        }

        CodeMemberProperty SerializationInfoProperty
        { 
            get
            { 
                return CreateProperty(GetCodeTypeReference(Globals.TypeOfSerializationInfo), Globals.SerializationInfoPropertyName, Globals.SerializationInfoFieldName, false/*isValueType*/); 
            }
        } 

        CodeMemberMethod GetObjectDataMethod
        {
            get 
            {
                CodeMemberMethod getObjectDataMethod = new CodeMemberMethod(); 
                getObjectDataMethod.Name = Globals.GetObjectDataMethodName; 
                getObjectDataMethod.Parameters.Add(SerializationInfoParameter);
                getObjectDataMethod.Parameters.Add(StreamingContextParameter); 
                getObjectDataMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                getObjectDataMethod.ImplementationTypes.Add(Globals.TypeOfISerializable);

                // Generates: if (this.SerializationInfo == null) return; 
                CodeConditionStatement returnIfNull = new CodeConditionStatement();
                returnIfNull.Condition = new CodeBinaryOperatorExpression( 
                    new CodePropertyReferenceExpression(ThisReference, Globals.SerializationInfoPropertyName), 
                    CodeBinaryOperatorType.IdentityEquality,
                    NullReference); 
                returnIfNull.TrueStatements.Add(new CodeMethodReturnStatement());

                // Generates: SerializationInfoEnumerator enumerator = this.SerializationInfo.GetEnumerator();
                CodeVariableDeclarationStatement getEnumerator = new CodeVariableDeclarationStatement(); 
                getEnumerator.Type = GetCodeTypeReference(Globals.TypeOfSerializationInfoEnumerator);
                getEnumerator.Name = Globals.EnumeratorFieldName; 
                getEnumerator.InitExpression = new CodeMethodInvokeExpression( 
                    new CodePropertyReferenceExpression(ThisReference, Globals.SerializationInfoPropertyName),
                    Globals.GetEnumeratorMethodName); 

                //Generates: SerializationEntry entry = enumerator.Current;
                CodeVariableDeclarationStatement getCurrent = new CodeVariableDeclarationStatement();
                getCurrent.Type = GetCodeTypeReference(Globals.TypeOfSerializationEntry); 
                getCurrent.Name = Globals.SerializationEntryFieldName;
                getCurrent.InitExpression = new CodePropertyReferenceExpression( 
                    new CodeVariableReferenceExpression(Globals.EnumeratorFieldName), 
                    Globals.CurrentPropertyName);
 
                //Generates: info.AddValue(entry.Name, entry.Value);
                CodeExpressionStatement addValue = new CodeExpressionStatement();
                CodePropertyReferenceExpression getCurrentName = new CodePropertyReferenceExpression(
                    new CodeVariableReferenceExpression(Globals.SerializationEntryFieldName), 
                    Globals.NameProperty);
                CodePropertyReferenceExpression getCurrentValue = new CodePropertyReferenceExpression( 
                    new CodeVariableReferenceExpression(Globals.SerializationEntryFieldName), 
                    Globals.ValueProperty);
                addValue.Expression = new CodeMethodInvokeExpression( 
                    new CodeArgumentReferenceExpression(Globals.SerializationInfoFieldName),
                    Globals.AddValueMethodName,
                    new CodeExpression[] { getCurrentName, getCurrentValue });
 
                //Generates: for (; enumerator.MoveNext(); )
                CodeIterationStatement loop = new CodeIterationStatement(); 
                loop.TestExpression = new CodeMethodInvokeExpression( 
                    new CodeVariableReferenceExpression(Globals.EnumeratorFieldName),
                    Globals.MoveNextMethodName); 
                loop.InitStatement = loop.IncrementStatement = new CodeSnippetStatement(String.Empty);
                loop.Statements.Add(getCurrent);
                loop.Statements.Add(addValue);
 
                getObjectDataMethod.Statements.Add(returnIfNull);
                getObjectDataMethod.Statements.Add(getEnumerator); 
                getObjectDataMethod.Statements.Add(loop); 

                return getObjectDataMethod; 
            }
        }

        CodeMemberField ExtensionDataObjectField 
        {
            get 
            { 
                CodeMemberField extensionDataObjectField = new CodeMemberField();
                extensionDataObjectField.Type = GetCodeTypeReference(Globals.TypeOfExtensionDataObject); 
                extensionDataObjectField.Name = Globals.ExtensionDataObjectFieldName;
                extensionDataObjectField.Attributes = MemberAttributes.Private;
                return extensionDataObjectField;
            } 
        }
 
        CodeMemberProperty ExtensionDataObjectProperty 
        {
            get 
            {
                CodeMemberProperty extensionDataObjectProperty = new CodeMemberProperty();
                extensionDataObjectProperty.Type = GetCodeTypeReference(Globals.TypeOfExtensionDataObject);
                extensionDataObjectProperty.Name = Globals.ExtensionDataObjectPropertyName; 
                extensionDataObjectProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                extensionDataObjectProperty.ImplementationTypes.Add(Globals.TypeOfIExtensibleDataObject); 
 
                CodeMethodReturnStatement propertyGet = new CodeMethodReturnStatement();
                propertyGet.Expression = new CodeFieldReferenceExpression(ThisReference, Globals.ExtensionDataObjectFieldName); 
                extensionDataObjectProperty.GetStatements.Add(propertyGet);

                CodeAssignStatement propertySet = new CodeAssignStatement();
                propertySet.Left = new CodeFieldReferenceExpression(ThisReference, Globals.ExtensionDataObjectFieldName); 
                propertySet.Right = new CodePropertySetValueReferenceExpression();
                extensionDataObjectProperty.SetStatements.Add(propertySet); 
 
                return extensionDataObjectProperty;
            } 
        }

        CodeMemberMethod RaisePropertyChangedEventMethod
        { 
            get
            { 
                CodeMemberMethod raisePropertyChangedEventMethod = new CodeMemberMethod(); 
                raisePropertyChangedEventMethod.Name = "RaisePropertyChanged";
                raisePropertyChangedEventMethod.Attributes = MemberAttributes.Final; 
                CodeArgumentReferenceExpression propertyName = new CodeArgumentReferenceExpression("propertyName");
                raisePropertyChangedEventMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), propertyName.ParameterName));
                CodeVariableReferenceExpression propertyChanged = new CodeVariableReferenceExpression("propertyChanged");
                raisePropertyChangedEventMethod.Statements.Add(new CodeVariableDeclarationStatement(typeof(PropertyChangedEventHandler), propertyChanged.VariableName, new CodeEventReferenceExpression(ThisReference, PropertyChangedEvent.Name))); 
                CodeConditionStatement ifStatement = new CodeConditionStatement(new CodeBinaryOperatorExpression(propertyChanged, CodeBinaryOperatorType.IdentityInequality, NullReference));
                raisePropertyChangedEventMethod.Statements.Add(ifStatement); 
                ifStatement.TrueStatements.Add(new CodeDelegateInvokeExpression(propertyChanged, ThisReference, new CodeObjectCreateExpression(typeof(PropertyChangedEventArgs), propertyName))); 
                return raisePropertyChangedEventMethod;
            } 
        }

        CodeMemberEvent PropertyChangedEvent
        { 
            get
            { 
                CodeMemberEvent propertyChangedEvent = new CodeMemberEvent(); 
                propertyChangedEvent.Attributes = MemberAttributes.Public;
                propertyChangedEvent.Name = "PropertyChanged"; 
                propertyChangedEvent.Type = GetCodeTypeReference(typeof(PropertyChangedEventHandler));
                propertyChangedEvent.ImplementationTypes.Add(Globals.TypeOfIPropertyChange);
                return propertyChangedEvent;
            } 
        }
 
        CodeMemberProperty CreateProperty(CodeTypeReference type, string propertyName, string fieldName, bool isValueType) 
        {
            CodeMemberProperty property = new CodeMemberProperty(); 
            property.Type = type;
            property.Name = propertyName;
            property.Attributes = MemberAttributes.Final;
            if(GenerateInternalTypes) 
                property.Attributes |= MemberAttributes.Assembly;
            else 
                property.Attributes |= MemberAttributes.Public; 

            CodeMethodReturnStatement propertyGet = new CodeMethodReturnStatement(); 
            propertyGet.Expression = new CodeFieldReferenceExpression(ThisReference, fieldName);
            property.GetStatements.Add(propertyGet);

            CodeAssignStatement propertySet = new CodeAssignStatement(); 
            propertySet.Left = new CodeFieldReferenceExpression(ThisReference, fieldName);
            propertySet.Right = new CodePropertySetValueReferenceExpression(); 
            if (EnableDataBinding && SupportsDeclareEvents) 
            {
                CodeConditionStatement ifStatement = new CodeConditionStatement(); 
                CodeExpression left = new CodeFieldReferenceExpression(ThisReference, fieldName);
                CodeExpression right = new CodePropertySetValueReferenceExpression();
                if(!isValueType)
                { 
                    left = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(Globals.TypeOfObject),
                        "ReferenceEquals", new CodeExpression[] { left, right } ); 
                } 
                else
                { 
                    left = new CodeMethodInvokeExpression(left, "Equals", new CodeExpression[] { right } );
                }
                right = new CodePrimitiveExpression(true);
                ifStatement.Condition = new CodeBinaryOperatorExpression(left, CodeBinaryOperatorType.IdentityInequality, right); 
                ifStatement.TrueStatements.Add(propertySet);
                ifStatement.TrueStatements.Add(new CodeMethodInvokeExpression(ThisReference, RaisePropertyChangedEventMethod.Name, new CodePrimitiveExpression(propertyName))); 
                property.SetStatements.Add(ifStatement); 
            }
            else 
                property.SetStatements.Add(propertySet);
            return property;
        }
    } 
}
 
 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK