CodeExporter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / Serialization / System / Runtime / Serialization / CodeExporter.cs / 1438166 / CodeExporter.cs

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

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

    class CodeExporter
    {
        DataContractSet dataContractSet; 
        CodeCompileUnit codeCompileUnit;
        ImportOptions options; 
        Dictionary namespaces; 
        Dictionary clrNamespaces;
 
        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent"
            + " data from being modified or leaked to other components in appdomain.")]
        static readonly string wildcardNamespaceMapping = "*";
 
        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent"
            + " data from being modified or leaked to other components in appdomain.")] 
        static readonly string typeNameFieldName = "typeName"; 

        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent" 
            + " data from being modified or leaked to other components in appdomain.")]
        static readonly object codeUserDataActualTypeKey = new object();

        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent" 
            + " data from being modified or leaked to other components in appdomain.")]
        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;
        } 

        [Fx.Tag.SecurityNote(Critical = "Sets critical properties on internal XmlDataContract.", 
            Safe = "Called during schema import/code generation.")] 
        [SecuritySafeCritical]
        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);
                Fx.Assert(baseContractCodeDomInfo.IsProcessed, "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; 
        }

        [Fx.Tag.SecurityNote(Critical = "Sets critical properties on internal DataContract.",
            Safe = "Called during schema import/code generation.")] 
        [SecuritySafeCritical]
        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.
//-----------------------------------------------------------

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

    class CodeExporter
    {
        DataContractSet dataContractSet; 
        CodeCompileUnit codeCompileUnit;
        ImportOptions options; 
        Dictionary namespaces; 
        Dictionary clrNamespaces;
 
        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent"
            + " data from being modified or leaked to other components in appdomain.")]
        static readonly string wildcardNamespaceMapping = "*";
 
        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent"
            + " data from being modified or leaked to other components in appdomain.")] 
        static readonly string typeNameFieldName = "typeName"; 

        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent" 
            + " data from being modified or leaked to other components in appdomain.")]
        static readonly object codeUserDataActualTypeKey = new object();

        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent" 
            + " data from being modified or leaked to other components in appdomain.")]
        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;
        } 

        [Fx.Tag.SecurityNote(Critical = "Sets critical properties on internal XmlDataContract.", 
            Safe = "Called during schema import/code generation.")] 
        [SecuritySafeCritical]
        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);
                Fx.Assert(baseContractCodeDomInfo.IsProcessed, "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; 
        }

        [Fx.Tag.SecurityNote(Critical = "Sets critical properties on internal DataContract.",
            Safe = "Called during schema import/code generation.")] 
        [SecuritySafeCritical]
        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.

                        

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