File: system\reflection\emit\assemblybuilder.cs
Project: ndp\clr\src\bcl\mscorlib.csproj (mscorlib)
// ==++==
// 
//   Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// ==--==
 
//*************************************************************************************************************
// For each dynamic assembly there will be two AssemblyBuilder objects: the "internal" 
// AssemblyBuilder object and the "external" AssemblyBuilder object.
//  1.  The "internal" object is the real assembly object that the VM creates and knows about. However, 
//      you can perform RefEmit operations on it only if you have its granted permission. From the AppDomain 
//      and other "internal" objects like the "internal" ModuleBuilders and runtime types, you can only
//      get the "internal" objects. This is to prevent low-trust code from getting a hold of the dynamic
//      AssemblyBuilder/ModuleBuilder/TypeBuilder/MethodBuilder/etc other people have created by simply 
//      enumerating the AppDomain and inject code in it.
//  2.  The "external" object is merely an wrapper of the "internal" object and all operations on it
//      are directed to the internal object. This is the one you get by calling DefineDynamicAssembly
//      on AppDomain and the one you can always perform RefEmit operations on. You can get other "external"
//      objects from the "external" AssemblyBuilder, ModuleBuilder, TypeBuilder, MethodBuilder, etc. Note
//      that VM doesn't know about this object. So every time we call into the VM we need to pass in the
//      "internal" object.
//
// "internal" and "external" ModuleBuilders are similar
//*************************************************************************************************************
 
// <OWNER>Microsoft</OWNER>
namespace System.Reflection.Emit
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Diagnostics.Contracts;
    using System.Diagnostics.SymbolStore;
    using CultureInfo = System.Globalization.CultureInfo;
    using System.IO;
    using System.Reflection;
    using System.Resources;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Runtime.Serialization;
    using System.Runtime.Versioning;
    using System.Security;
    using System.Security.Permissions;
    using System.Security.Policy;
    using System.Threading;
 
    // These must match the definitions in Assembly.hpp
    [Flags]
    internal enum DynamicAssemblyFlags
    {
        None = 0x00000000,
 
        // Security attributes which affect the module security descriptor
        AllCritical             = 0x00000001,
        Aptca                   = 0x00000002,
        Critical                = 0x00000004,
        Transparent             = 0x00000008,
        TreatAsSafe             = 0x00000010,
    }
 
    // When the user calls AppDomain.DefineDynamicAssembly the loader creates a new InternalAssemblyBuilder. 
    // This InternalAssemblyBuilder can be retrieved via a call to Assembly.GetAssemblies() by untrusted code.
    // In the past, when InternalAssemblyBuilder was AssemblyBuilder, the untrusted user could down cast the
    // Assembly to an AssemblyBuilder and emit code with the elevated permissions of the trusted code which 
    // origionally created the AssemblyBuilder via DefineDynamicAssembly. Today, this can no longer happen
    // because the Assembly returned via AssemblyGetAssemblies() will be an InternalAssemblyBuilder.
    
    // Only the caller of DefineDynamicAssembly will get an AssemblyBuilder. 
    // There is a 1-1 relationship between InternalAssemblyBuilder and AssemblyBuilder. 
    // AssemblyBuilder is composed of its InternalAssemblyBuilder.
    // The AssemblyBuilder data members (e.g. m_foo) were changed to properties which then delegate 
    // the access to the composed InternalAssemblyBuilder. This way, AssemblyBuilder simply wraps 
    // InternalAssemblyBuilder and still operates on InternalAssemblyBuilder members. 
    // This also makes the change transparent to the loader. This is good because most of the complexity
    // of Assembly building is in the loader code so not touching that code reduces the chance of 
    // introducing new bugs.
    internal sealed class InternalAssemblyBuilder : RuntimeAssembly
    {
        private InternalAssemblyBuilder() { }
 
        #region object overrides
        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;
 
            if (obj is InternalAssemblyBuilder)
                return ((object)this == obj);
 
            return obj.Equals(this);
        }
        // Need a dummy GetHashCode to pair with Equals
        public override int GetHashCode() { return base.GetHashCode(); }
        #endregion
 
        // Assembly methods that are overridden by AssemblyBuilder should be overridden by InternalAssemblyBuilder too
        #region Methods inherited from Assembly
        public override String[] GetManifestResourceNames()
        {
            throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
        }
 
        #if FEATURE_CORECLR
        [System.Security.SecurityCritical] // auto-generated
        #endif
        public override FileStream GetFile(String name)
        {
            throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
        }
 
        #if FEATURE_CORECLR
        [System.Security.SecurityCritical] // auto-generated
        #endif
        public override FileStream[] GetFiles(bool getResourceModules)
        {
            throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
        }
 
        public override Stream GetManifestResourceStream(Type type, String name)
        {
            throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
        }
 
        public override Stream GetManifestResourceStream(String name)
        {
            throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
        }
 
        public override ManifestResourceInfo GetManifestResourceInfo(String resourceName)
        {
            throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
        }
 
        public override String Location
        {
#if FEATURE_CORECLR
            [SecurityCritical]
#endif // FEATURE_CORECLR
            get
            {
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
            }
        }
 
        public override String CodeBase
        {
#if FEATURE_CORECLR
            [SecurityCritical]
#endif // FEATURE_CORECLR
            get
            {
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
            }
        }
 
        public override Type[] GetExportedTypes()
        {
            throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
        }
 
        public override String ImageRuntimeVersion
        {
            get
            {
                return RuntimeEnvironment.GetSystemVersion();
            }
        }
        #endregion
    }
 
    // AssemblyBuilder class.
    // deliberately not [serializable]
    [HostProtection(MayLeakOnAbort = true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(_AssemblyBuilder))]
    [ComVisible(true)]
    public sealed class AssemblyBuilder : Assembly, _AssemblyBuilder
    {
        #region FCALL
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private static extern RuntimeModule GetInMemoryAssemblyModule(RuntimeAssembly assembly);
 
        [System.Security.SecurityCritical]  // auto-generated
        private Module nGetInMemoryAssemblyModule()
        {
            return AssemblyBuilder.GetInMemoryAssemblyModule(GetNativeHandle());
        }
 
#if !FEATURE_CORECLR
        [System.Security.SecurityCritical]  // auto-generated
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private static extern RuntimeModule GetOnDiskAssemblyModule(RuntimeAssembly assembly);
 
        [System.Security.SecurityCritical]  // auto-generated
        private ModuleBuilder GetOnDiskAssemblyModuleBuilder()
        {
            if (m_onDiskAssemblyModuleBuilder == null)
            {
                Module module = AssemblyBuilder.GetOnDiskAssemblyModule(InternalAssembly.GetNativeHandle());
                ModuleBuilder modBuilder = new ModuleBuilder(this, (InternalModuleBuilder)module);
                modBuilder.Init("RefEmit_OnDiskManifestModule", null, 0);
                m_onDiskAssemblyModuleBuilder = modBuilder;
            }
 
            return m_onDiskAssemblyModuleBuilder;
        }
#endif // FEATURE_CORECLR
 
        #endregion
 
        #region Internal Data Members
        // This is only valid in the "external" AssemblyBuilder
        internal AssemblyBuilderData m_assemblyData;
        private InternalAssemblyBuilder m_internalAssemblyBuilder;
        private ModuleBuilder m_manifestModuleBuilder;
        // Set to true if the manifest module was returned by code:DefineDynamicModule to the user
        private bool m_fManifestModuleUsedAsDefinedModule;
        internal const string MANIFEST_MODULE_NAME = "RefEmit_InMemoryManifestModule";
#if !FEATURE_CORECLR
        private ModuleBuilder m_onDiskAssemblyModuleBuilder;
#endif // !FEATURE_CORECLR
 
#if FEATURE_APPX
        private bool m_profileAPICheck;
#endif
 
        internal ModuleBuilder GetModuleBuilder(InternalModuleBuilder module)
        {
            Contract.Requires(module != null);
            Contract.Assert(this.InternalAssembly == module.Assembly);
 
            lock(SyncRoot)
            {
#if !FEATURE_CORECLR
                foreach (ModuleBuilder modBuilder in m_assemblyData.m_moduleBuilderList)
                {
                    if (modBuilder.InternalModule == module)
                        return modBuilder;
                }
 
                // m_onDiskAssemblyModuleBuilder is null before Save
                if (m_onDiskAssemblyModuleBuilder != null && m_onDiskAssemblyModuleBuilder.InternalModule == module)
                    return m_onDiskAssemblyModuleBuilder;
#endif // !FEATURE_CORECLR
 
                // in CoreCLR there is only one module in each dynamic assembly, the manifest module
                if (m_manifestModuleBuilder.InternalModule == module)
                    return m_manifestModuleBuilder;
 
                throw new ArgumentException("module");
            }
        }
 
        internal object SyncRoot
        {
            get
            {
                return InternalAssembly.SyncRoot;
            }
        }
 
        internal InternalAssemblyBuilder InternalAssembly
        {
            get
            {
                return m_internalAssemblyBuilder;
            }
        }
 
        internal RuntimeAssembly GetNativeHandle()
        {
            return InternalAssembly.GetNativeHandle();
        }
 
        [SecurityCritical]
        internal Version GetVersion()
        {
            return InternalAssembly.GetVersion();
        }
 
#if FEATURE_APPX
        internal bool ProfileAPICheck
        {
            get
            {
                return m_profileAPICheck;
            }
        }
#endif
        #endregion
 
        #region Constructor
        [System.Security.SecurityCritical]  // auto-generated
        internal AssemblyBuilder(AppDomain domain,
                                 AssemblyName name,
                                 AssemblyBuilderAccess access,
                                 String dir,
                                 Evidence evidence,
                                 PermissionSet requiredPermissions,
                                 PermissionSet optionalPermissions,
                                 PermissionSet refusedPermissions,
                                 ref StackCrawlMark stackMark,
                                 IEnumerable<CustomAttributeBuilder> unsafeAssemblyAttributes,
                                 SecurityContextSource securityContextSource)
        {
            if (name == null)
                throw new ArgumentNullException("name");
 
            if (access != AssemblyBuilderAccess.Run
#if !FEATURE_CORECLR
                && access != AssemblyBuilderAccess.Save
                && access != AssemblyBuilderAccess.RunAndSave
#endif // !FEATURE_CORECLR
#if FEATURE_REFLECTION_ONLY_LOAD
                && access != AssemblyBuilderAccess.ReflectionOnly
#endif // FEATURE_REFLECTION_ONLY_LOAD
#if FEATURE_COLLECTIBLE_TYPES
                && access != AssemblyBuilderAccess.RunAndCollect
#endif // FEATURE_COLLECTIBLE_TYPES
                )
            {
                throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)access), "access");
            }
 
            if (securityContextSource < SecurityContextSource.CurrentAppDomain ||
                securityContextSource > SecurityContextSource.CurrentAssembly)
            {
                throw new ArgumentOutOfRangeException("securityContextSource");
            }
 
            // Clone the name in case the caller modifies it underneath us.
            name = (AssemblyName)name.Clone();
            
