        pAssem->m_isDynamic = true;
        pAssem->m_dwDynamicAssemblyAccess = args->access;

        // Set the additional strong name information

        pAssem->SetStrongNameLevel(Assembly::SN_NONE);

        if (publicKey.GetSize() > 0) {

            pAssem->SetStrongNameLevel(Assembly::SN_PUBLIC_KEY);
            gc.strongNameKeyPair = args->assemblyName->GetStrongNameKeyPair();
            // If there's a public key, there might be a strong name key pair.
            if (gc.strongNameKeyPair!= NULL) 
            {
                MethodDescCallSite getKeyPair(METHOD__STRONG_NAME_KEY_PAIR__GET_KEY_PAIR, &gc.strongNameKeyPair);

                ARG_SLOT arglist[] = 
                {
                    ObjToArgSlot(gc.strongNameKeyPair),
                    PtrToArgSlot(&gc.orArrayOrContainer)
                };

                BOOL bKeyInArray;
                bKeyInArray = (BOOL)getKeyPair.Call_RetBool(arglist);

                if (bKeyInArray) {
                    U1ARRAYREF orArray = (U1ARRAYREF)gc.orArrayOrContainer;
                    pAssem->m_cbStrongNameKeyPair = orArray->GetNumComponents();
                    pAssem->m_pbStrongNameKeyPair = new BYTE[pAssem->m_cbStrongNameKeyPair];

                    pAssem->m_FreeFlag |= pAssem->FREE_KEY_PAIR;
                    memcpy(pAssem->m_pbStrongNameKeyPair, orArray->GetDataPtr(), pAssem->m_cbStrongNameKeyPair);
                    pAssem->SetStrongNameLevel(Assembly::SN_FULL_KEYPAIR_IN_ARRAY);
                }
                else {
                    STRINGREF orContainer = (STRINGREF)gc.orArrayOrContainer;
                    DWORD cchContainer = orContainer->GetStringLength();
                    pAssem->m_pwStrongNameKeyContainer = new WCHAR[cchContainer + 1];

                    pAssem->m_FreeFlag |= pAssem->FREE_KEY_CONTAINER;
                    memcpy(pAssem->m_pwStrongNameKeyContainer, orContainer->GetBuffer(), cchContainer * sizeof(WCHAR));
                    pAssem->m_pwStrongNameKeyContainer[cchContainer] = L'\0';

                    pAssem->SetStrongNameLevel(Assembly::SN_FULL_KEYPAIR_IN_CONTAINER);
                }
            }
        }

        //we need to suppress release for pAssem to avoid double release
        pAssem.SuppressRelease ();
        pDomainAssembly->SetAssembly(pAssem);

        // Finish loading process
        pDomainAssembly->Begin();
        pDomainAssembly->m_level = FILE_LOAD_ALLOCATE;
        pDomainAssembly->DeliverSyncEvents();
        pDomainAssembly->DeliverAsyncEvents();
        pDomainAssembly->FinishLoad();
        pDomainAssembly->ClearLoading();
        pDomainAssembly->m_level = FILE_ACTIVE;

        {
            CANNOTTHROWCOMPLUSEXCEPTION();
            FAULT_FORBID();

            //Cannot fail after this point

            pDomainAssembly.SuppressRelease(); // This also effectively suppresses the release of the pAssem 
            pamTracker->SuppressRelease();
            pAssem->SetIsTenured();
            pRetVal = pAssem;
        }
    }
    GCPROTECT_END();

    RETURN pRetVal;
}

ReflectionModule *Assembly::CreateDynamicModule(LPCWSTR name)
{
    CONTRACT(ReflectionModule *)
    {
        THROWS;
        GC_TRIGGERS;
        MODE_COOPERATIVE;
        INJECT_FAULT(COMPlusThrowOM(););
        POSTCONDITION(CheckPointer(RETVAL));
    }
    CONTRACT_END;

    AllocMemTracker amTracker;

    // Add a manifest entry for the module
    mdFile token;
    IMetaDataAssemblyEmit *pAssemblyEmit = GetManifestFile()->GetAssemblyEmitter();
    IfFailThrow(pAssemblyEmit->DefineFile(name, NULL, 0, 0, &token));

    // Define initial metadata for the module
    SafeComHolder<IMetaDataEmit> pEmit;
    PEFile::DefineEmitScope(IID_IMetaDataEmit, (void **) &pEmit);

    pEmit->SetModuleProps(name);

    // Create the PEFile for the module
    PEModuleHolder pFile(PEModule::Create(GetManifestFile(), token, pEmit));

    // Create the DomainModule
    NewHolder<DomainModule> pDomainModule(new DomainModule(GetAppDomain(), GetDomainAssembly(), pFile));

    // Create the module itself
    ReflectionModuleHolder pWrite(ReflectionModule::Create(this, pFile, &amTracker));

    amTracker.SuppressRelease();
    pWrite->SetIsTenured();

    // Modules take the DebuggerAssemblyControlFlags down from its parent Assembly initially.
    // By default, this turns on JIT optimization.
    
    pWrite->SetDebuggerInfoBits(GetDebuggerInfoBits());

    // Associate the two
    pDomainModule->SetModule(pWrite);
    m_pManifest->StoreFileThrowing(token, pWrite);

    // Simulate loading process
    pDomainModule->Begin();
    pDomainModule->DeliverSyncEvents();
    pDomainModule->DeliverAsyncEvents();
    pDomainModule->FinishLoad();
    pDomainModule->ClearLoading();
    pDomainModule->m_level = FILE_ACTIVE;

    pDomainModule.SuppressRelease();
    RETURN pWrite.Extract();
}


void Assembly::SetDomainAssembly(DomainAssembly *pDomainAssembly)
{
    CONTRACT_VOID
    {
        PRECONDITION(CheckPointer(pDomainAssembly, NULL_OK));
        THROWS;
        GC_TRIGGERS;
        INJECT_FAULT(COMPlusThrowOM(););
    }
    CONTRACT_END;

    GetManifestModule()->SetDomainFile(pDomainAssembly);

    AssemblySecurityDescriptor *pSec = pDomainAssembly->GetSecurityDescriptor();

    Security::AddToSharedDescriptor(pSec, GetSharedSecurityDescriptor());

    TIMELINE_START(LOADER, ("EarlyResolve"));

    if (!pDomainAssembly->ShouldDelayPolicyResolution())
    {
        if (g_pConfig->SecurityNeutralCode())
        {
            // If a security failure occurs, we will note it on the DomainAssembly.  However
            // we let the load proceed as passive uses of the assembly are still valid.
            EX_TRY
            {
                Security::EarlyResolveThrowing(this, pSec);
            }
            EX_CATCH
            {
                if (!GET_EXCEPTION()->IsTransient())
                    pDomainAssembly->SetSecurityError(GET_EXCEPTION());
            }
            EX_END_CATCH(RethrowTransientExceptions);
        }
        else
            Security::EarlyResolveThrowing(this, pSec);
    }

    TIMELINE_END(LOADER, ("EarlyResolve"));

    RETURN;
}

#endif // #ifndef DACCESS_COMPILE

DomainAssembly *Assembly::GetDomainAssembly(AppDomain *pDomain)
{
    CONTRACT(DomainAssembly *)
    {
        PRECONDITION(CheckPointer(pDomain, NULL_OK));
        POSTCONDITION(CheckPointer(RETVAL));
        THROWS;
        GC_TRIGGERS;
    }
    CONTRACT_END;

    RETURN GetManifestModule()->GetDomainAssembly(pDomain);
}

DomainAssembly *Assembly::FindDomainAssembly(AppDomain *pDomain)
{
    CONTRACT(DomainAssembly *)
    {
        PRECONDITION(CheckPointer(pDomain));
        POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
        NOTHROW;
        GC_NOTRIGGER;
        FORBID_FAULT;
    }
    CONTRACT_END;

    PREFIX_ASSUME (GetManifestModule()!=NULL); 
    RETURN GetManifestModule()->FindDomainAssembly(pDomain);
}

BOOL Assembly::IsIntrospectionOnly()
{
    WRAPPER_CONTRACT;
    return m_pManifestFile->IsIntrospectionOnly();
}


#ifndef DACCESS_COMPILE

ListLock*  Assembly::GetClassInitLock()
{
    WRAPPER_CONTRACT;

    return m_pDomain->GetClassInitLock();
}

LoaderHeap* Assembly::GetLowFrequencyHeap()
{
    