#if !FEATURE_CORECLR
            // Set the public key from the key pair if one has been provided.
            // (Overwite any public key in the Assembly name, since it's no
            // longer valid to have a disparity).
            if (name.KeyPair != null)
                name.SetPublicKey(name.KeyPair.PublicKey);
#endif
 
            // If the caller is trusted they can supply identity
            // evidence for the new assembly. Otherwise we copy the
            // current grant and deny sets from the caller's assembly,
            // inject them into the new assembly and mark policy as
            // resolved. If/when the assembly is persisted and
            // reloaded, the normal rules for gathering evidence will
            // be used.
            if (evidence != null)
#pragma warning disable 618
                new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
#pragma warning restore 618
 
#if FEATURE_COLLECTIBLE_TYPES && !FEATURE_CORECLR
            // Collectible assemblies require FullTrust. This demand may be removed if we deem the
            // feature robust enough to be used directly by untrusted API consumers.
            if (access == AssemblyBuilderAccess.RunAndCollect)
                new PermissionSet(PermissionState.Unrestricted).Demand();
#endif // FEATURE_COLLECTIBLE_TYPES && !FEATURE_CORECLR
 
            // Scan the assembly level attributes for any attributes which modify how we create the
            // assembly. Currently, we look for any attribute which modifies the security transparency
            // of the assembly.
            List<CustomAttributeBuilder> assemblyAttributes = null;
            DynamicAssemblyFlags assemblyFlags = DynamicAssemblyFlags.None;
            byte[] securityRulesBlob = null;
            byte[] aptcaBlob = null;
            if (unsafeAssemblyAttributes != null)
            {
                // Create a copy to ensure that it cannot be modified from another thread
                // as it is used further below.
                assemblyAttributes = new List<CustomAttributeBuilder>(unsafeAssemblyAttributes);
 
#pragma warning disable 618 // We deal with legacy attributes here as well for compat
                foreach (CustomAttributeBuilder attribute in assemblyAttributes)
                {
                    if (attribute.m_con.DeclaringType == typeof(SecurityTransparentAttribute))
                    {
                        assemblyFlags |= DynamicAssemblyFlags.Transparent;
                    }
                    else if (attribute.m_con.DeclaringType == typeof(SecurityCriticalAttribute))
                    {
#if !FEATURE_CORECLR
                        SecurityCriticalScope scope = SecurityCriticalScope.Everything;
                        if (attribute.m_constructorArgs != null &&
                            attribute.m_constructorArgs.Length == 1 &&
                            attribute.m_constructorArgs[0] is SecurityCriticalScope)
                        {
                            scope = (SecurityCriticalScope)attribute.m_constructorArgs[0];
                        }
 
                        assemblyFlags |= DynamicAssemblyFlags.Critical;
                        if (scope == SecurityCriticalScope.Everything)
#endif // !FEATURE_CORECLR
                        {
                            assemblyFlags |= DynamicAssemblyFlags.AllCritical;
                        }
                    }
#if !FEATURE_CORECLR
                    else if (attribute.m_con.DeclaringType == typeof(SecurityRulesAttribute))
                    {
                        securityRulesBlob = new byte[attribute.m_blob.Length];
                        Array.Copy(attribute.m_blob, securityRulesBlob, securityRulesBlob.Length);
                    }
                    else if (attribute.m_con.DeclaringType == typeof(SecurityTreatAsSafeAttribute))
                    {
                        assemblyFlags |= DynamicAssemblyFlags.TreatAsSafe;
                    }
#endif // !FEATURE_CORECLR
#if FEATURE_APTCA
                    else if (attribute.m_con.DeclaringType == typeof(AllowPartiallyTrustedCallersAttribute))
                    {
                        assemblyFlags |= DynamicAssemblyFlags.Aptca;
                        aptcaBlob = new byte[attribute.m_blob.Length];
                        Array.Copy(attribute.m_blob, aptcaBlob, aptcaBlob.Length);
                    }
#endif // FEATURE_APTCA
                }
#pragma warning restore 618
            }
 
            m_internalAssemblyBuilder = (InternalAssemblyBuilder)nCreateDynamicAssembly(domain,
                                                                                        name,
                                                                                        evidence,
                                                                                        ref stackMark,
                                                                                        requiredPermissions,
                                                                                        optionalPermissions,
                                                                                        refusedPermissions,
                                                                                        securityRulesBlob,
                                                                                        aptcaBlob,
                                                                                        access,
                                                                                        assemblyFlags,
                                                                                        securityContextSource);
 
            m_assemblyData = new AssemblyBuilderData(m_internalAssemblyBuilder,
                                                     name.Name,
                                                     access,
                                                     dir);
            m_assemblyData.AddPermissionRequests(requiredPermissions,
                                                 optionalPermissions,
                                                 refusedPermissions);
 
#if FEATURE_APPX
            if (AppDomain.ProfileAPICheck)
            {
                RuntimeAssembly creator = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
                if (creator != null && !creator.IsFrameworkAssembly())
                    m_profileAPICheck = true;
            }
#endif
            // Make sure that ManifestModule is properly initialized
            // We need to do this before setting any CustomAttribute
            InitManifestModule();
 
            if (assemblyAttributes != null)
            {
                foreach (CustomAttributeBuilder assemblyAttribute in assemblyAttributes)
                    SetCustomAttribute(assemblyAttribute);
            }
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        private void InitManifestModule()
        {
            InternalModuleBuilder modBuilder = (InternalModuleBuilder)nGetInMemoryAssemblyModule();
 
            // Note that this ModuleBuilder cannot be used for RefEmit yet
            // because it hasn't been initialized.
            // However, it can be used to set the custom attribute on the Assembly
            m_manifestModuleBuilder = new ModuleBuilder(this, modBuilder);
            
            // We are only setting the name in the managed ModuleBuilderData here.
            // The name in the underlying metadata will be set when the
            // manifest module is created during nCreateDynamicAssembly.
 
            // This name needs to stay in sync with that used in
            // Assembly::Init to call ReflectionModule::Create (in VM)
            m_manifestModuleBuilder.Init(AssemblyBuilder.MANIFEST_MODULE_NAME, null, 0);
 
            m_fManifestModuleUsedAsDefinedModule = false;
        }
        #endregion
 
        #region DefineDynamicAssembly
 
        /**********************************************
        * If an AssemblyName has a public key specified, the assembly is assumed
        * to have a strong name and a hash will be computed when the assembly
        * is saved.
        **********************************************/
        [System.Security.SecuritySafeCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public static AssemblyBuilder DefineDynamicAssembly(
            AssemblyName name,
            AssemblyBuilderAccess access)
        {
            Contract.Ensures(Contract.Result<AssemblyBuilder>() != null);
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return InternalDefineDynamicAssembly(name, access, null,
                                                 null, null, null, null, ref stackMark, null, SecurityContextSource.CurrentAssembly);
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public static AssemblyBuilder DefineDynamicAssembly(
            AssemblyName name,
            AssemblyBuilderAccess access,
            IEnumerable<CustomAttributeBuilder> assemblyAttributes)
        {
            Contract.Ensures(Contract.Result<AssemblyBuilder>() != null);
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return InternalDefineDynamicAssembly(name,
                                                 access,
                                                 null, null, null, null, null,
                                                 ref stackMark,
                                                 assemblyAttributes, SecurityContextSource.CurrentAssembly);
        }
 
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private static extern Assembly nCreateDynamicAssembly(AppDomain domain,
                                                              AssemblyName name,
                                                              Evidence identity,
                                                              ref StackCrawlMark stackMark,
                                                              PermissionSet requiredPermissions,
                                                              PermissionSet optionalPermissions,
                                                              PermissionSet refusedPermissions,
                                                              byte[] securityRulesBlob,
                                                              byte[] aptcaBlob,
                                                              AssemblyBuilderAccess access,
                                                              DynamicAssemblyFlags flags,
                                                              SecurityContextSource securityContextSource);
 
        private class AssemblyBuilderLock { }
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        internal static AssemblyBuilder InternalDefineDynamicAssembly(
            AssemblyName name,
            AssemblyBuilderAccess access,
            String dir,
            Evidence evidence,
            PermissionSet requiredPermissions,
            PermissionSet optionalPermissions,
            PermissionSet refusedPermissions,
            ref StackCrawlMark stackMark,
            IEnumerable<CustomAttributeBuilder> unsafeAssemblyAttributes,
            SecurityContextSource securityContextSource)
        {
#if FEATURE_CAS_POLICY
            if (evidence != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
            {
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
            }
#endif // FEATURE_CAS_POLICY
 
            lock (typeof(AssemblyBuilderLock))
            {
                // we can only create dynamic assemblies in the current domain
                return new AssemblyBuilder(AppDomain.CurrentDomain,
                                           name,
                                           access,
                                           dir,
                                           evidence,
                                           requiredPermissions,
                                           optionalPermissions,
                                           refusedPermissions,
                                           ref stackMark,
                                           unsafeAssemblyAttributes,
                                           securityContextSource);
            } //lock(typeof(AssemblyBuilderLock))
        }
        #endregion
 
        #region DefineDynamicModule
        /**********************************************
        *
        * Defines a named dynamic module. It is an error to define multiple 
        * modules within an Assembly with the same name. This dynamic module is
        * a transient module.
        * 
        **********************************************/
        [System.Security.SecuritySafeCritical]  // auto-generated
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public ModuleBuilder DefineDynamicModule(
            String      name)
        {
            Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return DefineDynamicModuleInternal(name, false, ref stackMark);
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public ModuleBuilder DefineDynamicModule(
            String      name,
            bool        emitSymbolInfo)         // specify if emit symbol info or not
        {
            Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return DefineDynamicModuleInternal( name, emitSymbolInfo, ref stackMark );
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        private ModuleBuilder DefineDynamicModuleInternal(
            String      name,
            bool        emitSymbolInfo,         // specify if emit symbol info or not
            ref StackCrawlMark stackMark)
        {
            lock(SyncRoot)
            {
                return DefineDynamicModuleInternalNoLock(name, emitSymbolInfo, ref stackMark);
            }
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        private ModuleBuilder DefineDynamicModuleInternalNoLock(
            String      name,
            bool        emitSymbolInfo,         // specify if emit symbol info or not
            ref StackCrawlMark stackMark)
        {
            if (name == null)
                throw new ArgumentNullException("name");
            if (name.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
            if (name[0] == '\0')
                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), "name");
            Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
            Contract.EndContractBlock();
 
            BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineDynamicModule( " + name + " )");
 
            Contract.Assert(m_assemblyData != null, "m_assemblyData is null in DefineDynamicModuleInternal");
 
            ModuleBuilder dynModule;
            ISymbolWriter writer = null;
            IntPtr pInternalSymWriter = new IntPtr();
 
            // create the dynamic module
 
#if FEATURE_MULTIMODULE_ASSEMBLIES
 
#if FEATURE_CORECLR
#error FEATURE_MULTIMODULE_ASSEMBLIES should always go with !FEATURE_CORECLR
#endif //FEATURE_CORECLR
 
            m_assemblyData.CheckNameConflict(name);
 
            if (m_fManifestModuleUsedAsDefinedModule == true)
            {   // We need to define a new module
                int tkFile;
                InternalModuleBuilder internalDynModule = (InternalModuleBuilder)DefineDynamicModule(
                    InternalAssembly, 
                    emitSymbolInfo, 
                    name,
                    name,
                    ref stackMark, 
                    ref pInternalSymWriter,
                    true /*fIsTransient*/,
                    out tkFile);
                dynModule = new ModuleBuilder(this, internalDynModule);
 
                // initialize the dynamic module's managed side information
                dynModule.Init(name, null, tkFile);
            }
            else
            {   // We will reuse the manifest module
                m_manifestModuleBuilder.ModifyModuleName(name);
                dynModule = m_manifestModuleBuilder;
 
                if (emitSymbolInfo)
                {
                    pInternalSymWriter = ModuleBuilder.nCreateISymWriterForDynamicModule(dynModule.InternalModule, name);
                }
            }
 
#else // FEATURE_MULTIMODULE_ASSEMBLIES
            // Without FEATURE_MULTIMODULE_ASSEMBLIES only one ModuleBuilder per AssemblyBuilder can be created
            if (m_fManifestModuleUsedAsDefinedModule == true)
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoMultiModuleAssembly"));
 
            // Init(...) has already been called on m_manifestModuleBuilder in InitManifestModule()
            dynModule = m_manifestModuleBuilder;
#endif // FEATURE_MULTIMODULE_ASSEMBLIES
 
            // Create the symbol writer
            if (emitSymbolInfo)
            {
#if FEATURE_MULTIMODULE_ASSEMBLIES && !FEATURE_CORECLR
                // this is the code path for the desktop runtime
 
                // create the default SymWriter
                Assembly assem = LoadISymWrapper();
                Type symWriter = assem.GetType("System.Diagnostics.SymbolStore.SymWriter", true, false);
                if (symWriter != null && !symWriter.IsVisible)
                    symWriter = null;
 
                if (symWriter == null)
                {
                    // cannot find SymWriter - throw TypeLoadException since we couldnt find the type.
                    throw new TypeLoadException(Environment.GetResourceString(ResId.MissingType, "SymWriter"));
                }
 
                new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
 
                try
                {
                    (new PermissionSet(PermissionState.Unrestricted)).Assert();
                    writer = (ISymbolWriter)Activator.CreateInstance(symWriter);
 
                    // Set the underlying writer for the managed writer
                    // that we're using.  Note that this function requires
                    // unmanaged code access.
                    writer.SetUnderlyingWriter(pInternalSymWriter);
                }
                finally
                {
                    CodeAccessPermission.RevertAssert();
                }
#endif // FEATURE_MULTIMODULE_ASSEMBLIES && !FEATURE_CORECLR
 
#if !FEATURE_MULTIMODULE_ASSEMBLIES && FEATURE_CORECLR
                // this is the code path for CoreCLR
 
                writer = SymWrapperCore.SymWriter.CreateSymWriter();
                // Set the underlying writer for the managed writer
                // that we're using.  Note that this function requires
                // unmanaged code access.
#pragma warning disable 618
                new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
#pragma warning restore 618

                String fileName = "Unused"; // this symfile is never written to disk so filename does not matter.
                
                // Pass the "real" module to the VM
                pInternalSymWriter = ModuleBuilder.nCreateISymWriterForDynamicModule(dynModule.InternalModule, fileName);
 
                // In Telesto, we took the SetUnderlyingWriter method private as it's a very rickety method.
                // This might someday be a good move for the desktop CLR too.
                ((SymWrapperCore.SymWriter)writer).InternalSetUnderlyingWriter(pInternalSymWriter);
#endif // !FEATURE_MULTIMODULE_ASSEMBLIES && FEATURE_CORECLR
            } // Creating the symbol writer
 
            dynModule.SetSymWriter(writer);
            m_assemblyData.AddModule(dynModule);
 
            if (dynModule == m_manifestModuleBuilder)
            {   // We are reusing manifest module as user-defined dynamic module
                m_fManifestModuleUsedAsDefinedModule = true;
            }
 
            return dynModule;
        } // DefineDynamicModuleInternalNoLock
 
#if !FEATURE_CORECLR
        // All dynamic modules in SilverLight are transient so we removed this overload of DefineDynamicModule
        // Note that it is assumed that !FEATURE_CORECLR always goes with FEATURE_MULTIMODULE_ASSEMBLIES
        // If we ever will build a non coreclr version of the runtime without FEATURE_MULTIMODULE_ASSEMBLIES
        // we will need to make the same changes here as the ones we made in the transient overload
 
        /**********************************************
        *
        * Defines a named dynamic module. It is an error to define multiple 
        * modules within an Assembly with the same name. No symbol information
        * will be emitted.
        * 
        **********************************************/
        [System.Security.SecuritySafeCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public ModuleBuilder DefineDynamicModule(
            String name,
            String fileName)
        {
            Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
 
            // delegate to the next DefineDynamicModule 
            return DefineDynamicModuleInternal(name, fileName, false, ref stackMark);
        }
 
        /**********************************************
        *
        * Emit symbol information if emitSymbolInfo is true using the
        * default symbol writer interface.
        * An exception will be thrown if the assembly is transient.
        *
        **********************************************/
        [System.Security.SecuritySafeCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public ModuleBuilder DefineDynamicModule(
            String name,                   // module name
            String fileName,               // module file name
            bool emitSymbolInfo)         // specify if emit symbol info or not
        {
            Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return DefineDynamicModuleInternal(name, fileName, emitSymbolInfo, ref stackMark);
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        private ModuleBuilder DefineDynamicModuleInternal(
            String name,                   // module name
            String fileName,               // module file name
            bool emitSymbolInfo,         // specify if emit symbol info or not
            ref StackCrawlMark stackMark)       // stack crawl mark used to find caller
        {
            lock(SyncRoot)
            {
                return DefineDynamicModuleInternalNoLock(name, fileName, emitSymbolInfo, ref stackMark);
            }
        }
 
        // "name" will be used for:
        //     1. The Name field in the Module table.
        //     2. ModuleBuilder.GetModule(string).
        // "fileName" will be used for:
        //     1. The name field in the ModuleRef table when this module is being referenced by
        //        another module in the same assembly.
        //     2. .file record in the in memory assembly manifest when the module is created in memory 
        //     3. .file record in the on disk assembly manifest when the assembly is saved to disk 
        //     4. The file name of the saved module.
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        private ModuleBuilder DefineDynamicModuleInternalNoLock(
            String name,                        // module name
            String fileName,                    // module file name
            bool   emitSymbolInfo,              // specify if emit symbol info or not
            ref    StackCrawlMark stackMark)    // stack crawl mark used to find caller
        {
            if (name == null)
                throw new ArgumentNullException("name");
            if (name.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
            if (name[0] == '\0')
                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), "name");
 
            if (fileName == null)
                throw new ArgumentNullException("fileName");
            if (fileName.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "fileName");
            if (!String.Equals(fileName, Path.GetFileName(fileName)))
                throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName");
            Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
            Contract.EndContractBlock();
 
            BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineDynamicModule( " + name + ", " + fileName + ", " + emitSymbolInfo + " )");
            if (m_assemblyData.m_access == AssemblyBuilderAccess.Run)
            {
                // Error! You cannot define a persistable module within a transient data.
                throw new NotSupportedException(Environment.GetResourceString("Argument_BadPersistableModuleInTransientAssembly"));
            }
 
            if (m_assemblyData.m_isSaved == true)
            {
                // assembly has been saved before!
                throw new InvalidOperationException(Environment.GetResourceString(
                    "InvalidOperation_CannotAlterAssembly"));
            }
 
            ModuleBuilder dynModule;
            ISymbolWriter writer = null;
            IntPtr pInternalSymWriter = new IntPtr();
 
            // create the dynamic module
 
            m_assemblyData.CheckNameConflict(name);
            m_assemblyData.CheckFileNameConflict(fileName);
 
            int tkFile;
            InternalModuleBuilder internalDynModule = (InternalModuleBuilder)DefineDynamicModule(
                InternalAssembly,
                emitSymbolInfo,
                name,
                fileName,
                ref stackMark,
                ref pInternalSymWriter,
                false /*fIsTransient*/,
                out tkFile);
            dynModule = new ModuleBuilder(this, internalDynModule);
 
            // initialize the dynamic module's managed side information
            dynModule.Init(name, fileName, tkFile);
 
            // Create the symbol writer
            if (emitSymbolInfo)
            {
                // create the default SymWriter
                Assembly assem = LoadISymWrapper();
                Type symWriter = assem.GetType("System.Diagnostics.SymbolStore.SymWriter", true, false);
                if (symWriter != null && !symWriter.IsVisible)
                    symWriter = null;
 
                if (symWriter == null)
                {
                    // cannot find SymWriter - throw TypeLoadException since we couldnt find the type.
                    throw new TypeLoadException(Environment.GetResourceString("MissingType", "SymWriter"));
                }
                try
                {
                    (new PermissionSet(PermissionState.Unrestricted)).Assert();
                    writer = (ISymbolWriter)Activator.CreateInstance(symWriter);
 
                    // Set the underlying writer for the managed writer
                    // that we're using.  Note that this function requires
                    // unmanaged code access.
                    writer.SetUnderlyingWriter(pInternalSymWriter);
                }
                finally
                {
                    CodeAccessPermission.RevertAssert();
                }
            }
 
            dynModule.SetSymWriter(writer);
 
            m_assemblyData.AddModule(dynModule);
 
            return dynModule;
        } // DefineDynamicModuleInternalNoLock
#endif // !FEATURE_CORECLR
        #endregion
 
        private Assembly LoadISymWrapper()
        {
            if (m_assemblyData.m_ISymWrapperAssembly != null)
                return m_assemblyData.m_ISymWrapperAssembly;
 
            Assembly assem = Assembly.Load("ISymWrapper, Version=" + ThisAssembly.Version +
                ", Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken);
 
            m_assemblyData.m_ISymWrapperAssembly = assem;
            return assem;
        }
 
        internal void CheckContext(params Type[][] typess)
        {
            if (typess == null)
                return;
            
            foreach(Type[] types in typess)
                if (types != null)
                    CheckContext(types);
        }
 
        internal void CheckContext(params Type[] types)
        {
            if (types == null)
                return;
        
            foreach (Type type in types)
            {
                if (type == null)
                    continue;
 
                if (type.Module == null || type.Module.Assembly == null)
                    throw new ArgumentException(Environment.GetResourceString("Argument_TypeNotValid"));
 
                if (type.Module.Assembly == typeof(object).Module.Assembly)
                    continue;
 
                if (type.Module.Assembly.ReflectionOnly && !ReflectionOnly)
                    throw new InvalidOperationException(Environment.GetResourceString("Arugment_EmitMixedContext1", type.AssemblyQualifiedName));
 
                if (!type.Module.Assembly.ReflectionOnly && ReflectionOnly)
                    throw new InvalidOperationException(Environment.GetResourceString("Arugment_EmitMixedContext2", type.AssemblyQualifiedName));
            }
        }
 
#if !FEATURE_CORECLR
        /**********************************************
        *
        * Define stand alone managed resource for Assembly
        *
        **********************************************/
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        public IResourceWriter DefineResource(
            String      name,
            String      description,
            String      fileName)
        {
            return DefineResource(name, description, fileName, ResourceAttributes.Public);
        }
 
        /**********************************************
        *
        * Define stand alone managed resource for Assembly
        *
        **********************************************/
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        public IResourceWriter DefineResource(
            String      name,
            String      description,
            String      fileName,
            ResourceAttributes attribute)
        {
            lock(SyncRoot)
            {
                return DefineResourceNoLock(name, description, fileName, attribute);
            }
        }
 
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        private IResourceWriter DefineResourceNoLock(
            String      name,
            String      description,
            String      fileName,
            ResourceAttributes attribute)
        {
            if (name == null)
                throw new ArgumentNullException("name");
            if (name.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), name);
            if (fileName == null)
                throw new ArgumentNullException("fileName");
            if (fileName.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "fileName");
            if (!String.Equals(fileName, Path.GetFileName(fileName)))
                throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName");
            Contract.EndContractBlock();
 
            BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineResource( " + name + ", " + fileName + ")");
 
            m_assemblyData.CheckResNameConflict(name);
            m_assemblyData.CheckFileNameConflict(fileName);
 
            ResourceWriter resWriter;
            String  fullFileName;
 
            if (m_assemblyData.m_strDir == null)
            {
                // If assembly directory is null, use current directory
                fullFileName = Path.Combine(Environment.CurrentDirectory, fileName);
                resWriter = new ResourceWriter(fullFileName);
            }
            else
            {
                // Form the full path given the directory provided by user
                fullFileName = Path.Combine(m_assemblyData.m_strDir, fileName);
                resWriter = new ResourceWriter(fullFileName);
            }
            // get the full path
            fullFileName = Path.GetFullPath(fullFileName);
            
            // retrieve just the file name
            fileName = Path.GetFileName(fullFileName);
            
            m_assemblyData.AddResWriter( new ResWriterData( resWriter, null, name, fileName, fullFileName, attribute) );
            return resWriter;
        }
 
#endif // !FEATURE_CORECLR
 
        /**********************************************
        *
        * Add an existing resource file to the Assembly
        *
        **********************************************/
        #if FEATURE_CORECLR
        [System.Security.SecurityCritical] // auto-generated
        #endif
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        public void AddResourceFile(
            String      name,
            String      fileName)
        {
            AddResourceFile(name, fileName, ResourceAttributes.Public);
        }
 
        /**********************************************
        *
        * Add an existing resource file to the Assembly
        *
        **********************************************/
        #if FEATURE_CORECLR
        [System.Security.SecurityCritical] // auto-generated
        #endif
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        public void AddResourceFile(
            String      name,
            String      fileName,
            ResourceAttributes attribute)
        {
            lock(SyncRoot)
            {
                AddResourceFileNoLock(name, fileName, attribute);
            }
        }
 
        [System.Security.SecuritySafeCritical]
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        private void AddResourceFileNoLock(
            String      name,
            String      fileName,
            ResourceAttributes attribute)
        {
            if (name == null)
                throw new ArgumentNullException("name");
            if (name.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), name);
            if (fileName == null)
                throw new ArgumentNullException("fileName");
            if (fileName.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), fileName);
            if (!String.Equals(fileName, Path.GetFileName(fileName)))
                throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName");
            Contract.EndContractBlock();
 
            BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.AddResourceFile( " + name + ", " + fileName + ")");
 
            m_assemblyData.CheckResNameConflict(name);
            m_assemblyData.CheckFileNameConflict(fileName);
 
            String  fullFileName;
 
            if (m_assemblyData.m_strDir == null)
            {
                // If assembly directory is null, use current directory
                fullFileName = Path.Combine(Environment.CurrentDirectory, fileName);
            }
            else
            {
                // Form the full path given the directory provided by user
                fullFileName = Path.Combine(m_assemblyData.m_strDir, fileName);
            }
            
            // get the full path
            fullFileName = Path.UnsafeGetFullPath(fullFileName);
            
            // retrieve just the file name
            fileName = Path.GetFileName(fullFileName);
            
            if (File.UnsafeExists(fullFileName) == false)
                throw new FileNotFoundException(Environment.GetResourceString(
                    "IO.FileNotFound_FileName",
                    fileName), fileName);
            m_assemblyData.AddResWriter( new ResWriterData( null, null, name, fileName, fullFileName, attribute) );
        }
 
        #region object overrides
        public override bool Equals(object obj)
        {
            return InternalAssembly.Equals(obj);
        }
        // Need a dummy GetHashCode to pair with Equals
        public override int GetHashCode() { return InternalAssembly.GetHashCode(); }
        #endregion
 
        #region ICustomAttributeProvider Members
        public override Object[] GetCustomAttributes(bool inherit)
        {
            return InternalAssembly.GetCustomAttributes(inherit);
        }
 
        public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
        {
            return InternalAssembly.GetCustomAttributes(attributeType, inherit);
        }
 
        public override bool IsDefined(Type attributeType, bool inherit)
        {
            return InternalAssembly.IsDefined(attributeType, inherit);
        }
 
        public override IList<CustomAttributeData> GetCustomAttributesData()
        {
            return InternalAssembly.GetCustomAttributesData();
        }
        #endregion
 
        #region Assembly overrides
        // Returns the names of all the resources
        public override String[] GetManifestResourceNames()
        {
            return InternalAssembly.GetManifestResourceNames();
        }
        
        #if FEATURE_CORECLR
        [System.Security.SecurityCritical] // auto-generated
        #endif
        public override FileStream GetFile(String name)
        {
            return InternalAssembly.GetFile(name);
        }
        
        #if FEATURE_CORECLR
        [System.Security.SecurityCritical] // auto-generated
        #endif
        public override FileStream[] GetFiles(bool getResourceModules)
        {
            return InternalAssembly.GetFiles(getResourceModules);
        }
        
        public override Stream GetManifestResourceStream(Type type, String name)
        {
            return InternalAssembly.GetManifestResourceStream(type, name);
        }
        
        public override Stream GetManifestResourceStream(String name)
        {
            return InternalAssembly.GetManifestResourceStream(name);
        }
                      
        public override ManifestResourceInfo GetManifestResourceInfo(String resourceName)
        {
            return InternalAssembly.GetManifestResourceInfo(resourceName);
        }
 
        public override String Location
        {
            #if FEATURE_CORECLR
            [System.Security.SecurityCritical] // auto-generated
            #endif
            get
            {
                return InternalAssembly.Location;
            }
        }
 
        public override String ImageRuntimeVersion
        {
            get
            {
                return InternalAssembly.ImageRuntimeVersion;
            }
        }
        
        public override String CodeBase
        {
            #if FEATURE_CORECLR
            [System.Security.SecurityCritical] // auto-generated
            #endif
            get
            {
                return InternalAssembly.CodeBase;
            }
        }
 
        // Override the EntryPoint method on Assembly.
        // This doesn't need to be synchronized because it is simple enough
        public override MethodInfo EntryPoint 
        {
            get 
            {
                return m_assemblyData.m_entryPointMethod;
            }
        }
 
        // Get an array of all the public types defined in this assembly
        public override Type[] GetExportedTypes()
        {
            return InternalAssembly.GetExportedTypes();
        }
 
        #if FEATURE_CORECLR
        [System.Security.SecurityCritical] // auto-generated
        #endif
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        public override AssemblyName GetName(bool copiedName)
        {
            return InternalAssembly.GetName(copiedName);
        }
 
        public override String FullName
        {
            get
            {
                return InternalAssembly.FullName;
            }
        }
 
        public override Type GetType(String name, bool throwOnError, bool ignoreCase)
        {
            return InternalAssembly.GetType(name, throwOnError, ignoreCase);
        }
 
#if FEATURE_CAS_POLICY
        public override Evidence Evidence
        {
            get
            {
                return InternalAssembly.Evidence;
            }
        }
 
        public override PermissionSet PermissionSet
        {
            [SecurityCritical]
            get
            {
                return InternalAssembly.PermissionSet;
            }
        }
 
        public override SecurityRuleSet SecurityRuleSet
        {
            get
            {
                return InternalAssembly.SecurityRuleSet;
            }
        }
#endif // FEATURE_CAS_POLICY
 
        public override Module ManifestModule
        {
            get
            {
                return m_manifestModuleBuilder.InternalModule;
            }
        }
 
        public override bool ReflectionOnly
        {
            get
            {
                return InternalAssembly.ReflectionOnly;
            }
        }
 
        public override Module GetModule(String name)
        {
            return InternalAssembly.GetModule(name);
        }
 
        public override AssemblyName[] GetReferencedAssemblies()
        {
            return InternalAssembly.GetReferencedAssemblies();
        }
 
        public override bool GlobalAssemblyCache
        {
            get
            {
                return InternalAssembly.GlobalAssemblyCache;
            }
        }
 
        public override Int64 HostContext
        {
            get
            {
                return InternalAssembly.HostContext;
            }
        }
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)]
        public override Module[] GetModules(bool getResourceModules)
        {
            return InternalAssembly.GetModules(getResourceModules);
        }
 
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [ResourceConsumption(ResourceScope.Machine | ResourceScope.Assembly)]
        public override Module[] GetLoadedModules(bool getResourceModules)
        {
            return InternalAssembly.GetLoadedModules(getResourceModules);
        }
 
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public override Assembly GetSatelliteAssembly(CultureInfo culture)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return InternalAssembly.InternalGetSatelliteAssembly(culture, null, ref stackMark);
        }
 
        // Useful for binding to a very specific version of a satellite assembly
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public override Assembly GetSatelliteAssembly(CultureInfo culture, Version version)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return InternalAssembly.InternalGetSatelliteAssembly(culture, version, ref stackMark);
        }
 
        public override bool IsDynamic
        {
            get {
                return true;
            }
        }
        #endregion
        
       
#if !FEATURE_PAL
        /**********************************************
        *
        * Add an unmanaged Version resource to the
        *  assembly
        *
        **********************************************/
        public void DefineVersionInfoResource(
            String      product, 
            String      productVersion, 
            String      company, 
            String      copyright, 
            String      trademark)
        {
            lock(SyncRoot)
            {
                DefineVersionInfoResourceNoLock(
                    product,
                    productVersion,
                    company,
                    copyright,
                    trademark);
            }
        }
 
        private void DefineVersionInfoResourceNoLock(
            String product,
            String productVersion,
            String company,
            String copyright,
            String trademark)
        {
            if (m_assemblyData.m_strResourceFileName != null ||
                m_assemblyData.m_resourceBytes != null ||
                m_assemblyData.m_nativeVersion != null)
                throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
 
            m_assemblyData.m_nativeVersion = new NativeVersionInfo();
 
            m_assemblyData.m_nativeVersion.m_strCopyright = copyright;
            m_assemblyData.m_nativeVersion.m_strTrademark = trademark;
            m_assemblyData.m_nativeVersion.m_strCompany = company;
            m_assemblyData.m_nativeVersion.m_strProduct = product;
            m_assemblyData.m_nativeVersion.m_strProductVersion = productVersion;
            m_assemblyData.m_hasUnmanagedVersionInfo = true;
            m_assemblyData.m_OverrideUnmanagedVersionInfo = true;
 
        }
        
        public void DefineVersionInfoResource()
        {
            lock(SyncRoot)
            {
                DefineVersionInfoResourceNoLock();
            }
        }
 
        private void DefineVersionInfoResourceNoLock()
        {
            if (m_assemblyData.m_strResourceFileName != null ||
                m_assemblyData.m_resourceBytes != null ||
                m_assemblyData.m_nativeVersion != null)
                throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
            
            m_assemblyData.m_hasUnmanagedVersionInfo = true;
            m_assemblyData.m_nativeVersion = new NativeVersionInfo();
        }
 
        public void DefineUnmanagedResource(Byte[] resource)
        {
            if (resource == null)
                throw new ArgumentNullException("resource");
            Contract.EndContractBlock();
 
            lock(SyncRoot)
            {
                DefineUnmanagedResourceNoLock(resource);
            }
        }
 
        private void DefineUnmanagedResourceNoLock(Byte[] resource)
        {
            if (m_assemblyData.m_strResourceFileName != null ||
                m_assemblyData.m_resourceBytes != null ||
                m_assemblyData.m_nativeVersion != null)
                throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
            
            m_assemblyData.m_resourceBytes = new byte[resource.Length];
            System.Array.Copy(resource, m_assemblyData.m_resourceBytes, resource.Length);
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        public void DefineUnmanagedResource(String resourceFileName)
        {
            if (resourceFileName == null)
                throw new ArgumentNullException("resourceFileName");
            Contract.EndContractBlock();
 
            lock(SyncRoot)
            {
                DefineUnmanagedResourceNoLock(resourceFileName);
            }
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        private void DefineUnmanagedResourceNoLock(String resourceFileName)
        {
            if (m_assemblyData.m_strResourceFileName != null ||
                m_assemblyData.m_resourceBytes != null ||
                m_assemblyData.m_nativeVersion != null)
                throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
            
            // Check caller has the right to read the file.
            string      strFullFileName;
            if (m_assemblyData.m_strDir == null)
            {
                // If assembly directory is null, use current directory
                strFullFileName = Path.Combine(Environment.CurrentDirectory, resourceFileName);
            }
            else
            {
                // Form the full path given the directory provided by user
                strFullFileName = Path.Combine(m_assemblyData.m_strDir, resourceFileName);
            }
            strFullFileName = Path.GetFullPath(resourceFileName);
            new FileIOPermission(FileIOPermissionAccess.Read, strFullFileName).Demand();
            
            if (File.Exists(strFullFileName) == false)
                throw new FileNotFoundException(Environment.GetResourceString(
                    "IO.FileNotFound_FileName",
                    resourceFileName), resourceFileName);
            m_assemblyData.m_strResourceFileName = strFullFileName;
        }
#endif // !FEATURE_PAL
        
 
        
        /**********************************************
        *
        * return a dynamic module with the specified name.
        *
        **********************************************/
        public ModuleBuilder GetDynamicModule(
            String      name)                   // the name of module for the look up
        {
            lock(SyncRoot)
            {
                return GetDynamicModuleNoLock(name);
            }
        }
 
        private ModuleBuilder GetDynamicModuleNoLock(
            String      name)                   // the name of module for the look up
        {
            if (name == null)
                throw new ArgumentNullException("name");
            if (name.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
            Contract.EndContractBlock();
 
            BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.GetDynamicModule( " + name + " )");
            int size = m_assemblyData.m_moduleBuilderList.Count;
            for (int i = 0; i < size; i++)
            {
                ModuleBuilder moduleBuilder = (ModuleBuilder) m_assemblyData.m_moduleBuilderList[i];
                if (moduleBuilder.m_moduleData.m_strModuleName.Equals(name))
                {
                    return moduleBuilder;
                }
            }
            return null;
        }
    
        /**********************************************
        *
        * Setting the entry point if the assembly builder is building
        * an exe.
        *
        **********************************************/
        #if FEATURE_CORECLR
        [System.Security.SecurityCritical] // auto-generated
        #endif
        public void SetEntryPoint(
            MethodInfo  entryMethod) 
        {
            SetEntryPoint(entryMethod, PEFileKinds.ConsoleApplication);
        }
        #if FEATURE_CORECLR
        [System.Security.SecurityCritical] // auto-generated
        #endif
        public void SetEntryPoint(
            MethodInfo  entryMethod,        // entry method for the assembly. We use this to determine the entry module
            PEFileKinds fileKind)           // file kind for the assembly.
        {
            lock(SyncRoot)
            {
                SetEntryPointNoLock(entryMethod, fileKind);
            }
        }
 
        private void SetEntryPointNoLock(
            MethodInfo  entryMethod,        // entry method for the assembly. We use this to determine the entry module
            PEFileKinds fileKind)           // file kind for the assembly.
        {
 
            if (entryMethod == null)
                throw new ArgumentNullException("entryMethod");
            Contract.EndContractBlock();
 
            BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.SetEntryPoint");
 
            Module tmpModule = entryMethod.Module;
            if (tmpModule == null || !InternalAssembly.Equals(tmpModule.Assembly))
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EntryMethodNotDefinedInAssembly"));
 
            m_assemblyData.m_entryPointMethod = entryMethod;
            m_assemblyData.m_peFileKind = fileKind;
            
#if !FEATURE_CORECLR
            // Setting the entry point
            ModuleBuilder tmpMB = tmpModule as ModuleBuilder;
            if (tmpMB != null)
                m_assemblyData.m_entryPointModule = tmpMB;
            else
                m_assemblyData.m_entryPointModule = GetModuleBuilder((InternalModuleBuilder)tmpModule);
 
            MethodToken entryMethodToken = m_assemblyData.m_entryPointModule.GetMethodToken(entryMethod);
            m_assemblyData.m_entryPointModule.SetEntryPoint(entryMethodToken);
#endif //!FEATURE_CORECLR
        }
 
 
        /**********************************************
        * Use this function if client decides to form the custom attribute blob themselves
        **********************************************/
        #if FEATURE_CORECLR
        [System.Security.SecurityCritical] // auto-generated
        #else
        [System.Security.SecuritySafeCritical]
        #endif
        [System.Runtime.InteropServices.ComVisible(true)]
        public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
        {
            if (con == null)
                throw new ArgumentNullException("con");
            if (binaryAttribute == null)
                throw new ArgumentNullException("binaryAttribute");
            Contract.EndContractBlock();
    
            lock(SyncRoot)
            {
                SetCustomAttributeNoLock(con, binaryAttribute);
            }
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        private void SetCustomAttributeNoLock(ConstructorInfo con, byte[] binaryAttribute)
        {
            TypeBuilder.DefineCustomAttribute(
                m_manifestModuleBuilder,     // pass in the in-memory assembly module
                AssemblyBuilderData.m_tkAssembly,           // This is the AssemblyDef token
                m_manifestModuleBuilder.GetConstructorToken(con).Token,
                binaryAttribute,
                false,
                typeof(System.Diagnostics.DebuggableAttribute) == con.DeclaringType);
 
            // Track the CA for persistence
            if (m_assemblyData.m_access != AssemblyBuilderAccess.Run)
            {
                // tracking the CAs for persistence
                m_assemblyData.AddCustomAttribute(con, binaryAttribute);
            }
        }
 
        /**********************************************
        * Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder
        **********************************************/
        [System.Security.SecuritySafeCritical]  // auto-generated
        public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
        {
            if (customBuilder == null)
            {
                throw new ArgumentNullException("customBuilder");
            }
            Contract.EndContractBlock();
 
            lock(SyncRoot)
            {
                SetCustomAttributeNoLock(customBuilder);
            }
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        private void SetCustomAttributeNoLock(CustomAttributeBuilder customBuilder)
        {
            customBuilder.CreateCustomAttribute(
                m_manifestModuleBuilder, 
                AssemblyBuilderData.m_tkAssembly);          // This is the AssemblyDef token 
 
            // Track the CA for persistence
            if (m_assemblyData.m_access != AssemblyBuilderAccess.Run)
            {
                m_assemblyData.AddCustomAttribute(customBuilder);
            }
        }
 
 
        /**********************************************
        *
        * Saves the assembly to disk. Also saves all dynamic modules defined
        * in this dynamic assembly. Assembly file name can be the same as one of 
        * the module's name. If so, assembly info is stored within that module.
        * Assembly file name can be different from all of the modules underneath. In
        * this case, assembly is stored stand alone. 
        *
        **********************************************/
 
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        public void Save(String assemblyFileName)       // assembly file name
        {
            Save(assemblyFileName, System.Reflection.PortableExecutableKinds.ILOnly, System.Reflection.ImageFileMachine.I386);
        }
            
        [System.Security.SecuritySafeCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        public void Save(String assemblyFileName, 
            PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
        {
            lock(SyncRoot)
            {
                SaveNoLock(assemblyFileName, portableExecutableKind, imageFileMachine);
            }
        }
 
#if FEATURE_CORECLR
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        private void SaveNoLock(String assemblyFileName, 
            PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
        {
            // AssemblyBuilderAccess.Save can never be set with FEATURE_CORECLR
            throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CantSaveTransientAssembly"));
        }
#else // FEATURE_CORECLR
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        private void SaveNoLock(String assemblyFileName, 
            PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
        {
            if (assemblyFileName == null)
                throw new ArgumentNullException("assemblyFileName");
            if (assemblyFileName.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "assemblyFileName");
            if (!String.Equals(assemblyFileName, Path.GetFileName(assemblyFileName)))
                throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "assemblyFileName");
            Contract.EndContractBlock();
 
            int i;
            int         size;
            Type        type;
            TypeBuilder typeBuilder;
            ModuleBuilder modBuilder;
            String      strModFileName;
            ModuleBuilder assemblyModule;
            ResWriterData tempRes;
            int[]       tkAttrs = null;
            int[]       tkAttrs2 = null;
            ModuleBuilder onDiskAssemblyModule;
 
            BCLDebug.Log("DYNIL","## DYNIL LOGGING: AssemblyBuilder.Save( " + assemblyFileName + " )");
 
            String tmpVersionFile = null;
 
            try 
            {
                if (m_assemblyData.m_iCABuilder != 0)
                    tkAttrs = new int[m_assemblyData.m_iCABuilder];
                if ( m_assemblyData.m_iCAs != 0)
                    tkAttrs2 = new int[m_assemblyData.m_iCAs];
    
                if (m_assemblyData.m_isSaved == true)
                {
                    // assembly has been saved before!
                    throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_AssemblyHasBeenSaved,
                        InternalAssembly.GetSimpleName()));
                }
 
                if ((m_assemblyData.m_access & AssemblyBuilderAccess.Save) != AssemblyBuilderAccess.Save)
                {
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CantSaveTransientAssembly"));
                }
    
                // Check if assembly info is supposed to be stored with one of the module files.
                assemblyModule = m_assemblyData.FindModuleWithFileName(assemblyFileName);
    
                if (assemblyModule != null)
                {
                    m_onDiskAssemblyModuleBuilder = assemblyModule;
 
                    // In memory this module is not the manifest module and has a valid file token
                    // On disk it will be the manifest module so lets clean the file token
                    // We should not retrive FileToken after the assembly has been saved
                    // If that is absolutely necessary, we need two separate fields on ModuleBuilderData:
                    // the in memory file token and the on disk file token.
                    assemblyModule.m_moduleData.FileToken = 0;
                }
                else
                {   // If assembly is to be stored alone, then no file name should conflict with it.
                    // This check will ensure resource file names are different assembly file name.
                    m_assemblyData.CheckFileNameConflict(assemblyFileName);
                }
    
                if (m_assemblyData.m_strDir == null)
                {
                    // set it to current directory
                    m_assemblyData.m_strDir = Environment.CurrentDirectory;
                }
                else if (Directory.Exists(m_assemblyData.m_strDir) == false)
                {
                    throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDirectory", 
                        m_assemblyData.m_strDir));
                }
    
                // after this point, assemblyFileName is the full path name.
                assemblyFileName = Path.Combine(m_assemblyData.m_strDir, assemblyFileName);
                assemblyFileName = Path.GetFullPath(assemblyFileName);
    
                // Check caller has the right to create the assembly file itself.
                new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Append, assemblyFileName).Demand();
    
                // 1. setup/create the IMetaDataAssemblyEmit for the on disk version
                if (assemblyModule != null)
                {
                    // prepare saving CAs on assembly def. We need to introduce the MemberRef for
                    // the CA's type first of all. This is for the case the we have embedded manifest.
                    // We need to introduce these MRs before we call PreSave where we will snap
                    // into a ondisk metadata. If we do it after this, the ondisk metadata will
                    // not contain the proper MRs.
                    //
                    for (i=0; i < m_assemblyData.m_iCABuilder; i++)
                    {
                        tkAttrs[i] = m_assemblyData.m_CABuilders[i].PrepareCreateCustomAttributeToDisk(
                            assemblyModule); 
                    }
                    for (i=0; i < m_assemblyData.m_iCAs; i++)
                    {
                        tkAttrs2[i] = assemblyModule.InternalGetConstructorToken(m_assemblyData.m_CACons[i], true).Token;
                    }
                    assemblyModule.PreSave(assemblyFileName, portableExecutableKind, imageFileMachine);
                }
    
                RuntimeModule runtimeAssemblyModule = (assemblyModule != null) ? assemblyModule.ModuleHandle.GetRuntimeModule() : null;
                PrepareForSavingManifestToDisk(GetNativeHandle(), runtimeAssemblyModule);
 
                // This function will return the embedded manifest module, an already exposed ModuleBuilder
                // created by user, or make the stand alone manifest module exposed through managed code.
                //
                onDiskAssemblyModule = GetOnDiskAssemblyModuleBuilder();
    
    #if !FEATURE_PAL
                // Set any native resources on the OnDiskAssemblyModule.
                if (m_assemblyData.m_strResourceFileName != null)
                    onDiskAssemblyModule.DefineUnmanagedResourceFileInternalNoLock(m_assemblyData.m_strResourceFileName);
                else if (m_assemblyData.m_resourceBytes != null)
                    onDiskAssemblyModule.DefineUnmanagedResourceInternalNoLock(m_assemblyData.m_resourceBytes);
                else if (m_assemblyData.m_hasUnmanagedVersionInfo == true)
                {
                    // calculate unmanaged version info from assembly's custom attributes
                    m_assemblyData.FillUnmanagedVersionInfo();
    
                    String strFileVersion = m_assemblyData.m_nativeVersion.m_strFileVersion;
                    if (strFileVersion == null)
                        strFileVersion = GetVersion().ToString();
    
                    // Create the file.
                    CreateVersionInfoResource(
                         assemblyFileName,
                         m_assemblyData.m_nativeVersion.m_strTitle,   // title
                         null, // Icon filename
                         m_assemblyData.m_nativeVersion.m_strDescription,   // description
                         m_assemblyData.m_nativeVersion.m_strCopyright,
                         m_assemblyData.m_nativeVersion.m_strTrademark,
                         m_assemblyData.m_nativeVersion.m_strCompany,
                         m_assemblyData.m_nativeVersion.m_strProduct,
                         m_assemblyData.m_nativeVersion.m_strProductVersion,
                         strFileVersion, 
                         m_assemblyData.m_nativeVersion.m_lcid,
                         m_assemblyData.m_peFileKind == PEFileKinds.Dll,
                         JitHelpers.GetStringHandleOnStack(ref tmpVersionFile));
    
                    onDiskAssemblyModule.DefineUnmanagedResourceFileInternalNoLock(tmpVersionFile);
                }
    #endif // !FEATURE_PAL
    
                if (assemblyModule == null)
                {
                
                    // This is for introducing the MRs for CA's type. This case is for stand alone
                    // manifest. We need to wait till PrepareForSavingManifestToDisk is called. 
                    // That will trigger the creation of the on-disk stand alone manifest module.
                    //
                    for (i=0; i < m_assemblyData.m_iCABuilder; i++)
                    {
                        tkAttrs[i] = m_assemblyData.m_CABuilders[i].PrepareCreateCustomAttributeToDisk(
                            onDiskAssemblyModule); 
                    }
                    for (i=0; i < m_assemblyData.m_iCAs; i++)
                    {
                        tkAttrs2[i] = onDiskAssemblyModule.InternalGetConstructorToken(m_assemblyData.m_CACons[i], true).Token;
                    }
                }
            
                // 2. save all of the persistable modules contained by this AssemblyBuilder except the module that is going to contain
                // Assembly information
                // 
                // 3. create the file list in the manifest and track the file token. If it is embedded assembly,
                // the assembly file should not be on the file list.
                // 
                size = m_assemblyData.m_moduleBuilderList.Count;
                for (i = 0; i < size; i++) 
                {
                    ModuleBuilder mBuilder = (ModuleBuilder) m_assemblyData.m_moduleBuilderList[i];
                    if (mBuilder.IsTransient() == false && mBuilder != assemblyModule)
                    {
                        strModFileName = mBuilder.m_moduleData.m_strFileName;
                        if (m_assemblyData.m_strDir != null)
                        {
                            strModFileName = Path.Combine(m_assemblyData.m_strDir, strModFileName);
                            strModFileName = Path.GetFullPath(strModFileName);
                        }
                        
                        // Check caller has the right to create the Module file itself.
                        new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Append, strModFileName).Demand();
 
                        mBuilder.m_moduleData.FileToken = AddFile(GetNativeHandle(), mBuilder.m_moduleData.m_strFileName);
                        mBuilder.PreSave(strModFileName, portableExecutableKind, imageFileMachine);
                        mBuilder.Save(strModFileName, false, portableExecutableKind, imageFileMachine);
    
                        // Cannot set the hash value when creating the file since the file token
                        // is needed to created the entries for the embedded resources in the
                        // module and the resources need to be there before you figure the hash.
                        SetFileHashValue(GetNativeHandle(), mBuilder.m_moduleData.FileToken, strModFileName);
                    }
                }
        
                // 4. Add the public ComType
                for (i=0; i < m_assemblyData.m_iPublicComTypeCount; i++)
                {
                    type = m_assemblyData.m_publicComTypeList[i];
                    // If the type that was added as a Public Com Type was obtained via Reflection,
                    //  it will be a System.RuntimeType, even if it was really, at the same time,
                    //  a TypeBuilder.  Unfortunately, you can't get back to the TypeBuilder, so 
                    //  this code has to deal with either-or.
                    if (type is RuntimeType)
                    {
                        // If type is a runtime type, it must be a baked TypeBuilder,
                        // ttype.Module should be an InternalModuleBuilder
 
                        InternalModuleBuilder internalMB = (InternalModuleBuilder)type.Module;
                        modBuilder = this.GetModuleBuilder(internalMB);
                        if (modBuilder != assemblyModule)
                            DefineNestedComType(type, modBuilder.m_moduleData.FileToken, type.MetadataToken);
                    }
                    else
                    {
                        // Could assert that "type" is a TypeBuilder, but next statement throws if it isn't.
                        typeBuilder = (TypeBuilder) type;
                        // If type is a TypeBuilder, type.Module must be a ModuleBuilder.
                        modBuilder = typeBuilder.GetModuleBuilder();
                        if (modBuilder != assemblyModule)
                            DefineNestedComType(type, modBuilder.m_moduleData.FileToken, typeBuilder.MetadataTokenInternal);
                    }
                }
    
                // 5. write AssemblyDef's CAs (only if we are not saving directly the manifest module itself)
                if (onDiskAssemblyModule != m_manifestModuleBuilder)
                {
                    for (i = 0; i < m_assemblyData.m_iCABuilder; i++)
                    {
                        m_assemblyData.m_CABuilders[i].CreateCustomAttribute(
                            onDiskAssemblyModule,
                            AssemblyBuilderData.m_tkAssembly,   // This is the AssemblyDef token
                            tkAttrs[i], true);
                    }
 
                    for (i = 0; i < m_assemblyData.m_iCAs; i++)
                    {
                        TypeBuilder.DefineCustomAttribute(
                            onDiskAssemblyModule,               // pass in the in-memory assembly module
                            AssemblyBuilderData.m_tkAssembly,   // This is the AssemblyDef token
                            tkAttrs2[i],
                            m_assemblyData.m_CABytes[i],
                            true, false);
                    }
                }
    
                // 6. write security permission requests to the manifest.
#pragma warning disable 618
                if (m_assemblyData.m_RequiredPset != null)
                    AddDeclarativeSecurity(m_assemblyData.m_RequiredPset, SecurityAction.RequestMinimum);
 
                if (m_assemblyData.m_RefusedPset != null)
                    AddDeclarativeSecurity(m_assemblyData.m_RefusedPset, SecurityAction.RequestRefuse);
 
                if (m_assemblyData.m_OptionalPset != null)
                    AddDeclarativeSecurity(m_assemblyData.m_OptionalPset, SecurityAction.RequestOptional);
#pragma warning restore 618
 
                // 7. Save the stand alone managed resources
                size = m_assemblyData.m_resWriterList.Count;
                for (i = 0; i < size; i++)
                {
                    tempRes = null;
    
                    try
                    {
                        tempRes = (ResWriterData)m_assemblyData.m_resWriterList[i];
    
                        // If the user added an existing resource to the manifest, the
                        // corresponding ResourceWriter will be null.
                        if (tempRes.m_resWriter != null)
                            // Check caller has the right to create the Resource file itself.
                            new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Append, tempRes.m_strFullFileName).Demand();
                    }
                    finally
                    {
                        if (tempRes != null && tempRes.m_resWriter != null)
                            tempRes.m_resWriter.Close();
                    }
    
                    // Add entry to manifest for this stand alone resource
                    AddStandAloneResource(GetNativeHandle(), tempRes.m_strName, tempRes.m_strFileName, tempRes.m_strFullFileName, (int)tempRes.m_attribute);
                }
    
                // Save now!!
                if (assemblyModule == null)
                {
                    onDiskAssemblyModule.DefineNativeResource(portableExecutableKind, imageFileMachine);
    
                    // Stand alone manifest
                    int entryPoint = (m_assemblyData.m_entryPointModule != null) ? m_assemblyData.m_entryPointModule.m_moduleData.FileToken : 0;
 
                    SaveManifestToDisk(GetNativeHandle(), assemblyFileName, entryPoint, (int)m_assemblyData.m_peFileKind,
                            (int)portableExecutableKind, (int)imageFileMachine);
                    }
                else
                {
                    // embedded manifest
                    
                    // If the module containing the entry point is not the manifest file, we need to
                    // let the manifest file point to the module which contains the entry point.
                    // 
                    // 
                    // 
                    // 
                    if (m_assemblyData.m_entryPointModule != null && m_assemblyData.m_entryPointModule != assemblyModule)
                        assemblyModule.SetEntryPoint(new MethodToken(m_assemblyData.m_entryPointModule.m_moduleData.FileToken));
                    assemblyModule.Save(assemblyFileName, true, portableExecutableKind, imageFileMachine);
                }
                m_assemblyData.m_isSaved = true;
            }
            finally
            {
                if (tmpVersionFile != null)
                {
                    // Delete file.
                    System.IO.File.Delete(tmpVersionFile);
                }
            }
        }
#endif // FEATURE_CORECLR
    
#if FEATURE_CAS_POLICY
        [System.Security.SecurityCritical]  // auto-generated
        private void AddDeclarativeSecurity(PermissionSet pset, SecurityAction action)
        {
            // Translate sets into internal encoding (uses standard binary serialization).
            byte[] blob = pset.EncodeXml();
            AddDeclarativeSecurity(GetNativeHandle(), action, blob, blob.Length);
        }
#endif // FEATURE_CAS_POLICY
        
        internal bool IsPersistable()
        {
#if !FEATURE_CORECLR // AssemblyBuilderAccess.Save is never set in CoreCLR
            if ((m_assemblyData.m_access & AssemblyBuilderAccess.Save) == AssemblyBuilderAccess.Save)
            {
                return true;
            }
            else
#endif // FEATURE_CORECLR
            {
                return false;
            }
        }
    
        /**********************************************
        *
        * Internal helper to walk the nested type hierachy
        *
        **********************************************/
        [System.Security.SecurityCritical]  // auto-generated
        private int DefineNestedComType(Type type, int tkResolutionScope, int tkTypeDef)
        {
            Type        enclosingType = type.DeclaringType;
            if (enclosingType == null)
            {
                // Use full type name for non-nested types.
                return AddExportedTypeOnDisk(GetNativeHandle(), type.FullName, tkResolutionScope, tkTypeDef, type.Attributes);
            }
 
            tkResolutionScope = DefineNestedComType(enclosingType, tkResolutionScope, tkTypeDef);
            // Use simple name for nested types.
            return AddExportedTypeOnDisk(GetNativeHandle(), type.Name, tkResolutionScope, tkTypeDef, type.Attributes);
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        internal int DefineExportedTypeInMemory(Type type, int tkResolutionScope, int tkTypeDef)
        {
            Type enclosingType = type.DeclaringType;
            if (enclosingType == null)
            {
                // Use full type name for non-nested types.
                return AddExportedTypeInMemory(GetNativeHandle(), type.FullName, tkResolutionScope, tkTypeDef, type.Attributes);
            }
 
            tkResolutionScope = DefineExportedTypeInMemory(enclosingType, tkResolutionScope, tkTypeDef);
            // Use simple name for nested types.
            return AddExportedTypeInMemory(GetNativeHandle(), type.Name, tkResolutionScope, tkTypeDef, type.Attributes);
        }
 
        /**********************************************
         * 
         * Private methods
         * 
         **********************************************/
    
        /**********************************************
         * Make a private constructor so these cannot be constructed externally.
         * @internonly
         **********************************************/
        private AssemblyBuilder() {}
 
#if !FEATURE_CORECLR
        void _AssemblyBuilder.GetTypeInfoCount(out uint pcTInfo)
        {
            throw new NotImplementedException();
        }
 
        void _AssemblyBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
        {
            throw new NotImplementedException();
        }
 
        void _AssemblyBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
        {
            throw new NotImplementedException();
        }
 
        // If you implement this method, make sure to include _AssemblyBuilder.Invoke in VM\DangerousAPIs.h and 
        // include _AssemblyBuilder in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
        void _AssemblyBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
        {
            throw new NotImplementedException();
        }
#endif
 
        // Create a new module in which to emit code. This module will not contain the manifest.
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine | ResourceScope.Assembly)]
        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
        [SuppressUnmanagedCodeSecurity]
        static private extern void DefineDynamicModule(RuntimeAssembly containingAssembly,
                                                       bool emitSymbolInfo,
                                                       String name,
                                                       String filename,
                                                       StackCrawlMarkHandle stackMark,
                                                       ref IntPtr pInternalSymWriter,
                                                       ObjectHandleOnStack retModule,
                                                       bool fIsTransient,
                                                       out int tkFile);
 
        [System.Security.SecurityCritical]  // auto-generated
        private static Module DefineDynamicModule(RuntimeAssembly containingAssembly, 
                                           bool emitSymbolInfo,
                                           String name,
                                           String filename,
                                           ref StackCrawlMark stackMark,
                                           ref IntPtr pInternalSymWriter,
                                           bool fIsTransient,
                                           out int tkFile)
        {
            RuntimeModule retModule = null;
 
            DefineDynamicModule(containingAssembly.GetNativeHandle(),
                                emitSymbolInfo,
                                name,
                                filename,
                                JitHelpers.GetStackCrawlMarkHandle(ref stackMark),
                                ref pInternalSymWriter,
                                JitHelpers.GetObjectHandleOnStack(ref retModule),
                                fIsTransient,
                                out tkFile);
 
            return retModule;
        }
 
        // The following functions are native helpers for creating on-disk manifest
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)]
        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
        [SuppressUnmanagedCodeSecurity]
        static private extern void PrepareForSavingManifestToDisk(RuntimeAssembly assembly, RuntimeModule assemblyModule);  // module to contain assembly information if assembly is embedded
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
        [SuppressUnmanagedCodeSecurity]
        static private extern void SaveManifestToDisk(RuntimeAssembly assembly,
                                                String strFileName, 
                                                int entryPoint,
                                                int fileKind,
                                                int portableExecutableKind, 
                                                int ImageFileMachine);
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
        [SuppressUnmanagedCodeSecurity]
        static private extern int AddFile(RuntimeAssembly assembly, String strFileName);
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
        [SuppressUnmanagedCodeSecurity]
        static private extern void SetFileHashValue(RuntimeAssembly assembly,
                                                    int tkFile, 
                                                    String strFullFileName);
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)]
        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
        [SuppressUnmanagedCodeSecurity]
        static private extern int AddExportedTypeInMemory(RuntimeAssembly assembly,
                                                          String strComTypeName,
                                                          int tkAssemblyRef,
                                                          int tkTypeDef,
                                                          TypeAttributes flags);
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)]
        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
        [SuppressUnmanagedCodeSecurity]
        static private extern int AddExportedTypeOnDisk(RuntimeAssembly assembly, 
                                                        String strComTypeName, 
                                                        int tkAssemblyRef, 
                                                        int tkTypeDef, 
                                                        TypeAttributes flags);
 
        // Add an entry to assembly's manifestResource table for a stand alone resource.
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
        [SuppressUnmanagedCodeSecurity]
        static private extern void AddStandAloneResource(RuntimeAssembly assembly,
                                                         String strName,
                                                         String strFileName,
                                                         String strFullFileName,
                                                         int attribute);
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)]
        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
        [SuppressUnmanagedCodeSecurity]
#pragma warning disable 618
        static private extern void AddDeclarativeSecurity(RuntimeAssembly assembly, SecurityAction action, byte[] blob, int length);
#pragma warning restore 618
 
#if !FEATURE_PAL
        // Functions for defining unmanaged resources.
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)]
        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
        [SuppressUnmanagedCodeSecurity]
        static private extern void CreateVersionInfoResource(String filename, String title, String iconFilename, String description,
                                                             String copyright, String trademark, String company, String product,
                                                             String productVersion, String fileVersion, int lcid, bool isDll,
                                                             StringHandleOnStack retFileName);
#endif // !FEATURE_PAL
 
    }
}