HttpRuntime.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / xsp / System / Web / HttpRuntime.cs / 1 / HttpRuntime.cs

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

/* 
 * The ASP.NET runtime services 
 *
 * Copyright (c) 1998 Microsoft Corporation 
 */

namespace System.Web {
    using System.Text; 
    using System.Threading;
    using System.Data; 
    using System.Data.Common; 
    using System.IO;
    using System.Collections; 
    using System.Configuration;
    using System.Globalization;
    using System.Net;
    using System.Xml; 
    using System.Reflection;
    using System.Resources; 
    using System.Security; 
    using System.Security.Permissions;
    using System.Security.Policy; 
    using System.Web;
    using System.Web.UI;
#if ORCAS
    using System.Web.UI.Imaging; 
#endif
    using System.Web.Compilation; 
    using System.Web.Util; 
    using System.Web.Configuration;
    using System.Web.Caching; 
    using System.Web.Hosting;
    using System.Web.Security;
    using System.Web.Management;
    using System.Runtime.Remoting.Messaging; 
    using Microsoft.Win32;
    using System.Security.Cryptography; 
    using System.Security.Principal; 
    using System.Runtime.InteropServices;
 

    /// 
    ///    Provides a set of ASP.NET runtime services.
    ///  
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    public sealed class HttpRuntime { 
 
        private const string codegenDirName = "Temporary ASP.NET Files";
 
        private static HttpRuntime _theRuntime;   // single instance of the class
        internal static byte[] s_autogenKeys = new byte[88];

        // 
        // Names of special ASP.NET directories
        // 
 
        internal const string BinDirectoryName = "bin";
        internal const string CodeDirectoryName = "App_Code"; 
        internal const string WebRefDirectoryName = "App_WebReferences";
        internal const string ResourcesDirectoryName = "App_GlobalResources";
        internal const string LocalResourcesDirectoryName = "App_LocalResources";
        internal const string DataDirectoryName = "App_Data"; 
        internal const string ThemesDirectoryName = "App_Themes";
        internal const string GlobalThemesDirectoryName = "Themes"; 
        internal const string BrowsersDirectoryName = "App_Browsers"; 

        private static string DirectorySeparatorString = new string(Path.DirectorySeparatorChar, 1); 
        private static string DoubleDirectorySeparatorString = new string(Path.DirectorySeparatorChar, 2);


#if OLD 
        // For s_forbiddenDirs and s_forbiddenDirsConstant, see
        // ndll.h, and RestrictIISFolders in regiis.cxx 
 
        internal static string[]    s_forbiddenDirs =   {
                                        BinDirectoryName, 
                                        CodeDirectoryName,
                                        DataDirectoryName,
                                        ResourcesDirectoryName,
                                        WebRefDirectoryName, 
                                    };
 
        internal static Int32[]     s_forbiddenDirsConstant = { 
                                        UnsafeNativeMethods.RESTRICT_BIN,
                                        UnsafeNativeMethods.RESTRICT_CODE, 
                                        UnsafeNativeMethods.RESTRICT_DATA,
                                        UnsafeNativeMethods.RESTRICT_RESOURCES,
                                        UnsafeNativeMethods.RESTRICT_WEBREFERENCES,
                                    }; 
#endif
 
        static HttpRuntime() { 
            AddAppDomainTraceMessage("*HttpRuntime::cctor");
 
            StaticInit();

            _theRuntime = new HttpRuntime();
 
            _theRuntime.Init();
 
            AddAppDomainTraceMessage("HttpRuntime::cctor*"); 
        }
 
        [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
        public HttpRuntime() {
        }
 
        //
        // static initialization to get hooked up to the unmanaged code 
        // get installation directory, etc. 
        //
 
        private static bool s_initialized = false;
        private static String s_installDirectory;
        private static bool s_isEngineLoaded = false;
 
        // Force the static initialization of this class.
        internal static void ForceStaticInit() { } 
 
        private static void StaticInit() {
            if (s_initialized) { 
                // already initialized
                return;
            }
 
            bool isEngineLoaded = false;
            bool wasEngineLoadedHere = false; 
            String installDir = null; 

            // load webengine.dll if it is not loaded already 

#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features

            installDir = RuntimeEnvironment.GetRuntimeDirectory(); 

            if (UnsafeNativeMethods.GetModuleHandle(ModName.ENGINE_FULL_NAME) != IntPtr.Zero) { 
                isEngineLoaded = true; 
            }
 
            // Load webengine.dll if not loaded already

            if (!isEngineLoaded) {
                String fullPath = installDir + Path.DirectorySeparatorChar + ModName.ENGINE_FULL_NAME; 

                if (UnsafeNativeMethods.LoadLibrary(fullPath) != IntPtr.Zero) { 
                    isEngineLoaded = true; 
                    wasEngineLoadedHere = true;
                } 
            }

            if (isEngineLoaded) {
                UnsafeNativeMethods.InitializeLibrary(); 

                if (wasEngineLoadedHere) { 
                    UnsafeNativeMethods.PerfCounterInitialize(); 
                }
            } 

#else // !FEATURE_PAL
            string p = typeof(object).Module.FullyQualifiedName;
            installDir = Path.GetDirectoryName(p); 
#endif // !FEATURE_PAL
 
            s_installDirectory = installDir; 
            s_isEngineLoaded = isEngineLoaded;
            s_initialized = true; 

            AddAppDomainTraceMessage("Initialize");
        }
 
        //
        // Runtime services 
        // 

        private NamedPermissionSet _namedPermissionSet; 
        private FileChangesMonitor _fcm;
        private CacheInternal _cacheInternal;
        private Cache _cachePublic;
        private bool _isOnUNCShare; 
        private Profiler _profiler;
        private RequestTimeoutManager _timeoutManager; 
        private RequestQueue _requestQueue; 
        private bool _apartmentThreading;
 
#if ORCAS
        private IHttpDataStorageProvider _httpDataStorageProvider;
        private HttpDataStorageCleanup _httpDataStorageCleanup;
#endif 

#if SITECOUNTERS 
        private SiteCounters            _siteCounters; 
#endif
        private bool _processRequestInApplicationTrust; 
        //
        // Counters
        //
 
        private bool _beforeFirstRequest = true;
        private DateTime _firstRequestStartTime; 
        private bool _firstRequestCompleted; 
        private bool _userForcedShutdown;
        private bool _configInited; 
        private bool _fusionInited;
        private int _activeRequestCount;
        private DateTime _lastShutdownAttemptTime;
        private bool _shutdownInProgress; 
        private String _shutDownStack;
        private String _shutDownMessage; 
        private ApplicationShutdownReason _shutdownReason = ApplicationShutdownReason.None; 
        private string _trustLevel;
        private string _wpUserId; 
        private bool _shutdownWebEventRaised;

        //
        // Header Newlines 
        //
        private bool _enableHeaderChecking; 
 
        //
        // Callbacks 
        //

        private AsyncCallback _requestNotificationCompletionCallback;
        private AsyncCallback _handlerCompletionCallback; 
        private HttpWorkerRequest.EndOfSendNotification _asyncEndOfSendCallback;
        private WaitCallback _appDomainUnloadallback; 
 
        //
        // Initialization error (to be reported on subsequent requests) 
        //

        private Exception _initializationError;
        private bool _hostingInitFailed; // make such errors non-sticky 
        private Timer _appDomainShutdownTimer = null;
 
 
        //
        // App domain related 
        //

        private String _tempDir;
        private String _codegenDir; 
        private String _appDomainAppId;
        private String _appDomainAppPath; 
        private VirtualPath _appDomainAppVPath; 
        private String _appDomainId;
 
        //
        // Debugging support
        //
 
        private bool _debuggingEnabled = false;
 
        // 
        // App_Offline.htm support
        // 

        private const string AppOfflineFileName = "App_Offline.htm";
        private const long MaxAppOfflineFileLength = 1024 * 1024;
        private byte[] _appOfflineMessage; 

        // 
        // Client script support 
        //
 
        private const string AspNetClientFilesSubDirectory = "asp.netclientfiles";
        private const string AspNetClientFilesParentVirtualPath = "/aspnet_client/system_web/";
        private string _clientScriptVirtualPath;
        private string _clientScriptPhysicalPath; 

        // 
        //  Integrated pipeline mode 
        //
        private static bool _useIntegratedPipeline; 

        /////////////////////////////////////////////////////////////////////////
        // 3 steps of initialization:
        //     Init() is called from HttpRuntime cctor 
        //     HostingInit() is called by the Hosting Environment
        //     FirstRequestInit() is called on first HTTP request 
        // 

        /* 
         * Context-less initialization (on app domain creation)
         */
        private void Init() {
            try { 
#if !FEATURE_PAL
                if (Environment.OSVersion.Platform != PlatformID.Win32NT) 
                    throw new PlatformNotSupportedException(SR.GetString(SR.RequiresNT)); 
#else // !FEATURE_PAL
                // ROTORTODO 
                // Do nothing: FEATURE_PAL environment will always support ASP.NET hosting
#endif // !FEATURE_PAL

                _profiler = new Profiler(); 
                _timeoutManager = new RequestTimeoutManager();
                _wpUserId = GetCurrentUserName(); 
 
                _requestNotificationCompletionCallback = new AsyncCallback(this.OnRequestNotificationCompletion);
                _handlerCompletionCallback = new AsyncCallback(this.OnHandlerCompletion); 
                _asyncEndOfSendCallback = new HttpWorkerRequest.EndOfSendNotification(this.EndOfSendCallback);
                _appDomainUnloadallback = new WaitCallback(this.ReleaseResourcesAndUnloadAppDomain);

 
                // appdomain values
                if (GetAppDomainString(".appDomain") != null) { 
 
                    Debug.Assert(HostingEnvironment.IsHosted);
 
                    _appDomainAppId = GetAppDomainString(".appId");
                    _appDomainAppPath = GetAppDomainString(".appPath");
                    _appDomainAppVPath = VirtualPath.CreateNonRelativeTrailingSlash(GetAppDomainString(".appVPath"));
                    _appDomainId = GetAppDomainString(".domainId"); 

                    _isOnUNCShare = StringUtil.StringStartsWith(_appDomainAppPath, "\\\\"); 
 
                    // init perf counters for this appdomain
                    PerfCounters.Open(_appDomainAppId); 
                }
                else {
                    Debug.Assert(!HostingEnvironment.IsHosted);
                } 

                // _appDomainAppPath should be set before file change notifications are initialized 
                _fcm = new FileChangesMonitor(); 
            }
            catch (Exception e) { 
                // remember static initalization error
                InitializationException = e;
            }
        } 

        private void SetUpDataDirectory() { 
 
            // Set the DataDirectory (see VSWhidbey 226834) with permission (DevDiv 29614)
            string dataDirectory = Path.Combine(_appDomainAppPath, DataDirectoryName); 
            AppDomain.CurrentDomain.SetData("DataDirectory", dataDirectory,
                    new FileIOPermission(FileIOPermissionAccess.PathDiscovery, dataDirectory));
        }
 
        private void DisposeAppDomainShutdownTimer() {
            Timer timer = _appDomainShutdownTimer; 
            if (timer != null && Interlocked.CompareExchange(ref _appDomainShutdownTimer, null, timer) == timer) { 
                timer.Dispose();
            } 
        }

        private void AppDomainShutdownTimerCallback(Object state) {
            try { 
                DisposeAppDomainShutdownTimer();
                ShutdownAppDomain(ApplicationShutdownReason.InitializationError, "Initialization Error"); 
            } 
            catch { } // ignore exceptions
        } 

        /*
         * Restart the AppDomain in 10 seconds
         */ 
        private void StartAppDomainShutdownTimer() {
            if (_appDomainShutdownTimer == null && !_shutdownInProgress) { 
                lock (this) { 
                    if (_appDomainShutdownTimer == null && !_shutdownInProgress) {
                        _appDomainShutdownTimer = new Timer( 
                            new TimerCallback(this.AppDomainShutdownTimerCallback),
                            null,
                            10 * 1000,
                            0); 
                    }
                } 
            } 
        }
 

        /*
         * Initialization from HostingEnvironment of HTTP independent features
         */ 
        private void HostingInit(HostingEnvironmentFlags hostingFlags) {
            using (new ApplicationImpersonationContext()) { 
                try { 
                    // To ignore FCN during initialization
                    _firstRequestStartTime = DateTime.UtcNow; 

                    SetUpDataDirectory();

                    // Throw an exception about lack of access to app directory early on 
                    EnsureAccessToApplicationDirectory();
 
                    // Monitor renames to directories we are watching, and notifications on the bin directory 
                    //
                    // Note that this must be the first monitoring that we do of the application directory. 
                    // There is a bug in Windows 2000 Server where notifications on UNC shares do not
                    // happen correctly if:
                    //      1. the directory is monitored for regular notifications
                    //      2. the directory is then monitored for directory renames 
                    //      3. the directory is monitored again for regular notifications
                    StartMonitoringDirectoryRenamesAndBinDirectory(); 
 
                    //
                    // Get the configuration needed to minimally initialize 
                    // the components required for a complete configuration system,
                    // especially SetTrustLevel.
                    //
                    // We want to do this before calling SetUpCodegenDirectory(), 
                    // to remove the risk of the config system loading
                    // codegen assemblies in full trust (VSWhidbey 460506) 
                    // 
                    CacheSection cacheSection;
                    TrustSection trustSection; 
                    SecurityPolicySection securityPolicySection;
                    CompilationSection compilationSection;
                    HostingEnvironmentSection hostingEnvironmentSection;
                    Exception configInitException; 

                    GetInitConfigSections( 
                            out cacheSection, 
                            out trustSection,
                            out securityPolicySection, 
                            out compilationSection,
                            out hostingEnvironmentSection,
                            out configInitException);
 
                    // Once the configuration system is initialized, we can read
                    // the cache configuration settings. 
                    // 
                    // Note that we must do this after we start monitoring directory renames,
                    // as reading config will cause file monitoring on the application directory 
                    // to occur.
                    HttpRuntime.CacheInternal.ReadCacheInternalConfig(cacheSection);

                    // Set up the codegen directory for the app.  This needs to be done before we process 
                    // the policy file, because it needs to replace the $CodeGen$ token.
                    SetUpCodegenDirectory(compilationSection); 
 
                    // NOTE: after calling SetUpCodegenDirectory(), and until we call SetTrustLevel(), we are at
                    // risk of codegen assemblies being loaded in full trust.  No code that might cause 
                    // assembly loading should be added here!

                    try {
                        // Set code access policy on the app domain 
                        SetTrustLevel(trustSection, securityPolicySection);
 
                    } 
                    catch {
                        // throw the original config exception if it exists 
                        if (configInitException != null) {
                            throw configInitException;
                        }
                        throw; 
                    }
 
                    // Configure fusion to use directories set in the app config 
                    InitFusion(hostingEnvironmentSection);
 
                    // Complete initialization of configuration.
                    // Note that this needs to be called after SetTrustLevel,
                    // as it indicates that we have the permission set needed
                    // to correctly run configuration section handlers. 
                    // As little config should be read before CompleteInit() as possible.
                    // No section that runs before CompleteInit() should demand permissions, 
                    // as the permissions set has not yet determined until SetTrustLevel() 
                    // is called.
                    HttpConfigurationSystem.CompleteInit(); 

                    //
                    // If an exception occurred loading configuration,
                    // we are now ready to handle exception processing 
                    // with the correct trust level set.
                    // 
                    if (configInitException != null) { 
                        throw configInitException;
                    } 

                    SetThreadPoolLimits();

                    SetAutogenKeys(); 

                    // Initialize the build manager 
                    BuildManager.InitializeBuildManager(); 

                    // Determine apartment threading setting 
                    InitApartmentThreading();

                    // Init debugging
                    InitDebuggingSupport(); 
#if SITECOUNTERS
                    if (!BuildManagerHost.InClientBuildManager) { 
                        // create siteCounters object according to config 
                        InitSiteCounters();
                    } 
#endif
                    _processRequestInApplicationTrust = trustSection.ProcessRequestInApplicationTrust;
                }
                catch (Exception e) { 
                    _hostingInitFailed = true;
                    InitializationException = e; 
 
                    Debug.Trace("AppDomainFactory", "HostingInit failed. " + e.ToString());
 
                    if ((hostingFlags & HostingEnvironmentFlags.ThrowHostingInitErrors) != 0)
                        throw;
                }
            } 
        }
 
        internal static Exception InitializationException { 
            get {
                return _theRuntime._initializationError; 
            }

            // The exception is "cached" for 10 seconds, then the AppDomain is restarted.
            set { 
                _theRuntime._initializationError = value;
                // In v2.0, we shutdown immediately if hostingInitFailed...so we don't need the timer 
                if (!HostingInitFailed) { 
                    _theRuntime.StartAppDomainShutdownTimer();
                } 
            }
        }

        internal static bool HostingInitFailed { 
            get {
                return _theRuntime._hostingInitFailed; 
            } 
        }
 
        internal static void InitializeHostingFeatures(HostingEnvironmentFlags hostingFlags) {
            _theRuntime.HostingInit(hostingFlags);
        }
 
        internal static bool EnableHeaderChecking {
            get { 
                return _theRuntime._enableHeaderChecking; 
            }
        } 

        internal static bool ProcessRequestInApplicationTrust {
            get {
                return _theRuntime._processRequestInApplicationTrust; 
            }
        } 
 
        internal static byte[] AppOfflineMessage {
            get { 
                return _theRuntime._appOfflineMessage;
            }
        }
 
        /*
         * Initialization on first request (context available) 
         */ 
        private void FirstRequestInit(HttpContext context) {
            Exception error = null; 

            if (InitializationException == null && _appDomainId != null) {
#if DBG
                HttpContext.SetDebugAssertOnAccessToCurrent(true); 
#endif
                try { 
                    using (new ApplicationImpersonationContext()) { 
                        // Is this necessary?  See InitHttpConfiguration
                        CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture; 
                        CultureInfo savedUICulture = Thread.CurrentThread.CurrentUICulture;

                        try {
                            // Ensure config system is initialized 
                            InitHttpConfiguration(); // be sure config system is set
 
                            // Check if applicaton is enabled 
                            CheckApplicationEnabled();
 
                            // Check access to temp compilation directory (under hosting identity)
                            CheckAccessToTempDirectory();

                            // Initialize health monitoring 
                            InitializeHealthMonitoring();
 
                            // Init request queue (after reading config) 
                            InitRequestQueue();
 
                            // configure the profiler according to config
                            InitTrace(context);

#if ORCAS 
                            // Initialize the HttpDataStore and cleanup process
                            InitHttpDataStore(); 
#endif 

                            // Start heatbeat for Web Event Health Monitoring 
                            HealthMonitoringManager.StartHealthMonitoringHeartbeat();

                            // Remove read and browse access of the bin directory
                            RestrictIISFolders(context); 

                            // Preload all assemblies from bin (only if required).  ASURT 114486 
                            PreloadAssembliesFromBin(); 

                            // Decide whether or not to encode headers.  VsWhidbey 257154 
                            InitHeaderEncoding();

                            if (context.WorkerRequest is ISAPIWorkerRequestOutOfProc) {
                                // Make sure that the  section has no errors 
                                ProcessModelSection processModel = RuntimeConfig.GetMachineConfig().ProcessModel;
                            } 
                        } 
                        finally {
                            Thread.CurrentThread.CurrentUICulture = savedUICulture; 
                            Thread.CurrentThread.CurrentCulture = savedCulture;
                        }
                    }
                } 
                catch (ConfigurationException e) {
                    error = e; 
                } 
                catch (Exception e) {
                    // remember second-phase initialization error 
                    error = new HttpException(SR.GetString(SR.XSP_init_error, e.Message), e);
                }
                finally {
#if DBG 
                    HttpContext.SetDebugAssertOnAccessToCurrent(false);
#endif 
                } 
            }
 
            if (InitializationException != null) {
                // throw cached exception.  We need to wrap it in a new exception, otherwise
                // we lose the original stack.
                throw new HttpException(InitializationException.Message, InitializationException); 
            }
            else if (error != null) { 
                InitializationException = error; 
                // throw new exception
                throw error; 
            }

            AddAppDomainTraceMessage("FirstRequestInit");
        } 

        private void EnsureFirstRequestInit(HttpContext context) { 
            if (_beforeFirstRequest) { 
                lock (this) {
                    if (_beforeFirstRequest) { 
                        _firstRequestStartTime = DateTime.UtcNow;
                        FirstRequestInit(context);
                        _beforeFirstRequest = false;
                    } 
                }
            } 
        } 

        private void EnsureAccessToApplicationDirectory() { 
            if (!FileUtil.DirectoryAccessible(_appDomainAppPath)) {
                //
                if (_appDomainAppPath.IndexOf('?') >= 0) {
                    // Possible Unicode when not supported 
                    throw new HttpException(SR.GetString(SR.Access_denied_to_unicode_app_dir, _appDomainAppPath));
                } 
                else { 
                    throw new HttpException(SR.GetString(SR.Access_denied_to_app_dir, _appDomainAppPath));
                } 
            }
        }

        private void StartMonitoringDirectoryRenamesAndBinDirectory() { 
            _fcm.StartMonitoringDirectoryRenamesAndBinDirectory(AppDomainAppPathInternal, new FileChangeEventHandler(this.OnCriticalDirectoryChange));
        } 
 
        //
        // Monitor a local resources subdirectory and unload appdomain when it changes 
        //
        internal static void StartListeningToLocalResourcesDirectory(VirtualPath virtualDir) {
#if !FEATURE_PAL // FEATURE_PAL does not enable file change notification
            _theRuntime._fcm.StartListeningToLocalResourcesDirectory(virtualDir); 
#endif // !FEATURE_PAL
        } 
 
        //
        // Get the configuration needed to minimally initialize 
        // the components required for a complete configuration system,
        //
        // Note that if the application configuration file has an error,
        // AppLKGConfig will still retreive any valid configuration from 
        // that file, or from location directives that apply to the
        // application path. This implies that an administrator can 
        // lock down an application's trust level in root web.config, 
        // and it will still take effect if the application's web.config
        // has errors. 
        //
        private void GetInitConfigSections(
                out CacheSection cacheSection,
                out TrustSection trustSection, 
                out SecurityPolicySection securityPolicySection,
                out CompilationSection compilationSection, 
                out HostingEnvironmentSection hostingEnvironmentSection, 
                out Exception initException) {
 
            cacheSection = null;
            trustSection = null;
            securityPolicySection = null;
            compilationSection = null; 
            hostingEnvironmentSection = null;
            initException = null; 
 
            // AppLKGConfig is guaranteed to not throw an exception.
            RuntimeConfig appLKGConfig = RuntimeConfig.GetAppLKGConfig(); 

            // AppConfig may throw an exception.
            RuntimeConfig appConfig = null;
            try { 
                appConfig = RuntimeConfig.GetAppConfig();
            } 
            catch (Exception e) { 
                initException = e;
            } 

            // Cache section
            if (appConfig != null) {
                try { 
                    cacheSection = appConfig.Cache;
                } 
                catch (Exception e) { 
                    if (initException == null) {
                        initException = e; 
                    }
                }
            }
 
            if (cacheSection == null) {
                cacheSection = appLKGConfig.Cache; 
            } 

            // Trust section 
            if (appConfig != null) {
                try {
                    trustSection = appConfig.Trust;
                } 
                catch (Exception e) {
                    if (initException == null) { 
                        initException = e; 
                    }
                } 
            }

            if (trustSection == null) {
                trustSection = appLKGConfig.Trust; 
            }
 
            // SecurityPolicy section 
            if (appConfig != null) {
                try { 
                    securityPolicySection = appConfig.SecurityPolicy;
                }
                catch (Exception e) {
                    if (initException == null) { 
                        initException = e;
                    } 
                } 
            }
 
            if (securityPolicySection == null) {
                securityPolicySection = appLKGConfig.SecurityPolicy;
            }
 
            // Compilation section
            if (appConfig != null) { 
                try { 
                    compilationSection = appConfig.Compilation;
                } 
                catch (Exception e) {
                    if (initException == null) {
                        initException = e;
                    } 
                }
            } 
 
            if (compilationSection == null) {
                compilationSection = appLKGConfig.Compilation; 
            }

            // HostingEnvironment section
            if (appConfig != null) { 
                try {
                    hostingEnvironmentSection = appConfig.HostingEnvironment; 
                } 
                catch (Exception e) {
                    if (initException == null) { 
                        initException = e;
                    }
                }
            } 

            if (hostingEnvironmentSection == null) { 
                hostingEnvironmentSection = appLKGConfig.HostingEnvironment; 
            }
        } 

        // Set up the codegen directory for the app
        private void SetUpCodegenDirectory(CompilationSection compilationSection) {
            AppDomain appDomain = Thread.GetDomain(); 

            string codegenBase; 
 
            string simpleAppName = System.Web.Hosting.AppManagerAppDomainFactory.ConstructSimpleAppName(
                AppDomainAppVirtualPath); 

            string tempDirectory = null;

            // These variables are used for error handling 
            string tempDirAttribName = null;
            string configFileName = null; 
            int configLineNumber = 0; 

            if (compilationSection != null && !String.IsNullOrEmpty(compilationSection.TempDirectory)) { 
                tempDirectory = compilationSection.TempDirectory;

                compilationSection.GetTempDirectoryErrorInfo(out tempDirAttribName,
                    out configFileName, out configLineNumber); 
            }
 
            if (tempDirectory != null) { 
                tempDirectory = tempDirectory.Trim();
 
                if (!Path.IsPathRooted(tempDirectory)) {
                    // Make sure the path is not relative (VSWhidbey 260075)
                    tempDirectory = null;
                } 
                else {
                    try { 
                        // Canonicalize it to avoid problems with spaces (VSWhidbey 229873) 
                        tempDirectory = new DirectoryInfo(tempDirectory).FullName;
                    } 
                    catch {
                        tempDirectory = null;
                    }
                } 

                if (tempDirectory == null) { 
                    throw new ConfigurationErrorsException( 
                        SR.GetString(SR.Invalid_temp_directory, tempDirAttribName),
                        configFileName, configLineNumber); 
                }
#if FEATURE_PAL
            } else {
                System.UInt32 length = 0; 
                StringBuilder sb = null;
                bool bRet; 
 
                // Get the required length
                bRet = UnsafeNativeMethods.GetUserTempDirectory( 
                                    UnsafeNativeMethods.DeploymentDirectoryType.ddtInstallationDependentDirectory,
                                    null, ref length);

                if (true == bRet) { 
                    // now, allocate the string
                    sb = new StringBuilder ((int)length); 
 
                    // call again to get the value
                    bRet = UnsafeNativeMethods.GetUserTempDirectory( 
                                    UnsafeNativeMethods.DeploymentDirectoryType.ddtInstallationDependentDirectory,
                                    sb, ref length);
                }
 
                if (false == bRet) {
                    throw new ConfigurationException( 
                        HttpRuntime.FormatResourceString(SR.Invalid_temp_directory, tempDirAttribName)); 
                }
 
                tempDirectory = Path.Combine(sb.ToString(), codegenDirName);
            }

            // Always try to create the ASP.Net temp directory for FEATURE_PAL 
#endif // FEATURE_PAL
 
                // Create the config-specified directory if needed 
                try {
                    Directory.CreateDirectory(tempDirectory); 
                }
                catch (Exception e) {
                    throw new ConfigurationErrorsException(
                        SR.GetString(SR.Invalid_temp_directory, tempDirAttribName), 
                        e,
                        configFileName, configLineNumber); 
                } 
#if !FEATURE_PAL
            } 
            else {
                tempDirectory = Path.Combine(s_installDirectory, codegenDirName);
            }
#endif // !FEATURE_PAL 

            // If we don't have write access to the codegen dir, use the TEMP dir instead. 
            // This will allow non-admin users to work in hosting scenarios (e.g. Venus, aspnet_compiler) 
            if (!System.Web.UI.Util.HasWriteAccessToDirectory(tempDirectory)) {
 
                // Don't do this if we're in a service (!UserInteractive), as TEMP
                // could point to unwanted places.

#if !FEATURE_PAL // always fail here 
                if (!Environment.UserInteractive)
#endif // !FEATURE_PAL 
 { 
                    throw new HttpException(SR.GetString(SR.No_codegen_access,
                        System.Web.UI.Util.GetCurrentAccountName(), tempDirectory)); 
                }

                tempDirectory = Path.GetTempPath();
                Debug.Assert(System.Web.UI.Util.HasWriteAccessToDirectory(tempDirectory)); 
                tempDirectory = Path.Combine(tempDirectory, codegenDirName);
            } 
 
            _tempDir = tempDirectory;
 
            codegenBase = Path.Combine(tempDirectory, simpleAppName);

#pragma warning disable 0618    // To avoid deprecation warning
            appDomain.SetDynamicBase(codegenBase); 
#pragma warning restore 0618
 
            _codegenDir = Thread.GetDomain().DynamicDirectory; 

            // Create the codegen directory if needed 
            Directory.CreateDirectory(_codegenDir);
        }

        private void InitFusion(HostingEnvironmentSection hostingEnvironmentSection) { 

            AppDomain appDomain = Thread.GetDomain(); 
 
            // If there is a double backslash in the string, get rid of it (ASURT 122191)
            // Make sure to skip the first char, to avoid breaking the UNC case 
            string appDomainAppPath = _appDomainAppPath;
            if (appDomainAppPath.IndexOf(DoubleDirectorySeparatorString, 1, StringComparison.Ordinal) >= 1) {
                appDomainAppPath = appDomainAppPath[0] + appDomainAppPath.Substring(1).Replace(DoubleDirectorySeparatorString,
                    DirectorySeparatorString); 
            }
 
#pragma warning disable 0618    // To avoid deprecation warning 
            // Allow assemblies from 'bin' to be loaded
            appDomain.AppendPrivatePath(appDomainAppPath + BinDirectoryName); 
#pragma warning restore 0618

            // If shadow copying was disabled via config, turn it off (DevDiv 30864)
            if (hostingEnvironmentSection != null && !hostingEnvironmentSection.ShadowCopyBinAssemblies) { 
#pragma warning disable 0618    // To avoid deprecation warning
                appDomain.ClearShadowCopyPath(); 
#pragma warning restore 0618 
            }
            else { 
                // enable shadow-copying from bin
#pragma warning disable 0618    // To avoid deprecation warning
                appDomain.SetShadowCopyPath(appDomainAppPath + BinDirectoryName);
#pragma warning restore 0618 
            }
 
            // Get rid of the last part of the directory (the app name), since it will 
            // be re-appended.
            string parentDir = Directory.GetParent(_codegenDir).FullName; 
#pragma warning disable 0618    // To avoid deprecation warning
            appDomain.SetCachePath(parentDir);
#pragma warning restore 0618
 
            _fusionInited = true;
        } 
 
        private void InitRequestQueue() {
            RuntimeConfig config = RuntimeConfig.GetAppConfig(); 
            HttpRuntimeSection runtimeConfig = config.HttpRuntime;
            ProcessModelSection processConfig = config.ProcessModel;

            if (processConfig.AutoConfig) { 
                _requestQueue = new RequestQueue(
                    88 * processConfig.CpuCount, 
                    76 * processConfig.CpuCount, 
                    runtimeConfig.AppRequestQueueLimit,
                    processConfig.ClientConnectedCheck); 
            }
            else {

                // Configuration section handlers cannot validate values based on values 
                // in other configuration sections, so we validate minFreeThreads and
                // minLocalRequestFreeThreads here. 
                int maxThreads = (processConfig.MaxWorkerThreadsTimesCpuCount < processConfig.MaxIoThreadsTimesCpuCount) ? processConfig.MaxWorkerThreadsTimesCpuCount : processConfig.MaxIoThreadsTimesCpuCount; 
                // validate minFreeThreads
                if (runtimeConfig.MinFreeThreads >= maxThreads) { 
                    if (runtimeConfig.ElementInformation.Properties["minFreeThreads"].LineNumber == 0) {
                        if (processConfig.ElementInformation.Properties["maxWorkerThreads"].LineNumber != 0) {
                            throw new ConfigurationErrorsException(SR.GetString(SR.Thread_pool_limit_must_be_greater_than_minFreeThreads, runtimeConfig.MinFreeThreads.ToString(CultureInfo.InvariantCulture)),
                                                                   processConfig.ElementInformation.Properties["maxWorkerThreads"].Source, 
                                                                   processConfig.ElementInformation.Properties["maxWorkerThreads"].LineNumber);
                        } 
                        else { 
                            throw new ConfigurationErrorsException(SR.GetString(SR.Thread_pool_limit_must_be_greater_than_minFreeThreads, runtimeConfig.MinFreeThreads.ToString(CultureInfo.InvariantCulture)),
                                                                   processConfig.ElementInformation.Properties["maxIoThreads"].Source, 
                                                                   processConfig.ElementInformation.Properties["maxIoThreads"].LineNumber);
                        }
                    }
                    else { 
                        throw new ConfigurationErrorsException(SR.GetString(SR.Min_free_threads_must_be_under_thread_pool_limits, maxThreads.ToString(CultureInfo.InvariantCulture)),
                                                               runtimeConfig.ElementInformation.Properties["minFreeThreads"].Source, 
                                                               runtimeConfig.ElementInformation.Properties["minFreeThreads"].LineNumber); 
                    }
                } 
                // validate minLocalRequestFreeThreads
                if (runtimeConfig.MinLocalRequestFreeThreads > runtimeConfig.MinFreeThreads) {
                    if (runtimeConfig.ElementInformation.Properties["minLocalRequestFreeThreads"].LineNumber == 0) {
                        throw new ConfigurationErrorsException(SR.GetString(SR.Local_free_threads_cannot_exceed_free_threads), 
                                                               processConfig.ElementInformation.Properties["minFreeThreads"].Source,
                                                               processConfig.ElementInformation.Properties["minFreeThreads"].LineNumber); 
                    } 
                    else {
                        throw new ConfigurationErrorsException(SR.GetString(SR.Local_free_threads_cannot_exceed_free_threads), 
                                                               runtimeConfig.ElementInformation.Properties["minLocalRequestFreeThreads"].Source,
                                                               runtimeConfig.ElementInformation.Properties["minLocalRequestFreeThreads"].LineNumber);
                    }
                } 

                _requestQueue = new RequestQueue( 
                    runtimeConfig.MinFreeThreads, 
                    runtimeConfig.MinLocalRequestFreeThreads,
                    runtimeConfig.AppRequestQueueLimit, 
                    processConfig.ClientConnectedCheck);
            }
        }
 
#if ORCAS
        private void InitHttpDataStore() { 
            ImageGenerationSection igConfig = RuntimeConfig.GetAppConfig().ImageGeneration; 
            IDictionary settings = new Hashtable();
            int imageStorageExpiration = 300; 
            StorageType storageType = igConfig.StorageType;

            if (storageType == StorageType.Disk) {
                _httpDataStorageProvider = new DiskHttpDataStorageProvider(); 
                settings["storagePath"] = igConfig.StoragePath;
            } 
 
            int imageExp = (int) igConfig.StorageExpiration.TotalSeconds;
            if (imageExp > 0) { 
                imageStorageExpiration = imageExp;
            }

            if (_httpDataStorageProvider == null) { 
                _httpDataStorageProvider = new CacheHttpDataStorageProvider();
            } 
 
            try {
                _httpDataStorageProvider.Initialize(imageStorageExpiration, settings); 
            }
            catch (Exception e) {
                throw new ConfigurationErrorsException(e.Message, e, igConfig.SourceFileName, igConfig.SourceLineNumber);
            } 

            _httpDataStorageCleanup = new HttpDataStorageCleanup(imageStorageExpiration * 1000, _httpDataStorageProvider); 
        } 
#endif
 
        private void InitApartmentThreading() {
            HttpRuntimeSection runtimeConfig = RuntimeConfig.GetAppConfig().HttpRuntime;

            if (runtimeConfig != null) { 
                _apartmentThreading = runtimeConfig.ApartmentThreading;
            } 
            else { 
                _apartmentThreading = false;
            } 
        }

        private void InitTrace(HttpContext context) {
            TraceSection traceConfig = RuntimeConfig.GetAppConfig().Trace; 

            Profile.RequestsToProfile = traceConfig.RequestLimit; 
            Profile.PageOutput = traceConfig.PageOutput; 
            Profile.OutputMode = TraceMode.SortByTime;
            if (traceConfig.TraceMode == TraceDisplayMode.SortByCategory) 
                Profile.OutputMode = TraceMode.SortByCategory;

            Profile.LocalOnly = traceConfig.LocalOnly;
            Profile.IsEnabled = traceConfig.Enabled; 
            Profile.MostRecent = traceConfig.MostRecent;
            Profile.Reset(); 
 
            // the first request's context is created before InitTrace, so
            // we need to set this manually. (ASURT 93730) 
            context.TraceIsEnabled = traceConfig.Enabled;
            TraceContext.SetWriteToDiagnosticsTrace(traceConfig.WriteToDiagnosticsTrace);
        }
 
        private void InitDebuggingSupport() {
            CompilationSection compConfig = RuntimeConfig.GetAppConfig().Compilation; 
            _debuggingEnabled = compConfig.Debug; 
        }
 
#if SITECOUNTERS
        internal void InitSiteCounters() {
            SiteCountersSection siteCountersConfig = RuntimeConfig.GetAppConfig().SiteCounters;
            Type type; 
#if FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features
 		siteCountersConfig.Enabled = false; 
#endif // FEATURE_PAL 
            if (siteCountersConfig.Enabled) {
                type = siteCountersConfig.TypeInternal; 
            }
            else {
                type = BuildManager.GetType("System.Web.SiteCounters", true, false);
            } 

            _siteCounters = (SiteCounters) CreateNonPublicInstance(type); 
            _siteCounters.Initialize(); 
        }
#endif 
        /*
         * Pre-load all the bin assemblies if we're impersonated.  This way, if user code
         * calls Assembly.Load while impersonated, the assembly will already be loaded, and
         * we won't fail due to lack of permissions on the codegen dir (see ASURT 114486) 
         */
        private void PreloadAssembliesFromBin() { 
            bool appClientImpersonationEnabled = false; 

            if (!_isOnUNCShare) { 
                // if not on UNC share check if config has impersonation enabled (without userName)
                IdentitySection c = RuntimeConfig.GetAppConfig().Identity;
                if (c.Impersonate && c.ImpersonateToken == IntPtr.Zero)
                    appClientImpersonationEnabled = true; 
            }
 
            if (!appClientImpersonationEnabled) 
                return;
 
            // Get the path to the bin directory
            string binPath = HttpRuntime.BinDirectoryInternal;

            DirectoryInfo binPathDirectory = new DirectoryInfo(binPath); 

            if (!binPathDirectory.Exists) 
                return; 

            PreloadAssembliesFromBinRecursive(binPathDirectory); 
        }

        private void PreloadAssembliesFromBinRecursive(DirectoryInfo dirInfo) {
 
            FileInfo[] binDlls = dirInfo.GetFiles("*.dll");
 
            // Pre-load all the assemblies, ignoring all exceptions 
            foreach (FileInfo fi in binDlls) {
                try { Assembly.Load(System.Web.UI.Util.GetAssemblyNameFromFileName(fi.Name)); } 
                catch (FileNotFoundException) {
                    // If Load failed, try LoadFrom (VSWhidbey 493725)
                    try { Assembly.LoadFrom(fi.FullName); }
                    catch { } 
                }
                catch { } 
            } 

            // Recurse on the subdirectories 
            DirectoryInfo[] subDirs = dirInfo.GetDirectories();
            foreach (DirectoryInfo di in subDirs) {
                PreloadAssembliesFromBinRecursive(di);
            } 
        }
 
        private void SetAutoConfigLimits(ProcessModelSection pmConfig) { 
            // check if the current limits are ok
            int workerMax, ioMax; 
            ThreadPool.GetMaxThreads(out workerMax, out ioMax);

            // only set if different
            if (pmConfig.DefaultMaxWorkerThreadsForAutoConfig != workerMax || pmConfig.DefaultMaxIoThreadsForAutoConfig != ioMax) { 
                Debug.Trace("ThreadPool", "SetThreadLimit: from " + workerMax + "," + ioMax + " to " + pmConfig.DefaultMaxWorkerThreadsForAutoConfig + "," + pmConfig.DefaultMaxIoThreadsForAutoConfig);
                UnsafeNativeMethods.SetClrThreadPoolLimits(pmConfig.DefaultMaxWorkerThreadsForAutoConfig, pmConfig.DefaultMaxIoThreadsForAutoConfig); 
            } 

            // this is the code equivalent of setting maxconnection 
            System.Net.ServicePointManager.DefaultConnectionLimit = 12 * pmConfig.CpuCount;

            // we call InitRequestQueue later, from FirstRequestInit, and set minFreeThreads and minLocalRequestFreeThreads
        } 

        private void SetThreadPoolLimits() { 
            try { 
                ProcessModelSection pmConfig = RuntimeConfig.GetMachineConfig().ProcessModel;
 
                if (pmConfig.AutoConfig) {
                    // use recommendation in http://support.microsoft.com/?id=821268
                    SetAutoConfigLimits(pmConfig);
                } 
                else if (pmConfig.MaxWorkerThreadsTimesCpuCount > 0 && pmConfig.MaxIoThreadsTimesCpuCount > 0) {
                    // check if the current limits are ok 
                    int workerMax, ioMax; 
                    ThreadPool.GetMaxThreads(out workerMax, out ioMax);
 
                    // only set if different
                    if (pmConfig.MaxWorkerThreadsTimesCpuCount != workerMax || pmConfig.MaxIoThreadsTimesCpuCount != ioMax) {
                        Debug.Trace("ThreadPool", "SetThreadLimit: from " + workerMax + "," + ioMax + " to " + pmConfig.MaxWorkerThreadsTimesCpuCount + "," + pmConfig.MaxIoThreadsTimesCpuCount);
                        UnsafeNativeMethods.SetClrThreadPoolLimits(pmConfig.MaxWorkerThreadsTimesCpuCount, pmConfig.MaxIoThreadsTimesCpuCount); 
                    }
                } 
 
                if (pmConfig.MinWorkerThreadsTimesCpuCount > 0 || pmConfig.MinIoThreadsTimesCpuCount > 0) {
                    int currentMinWorkerThreads, currentMinIoThreads; 
                    ThreadPool.GetMinThreads(out currentMinWorkerThreads, out currentMinIoThreads);

                    int newMinWorkerThreads = pmConfig.MinWorkerThreadsTimesCpuCount > 0 ? pmConfig.MinWorkerThreadsTimesCpuCount : currentMinWorkerThreads;
                    int newMinIoThreads = pmConfig.MinIoThreadsTimesCpuCount > 0 ? pmConfig.MinIoThreadsTimesCpuCount : currentMinIoThreads; 

                    if (newMinWorkerThreads > 0 && newMinIoThreads > 0 
                        && (newMinWorkerThreads != currentMinWorkerThreads || newMinIoThreads != currentMinIoThreads)) 
                        ThreadPool.SetMinThreads(newMinWorkerThreads, newMinIoThreads);
                } 
            }
            catch {
            }
        } 

        internal static void CheckApplicationEnabled() { 
            // process App_Offline.htm file 
            string appOfflineFile = Path.Combine(_theRuntime._appDomainAppPath, AppOfflineFileName);
            bool appOfflineFileFound = false; 

            // monitor even if doesn't exist
            _theRuntime._fcm.StartMonitoringFile(appOfflineFile, new FileChangeEventHandler(_theRuntime.OnAppOfflineFileChange));
 
            // read the file into memory
            try { 
                if (File.Exists(appOfflineFile)) { 
                    Debug.Trace("AppOffline", "File " + appOfflineFile + " exists. Using it.");
 
                    using (FileStream fs = new FileStream(appOfflineFile, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                        if (fs.Length <= MaxAppOfflineFileLength) {
                            int length = (int)fs.Length;
 
                            if (length > 0) {
                                byte[] message = new byte[length]; 
 
                                if (fs.Read(message, 0, length) == length) {
                                    // remember the message 
                                    _theRuntime._appOfflineMessage = message;
                                    appOfflineFileFound = true;
                                }
                            } 
                            else {
                                // empty file 
                                appOfflineFileFound = true; 
                            }
                        } 
                    }
                }
            }
            catch { 
                // ignore any IO errors reading the file
            } 
 
            // throw if there is a valid App_Offline file
            if (appOfflineFileFound) { 
                throw new HttpException(404, String.Empty);
            }

            // process the config setting 
            HttpRuntimeSection runtimeConfig = RuntimeConfig.GetAppConfig().HttpRuntime;
            if (!runtimeConfig.Enable) { 
                // throw 404 on first request init -- this will get cached until config changes 
                throw new HttpException(404, String.Empty);
            } 
        }

        private void CheckAccessToTempDirectory() {
            // The original check (in HostingInit) was done under process identity 
            // this time we do it under hosting identity
            if (HostingEnvironment.HasHostingIdentity) { 
                using (new ApplicationImpersonationContext()) { 
                    if (!System.Web.UI.Util.HasWriteAccessToDirectory(_tempDir)) {
                        throw new HttpException(SR.GetString(SR.No_codegen_access, 
                            System.Web.UI.Util.GetCurrentAccountName(), _tempDir));
                    }
                }
            } 
        }
 
        private void InitializeHealthMonitoring() { 
#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features
            ProcessModelSection pmConfig = RuntimeConfig.GetMachineConfig().ProcessModel; 
            int deadLockInterval = (int)pmConfig.ResponseDeadlockInterval.TotalSeconds;
            int requestQueueLimit = pmConfig.RequestQueueLimit;
            Debug.Trace("HealthMonitor", "Initalizing: ResponseDeadlockInterval=" + deadLockInterval);
            UnsafeNativeMethods.InitializeHealthMonitor(deadLockInterval, requestQueueLimit); 
#endif // !FEATURE_PAL
        } 
 
        private static void InitHttpConfiguration() {
            if (!_theRuntime._configInited) { 
                _theRuntime._configInited = true;

                HttpConfigurationSystem.EnsureInit(null, true, true);
 
                // whenever possible report errors in the user's culture (from machine.config)
                // Note: this thread's culture is saved/restored during FirstRequestInit, so this is safe 
                // see ASURT 81655 

                GlobalizationSection globConfig = RuntimeConfig.GetAppLKGConfig().Globalization; 
                if (globConfig != null) {
                    if (!String.IsNullOrEmpty(globConfig.Culture) &&
                        !StringUtil.StringStartsWithIgnoreCase(globConfig.Culture, "auto"))
                        Thread.CurrentThread.CurrentCulture = HttpServerUtility.CreateReadOnlyCultureInfo(globConfig.Culture); 

                    if (!String.IsNullOrEmpty(globConfig.UICulture) && 
                        !StringUtil.StringStartsWithIgnoreCase(globConfig.UICulture, "auto")) 
                        Thread.CurrentThread.CurrentUICulture = HttpServerUtility.CreateReadOnlyCultureInfo(globConfig.UICulture);
                } 

                // check for errors in  section
                RuntimeConfig appConfig = RuntimeConfig.GetAppConfig();
                object section = appConfig.ProcessModel; 
                // check for errors in  section
                section = appConfig.HostingEnvironment; 
            } 
        }
 
        private void InitHeaderEncoding() {
            HttpRuntimeSection runtimeConfig = RuntimeConfig.GetAppConfig().HttpRuntime;
            _enableHeaderChecking = runtimeConfig.EnableHeaderChecking;
        } 

        private static void SetAutogenKeys() { 
#if !FEATURE_PAL // FEATURE_PAL does not enable cryptography 
            byte[] bKeysRandom = new byte[s_autogenKeys.Length];
            byte[] bKeysStored = new byte[s_autogenKeys.Length]; 
            bool fGetStoredKeys = false;
            RNGCryptoServiceProvider randgen = new RNGCryptoServiceProvider();

            // Gernerate random keys 
            randgen.GetBytes(bKeysRandom);
 
            // If getting stored keys via WorkerRequest object failed, get it directly 
            if (!fGetStoredKeys)
                fGetStoredKeys = (UnsafeNativeMethods.EcbCallISAPI(IntPtr.Zero, UnsafeNativeMethods.CallISAPIFunc.GetAutogenKeys, 
                                                                   bKeysRandom, bKeysRandom.Length, bKeysStored, bKeysStored.Length) == 1);

            // If we managed to get stored keys, copy them in; else use random keys
            if (fGetStoredKeys) 
                Buffer.BlockCopy(bKeysStored, 0, s_autogenKeys, 0, s_autogenKeys.Length);
            else 
                Buffer.BlockCopy(bKeysRandom, 0, s_autogenKeys, 0, s_autogenKeys.Length); 
#endif // !FEATURE_PAL
        } 

        internal static void IncrementActivePipelineCount() {
            Interlocked.Increment(ref _theRuntime._activeRequestCount);
            HostingEnvironment.IncrementBusyCount(); 
        }
 
        internal static void DecrementActivePipelineCount() { 
            HostingEnvironment.DecrementBusyCount();
            Interlocked.Decrement(ref _theRuntime._activeRequestCount); 
        }

        // DevDivBugs 190952: public method for querying runtime pipeline mode
        public static bool UsingIntegratedPipeline { 
            get {
                return UseIntegratedPipeline; 
            } 
        }
 
        internal static bool UseIntegratedPipeline {
            get {
                return _useIntegratedPipeline;
            } 
            set {
                _useIntegratedPipeline = value; 
            } 
        }
 

        /*
         * Process one step of the integrated pipeline
         * 
         */
 
        internal static RequestNotificationStatus ProcessRequestNotification(IIS7WorkerRequest wr, HttpContext context) 
        {
            return _theRuntime.ProcessRequestNotificationPrivate(wr, context); 
        }

        private RequestNotificationStatus ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) {
            RequestNotificationStatus status = RequestNotificationStatus.Pending; 
            try {
                // setup the HttpContext for this event/module combo 
                context.CurrentModuleIndex = UnsafeIISMethods.MgdGetCurrentModuleIndex(wr.RequestContext); 
                context.IsPostNotification = UnsafeIISMethods.MgdIsCurrentNotificationPost(wr.RequestContext);
                context.CurrentNotification = (RequestNotification)UnsafeIISMethods.MgdGetCurrentNotification(wr.RequestContext); 
#if DBG
                Debug.Trace("PipelineRuntime", "HttpRuntime::ProcessRequestNotificationPrivate: notification=" + context.CurrentNotification.ToString()
                            + ", isPost=" + context.IsPostNotification
                            + ", moduleIndex=" + context.CurrentModuleIndex); 
#endif
 
                IHttpHandler handler = null; 
                if (context.NeedToInitializeApp()) {
                    // First request initialization 
                    try {
                        EnsureFirstRequestInit(context);
                    }
                    catch { 
                        // If we are handling a DEBUG request, ignore the FirstRequestInit exception.
                        // This allows the HttpDebugHandler to execute, and lets the debugger attach to 
                        // the process (VSWhidbey 358135) 
                        if (!context.Request.IsDebuggingRequest) {
                            throw; 
                        }
                    }

                    context.Response.InitResponseWriter(); 
                    handler = HttpApplicationFactory.GetApplicationInstance(context);
                    if (handler == null) 
                        throw new HttpException(SR.GetString(SR.Unable_create_app_object)); 

                    if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, handler.GetType().FullName, "Start"); 

                    HttpApplication app = handler as HttpApplication;
                    if (app != null) {
                        // associate the context with an application instance 
                        app.AssignContext(context);
                    } 
                } 

                // this may throw, and should be called after app initialization 
                wr.SynchronizeVariables(context);

                if (context.ApplicationInstance != null) {
                    // process request 
                    IAsyncResult ar = context.ApplicationInstance.BeginProcessRequestNotification(context, _requestNotificationCompletionCallback);
 
                    if (ar.CompletedSynchronously) { 
                        status = RequestNotificationStatus.Continue;
                    } 
                }
                else if (handler != null) {
                    // HttpDebugHandler is processed here
                    handler.ProcessRequest(context); 
                    status = RequestNotificationStatus.FinishRequest;
                } 
                else { 
                    status = RequestNotificationStatus.Continue;
                } 
            }
            catch (Exception e) {
                status = RequestNotificationStatus.FinishRequest;
                context.Response.InitResponseWriter(); 
                // errors are handled in HttpRuntime::FinishRequestNotification
                context.AddError(e); 
            } 

            if (status != RequestNotificationStatus.Pending) { 
                // we completed synchronously
                FinishRequestNotification(wr, context, ref status);
            }
 
#if DBG
            Debug.Trace("PipelineRuntime", "HttpRuntime::ProcessRequestNotificationPrivate: status=" + status.ToString()); 
#endif 

            return status; 
        }

        private void FinishRequestNotification(IIS7WorkerRequest wr, HttpContext context, ref RequestNotificationStatus status) {
 
            Debug.Assert(status != RequestNotificationStatus.Pending, "status != RequestNotificationStatus.Pending");
 
            HttpApplication app = context.ApplicationInstance; 

            if (context.NotificationContext.RequestCompleted) { 
                status = RequestNotificationStatus.FinishRequest;
            }

            // check if the app offline or whether an error has occurred, and report the condition 
            context.ReportRuntimeErrorIfExists(ref status);
 
            // we do not return FinishRequest for LogRequest or EndRequest 
            if (status == RequestNotificationStatus.FinishRequest
                && (context.CurrentNotification == RequestNotification.LogRequest 
                    || context.CurrentNotification == RequestNotification.EndRequest)) {
                status = RequestNotificationStatus.Continue;
            }
 
            IntPtr requestContext = wr.RequestContext;
            bool sendHeaders = UnsafeIISMethods.MgdIsLastNotification(requestContext, status); 
            try { 
                context.Response.UpdateNativeResponse(sendHeaders);
            } 
            catch(Exception e) {
                // if we catch an exception here then
                // i) clear cached response body bytes on the worker request
                // ii) clear the managed headers, the IIS native headers, the mangaged httpwriter response buffers, and the native IIS response buffers 
                // iii) attempt to format the exception and write it to the response
                wr.UnlockCachedResponseBytes(); 
                context.AddError(e); 
                context.ReportRuntimeErrorIfExists(ref status);
                context.Response.UpdateNativeResponse(sendHeaders); 
            }

            if (sendHeaders) {
                context.FinishPipelineRequest(); 
            }
 
            // Perf optimization: dispose managed context if possible (no need to try if status is pending) 
            if (status != RequestNotificationStatus.Pending) {
                PipelineRuntime.DisposeHandler(context, requestContext, status); 
            }
        }

        internal static void FinishPipelineRequest(HttpContext context) { 
            // Remember that first request is done
            _theRuntime._firstRequestCompleted = true; 
            context.Request.Dispose(); 
            context.Response.Dispose();
            HttpApplication app = context.ApplicationInstance; 
            if(null != app) {
                HttpApplication.ThreadContext threadContext = context.IndicateCompletionContext;
                if (threadContext != null) {
                    if (!threadContext.HasLeaveBeenCalled) { 
                        lock (threadContext) {
                            if (!threadContext.HasLeaveBeenCalled) { 
                                threadContext.Leave(); 
                                context.IndicateCompletionContext = null;
                                context.InIndicateCompletion = false; 
                            }
                        }
                    }
                } 
                app.ReleaseAppInstance();
            } 
 
            SetExecutionTimePerformanceCounter(context);
            UpdatePerfCounters(context.Response.StatusCode); 
            if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_END_HANDLER, context.WorkerRequest);

            // In case of a HostingInit() error, app domain should not stick around
            if (HostingInitFailed) { 
                Debug.Trace("AppDomainFactory", "Shutting down appdomain because of HostingInit error");
                ShutdownAppDomain(ApplicationShutdownReason.HostingEnvironment, "HostingInit error"); 
            } 
        }
 

        /*
         * Process one request
         */ 
        private void ProcessRequestInternal(HttpWorkerRequest wr) {
            // Construct the Context on HttpWorkerRequest, hook everything together 
            HttpContext context; 

            try { 
                context = new HttpContext(wr, false /* initResponseWriter */);
            }
            catch {
                // If we fail to create the context for any reason, send back a 400 to make sure 
                // the request is correctly closed (relates to VSUQFE3962)
                wr.SendStatus(400, "Bad Request"); 
                wr.SendKnownResponseHeader(HttpWorkerRequest.HeaderContentType, "text/html; charset=utf-8"); 
                byte[] body = Encoding.ASCII.GetBytes("Bad Request");
                wr.SendResponseFromMemory(body, body.Length); 
                wr.FlushResponse(true);
                wr.EndOfRequest();
                return;
            } 

            wr.SetEndOfSendNotification(_asyncEndOfSendCallback, context); 
 
            // Count active requests
            Interlocked.Increment(ref _activeRequestCount); 
            HostingEnvironment.IncrementBusyCount();

            try {
                // First request initialization 
                try {
                    EnsureFirstRequestInit(context); 
                } 
                catch {
                    // If we are handling a DEBUG request, ignore the FirstRequestInit exception. 
                    // This allows the HttpDebugHandler to execute, and lets the debugger attach to
                    // the process (VSWhidbey 358135)
                    if (!context.Request.IsDebuggingRequest) {
                        throw; 
                    }
                } 
 
                // Init response writer (after we have config in first request init)
                // no need for impersonation as it is handled in config system 
                context.Response.InitResponseWriter();

                // Get application instance
                IHttpHandler app = HttpApplicationFactory.GetApplicationInstance(context); 

                if (app == null) 
                    throw new HttpException(SR.GetString(SR.Unable_create_app_object)); 

                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, app.GetType().FullName, "Start"); 

                // Process the request

                if (app is IHttpAsyncHandler) { 
                    // asynchronous handler
                    IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler)app; 
                    context.AsyncAppHandler = asyncHandler; 
                    asyncHandler.BeginProcessRequest(context, _handlerCompletionCallback, context);
                } 
                else {
                    // synchronous handler
                    app.ProcessRequest(context);
                    FinishRequest(context.WorkerRequest, context, null); 
                }
            } 
            catch (Exception e) { 
                context.Response.InitResponseWriter();
                FinishRequest(wr, context, e); 
            }
        }

        private void RejectRequestInternal(HttpWorkerRequest wr, bool silent) { 
            // Construct the Context on HttpWorkerRequest, hook everything together
            HttpContext context = new HttpContext(wr, false /* initResponseWriter */); 
            wr.SetEndOfSendNotification(_asyncEndOfSendCallback, context); 

            // Count active requests 
            Interlocked.Increment(ref _activeRequestCount);
            HostingEnvironment.IncrementBusyCount();

            if (silent) { 
                context.Response.InitResponseWriter();
                FinishRequest(wr, context, null); 
            } 
            else {
                PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.REQUESTS_REJECTED); 
                PerfCounters.IncrementCounter(AppPerfCounter.APP_REQUESTS_REJECTED);
                try {
                    throw new HttpException(503, SR.GetString(SR.Server_too_busy));
                } 
                catch (Exception e) {
                    context.Response.InitResponseWriter(); 
                    FinishRequest(wr, context, e); 
                }
            } 
        }


        /* 
         * Finish processing request, [....] or async
         */ 
        private void FinishRequest(HttpWorkerRequest wr, HttpContext context, Exception e) { 
            HttpResponse response = context.Response;
 
            if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_END_HANDLER, context.WorkerRequest);

            SetExecutionTimePerformanceCounter(context);
 
            // Flush in case of no error
            if (e == null) { 
                // impersonate around PreSendHeaders / PreSendContent 
                using (new ClientImpersonationContext(context, false)) {
                    try { 
                        // this sends the actual content in most cases
                        response.FinalFlushAtTheEndOfRequestProcessing();
                    }
                    catch (Exception eFlush) { 
                        e = eFlush;
                    } 
                } 
            }
 
            // Report error if any
            if (e != null) {
                if (_appOfflineMessage != null) {
                    try { 
                        response.StatusCode = 404;
                        response.OutputStream.Write(_appOfflineMessage, 0, _appOfflineMessage.Length); 
                        response.FinalFlushAtTheEndOfRequestProcessing(); 
                    }
                    catch { 
                    }
                }
                else {
                    using (new HttpContextWrapper(context)) { 
                        // when application is on UNC share the code below must
                        // be run while impersonating the token given by IIS 
                        using (new ApplicationImpersonationContext()) { 
                            try {
                                try { 
                                    // try to report error in a way that could possibly throw (a config exception)
                                    response.ReportRuntimeError(e, true /*canThrow*/, false);
                                }
                                catch (Exception eReport) { 
                                    // report the config error in a way that would not throw
                                    response.ReportRuntimeError(eReport, false /*canThrow*/, false); 
                                } 

                                response.FinalFlushAtTheEndOfRequestProcessing(); 
                            }
                            catch {
                            }
                        } 
                    }
                } 
            } 

            // Remember that first request is done 
            _firstRequestCompleted = true;


            // In case we reporting HostingInit() error, app domain should not stick around 
            if (_hostingInitFailed) {
                Debug.Trace("AppDomainFactory", "Shutting down appdomain because of HostingInit error"); 
                ShutdownAppDomain(ApplicationShutdownReason.HostingEnvironment, "HostingInit error"); 
            }
 
            // Check status code and increment proper counter
            // If it's an error status code (i.e. 400 or higher), increment the proper perf counters
            int statusCode = response.StatusCode;
            UpdatePerfCounters(statusCode); 

            context.FinishRequestForCachedPathData(statusCode); 
 
            wr.EndOfRequest();
 
            // Count active requests
            HostingEnvironment.DecrementBusyCount();
            Interlocked.Decrement(ref _activeRequestCount);
 
            // Schedule more work if some requests are queued
            if (_requestQueue != null) 
                _requestQueue.ScheduleMoreWorkIfNeeded(); 
        }
 
        //
        // Make sure shutdown happens only once
        //
 
        private bool InitiateShutdownOnce() {
            if (_shutdownInProgress) 
                return false; 

            lock (this) { 
                if (_shutdownInProgress)
                    return false;
                _shutdownInProgress = true;
            } 

            return true; 
        } 

        // 
        // Shutdown this and restart new app domain
        //

        private void ReleaseResourcesAndUnloadAppDomain(Object state /*not used*/) { 
            Debug.Trace("AppDomainFactory", "ReleaseResourcesAndUnloadAppDomain, Id=" + _appDomainAppId
                        + " DomainId = " + _appDomainId 
                        + " Stack = " + Environment.StackTrace ); 

            try { 
                PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.APPLICATION_RESTARTS);
            }
            catch {
            } 

            // Release all resources 
            try { 
                Dispose();
            } 
            catch {
            }

            Thread.Sleep(250); 

            AddAppDomainTraceMessage("before Unload"); 
 
            for (; ; ) {
                try { 
                    AppDomain.Unload(Thread.GetDomain());
                }
                catch (CannotUnloadAppDomainException) {
                    Debug.Assert(false); 
                }
                catch (Exception e) { 
                    Debug.Trace("AppDomainFactory", "AppDomain.Unload exception: " + e + "; Id=" + _appDomainAppId); 
                    AddAppDomainTraceMessage("Unload Exception: " + e);
                    throw; 
                }
            }
        }
 
        private static void SetExecutionTimePerformanceCounter(HttpContext context) {
            // Set the Request Execution time perf counter 
            TimeSpan elapsed = DateTime.UtcNow.Subtract(context.WorkerRequest.GetStartTime()); 
            long milli = elapsed.Ticks / TimeSpan.TicksPerMillisecond;
 
            if (milli > Int32.MaxValue)
                milli = Int32.MaxValue;

            PerfCounters.SetGlobalCounter(GlobalPerfCounter.REQUEST_EXECUTION_TIME, (int)milli); 
            PerfCounters.SetCounter(AppPerfCounter.APP_REQUEST_EXEC_TIME, (int)milli);
        } 
 
        private static void UpdatePerfCounters(int statusCode) {
            if (400 <= statusCode) { 
                PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_FAILED);
                switch (statusCode) {
                    case 401: // Not authorized
                        PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_AUTHORIZED); 
                        break;
                    case 404: // Not found 
                    case 414: // Not found 
                        PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_FOUND);
                        break; 
                }
            }
            else {
                // If status code is not in the 400-599 range (i.e. 200-299 success or 300-399 redirection), 
                // count it as a successful request.
                PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_SUCCEDED); 
            } 
        }
 
        private void WaitForRequestsToFinish(int waitTimeoutMs) {
            DateTime waitLimit = DateTime.UtcNow.AddMilliseconds(waitTimeoutMs);

            for (; ; ) { 
                if (_activeRequestCount == 0 && (_requestQueue == null || _requestQueue.IsEmpty))
                    break; 
 
                Thread.Sleep(250);
 
                // only apply timeout if a managed debugger is not attached
                if (!System.Diagnostics.Debugger.IsAttached && DateTime.UtcNow > waitLimit) {
                    break; // give it up
                } 
            }
        } 
 
        /*
         * Cleanup of all unmananged state 
         */
        private void Dispose() {
            // get shutdown timeout from config
            int drainTimeoutSec = HttpRuntimeSection.DefaultShutdownTimeout; 
            HttpRuntimeSection runtimeConfig = RuntimeConfig.GetAppLKGConfig().HttpRuntime;
            if (runtimeConfig != null) { 
                drainTimeoutSec = (int)runtimeConfig.ShutdownTimeout.TotalSeconds; 
            }
 
            // before aborting compilation give time to drain (new requests are no longer coming at this point)
            WaitForRequestsToFinish(drainTimeoutSec * 1000);

            // reject remaining queued requests 
            if (_requestQueue != null)
                _requestQueue.Drain(); 
 
            // give it a little more time to drain
            WaitForRequestsToFinish((drainTimeoutSec * 1000) / 6); 


            // wait for pending async io to complete,  prior to aborting requests
            // this isn't necessary for IIS 7, where the async sends are always done 
            // from native code with native buffers
            System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.WaitForPendingAsyncIo(); 
 
            // For IIS7 integrated pipeline, wait until GL_APPLICATION_STOP fires and
            // there are no active calls to IndicateCompletion before unloading the AppDomain 
            if (HttpRuntime.UseIntegratedPipeline) {
                PipelineRuntime.WaitForRequestsToDrain();
            }
 
#if ORCAS
            // Kill the HttpDataStore cleanup thread and dispose the storage provider 
            if (_httpDataStorageCleanup != null) { 
                _httpDataStorageCleanup.Stop();
            } 

            if (_httpDataStorageProvider != null) {
                _httpDataStorageProvider.Dispose();
            } 
#endif
 
            // Dispose AppDomainShutdownTimer 
            DisposeAppDomainShutdownTimer();
 
            // kill all remaining requests (and the timeout timer)
            _timeoutManager.Stop();

            // give it a little more time to drain 
            WaitForRequestsToFinish((drainTimeoutSec * 1000) / 6);
 
#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features 
            // double check for pending async io
            System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.WaitForPendingAsyncIo(); 

            // stop sqlcachedependency polling
            SqlCacheDependencyManager.Dispose((drainTimeoutSec * 1000) / 2);
#endif // !FEATURE_PAL 
            // cleanup cache (this ends all sessions)
            if (_cacheInternal != null) { 
                _cacheInternal.Dispose(); 
            }
#if SITECOUNTERS 

            // cleanup siteCounters (this flushes all counter data)
            if (_siteCounters != null) {
                _siteCounters.Dispose(); 
            }
#endif 
            // app on end, cleanup app instances 
            HttpApplicationFactory.EndApplication();  // call app_onEnd
 
            // stop file changes monitor
            _fcm.Stop();

            // stop health monitoring timer 
            HealthMonitoringManager.Shutdown();
        } 
 
        /*
         * Async completion of IIS7 pipeline (unlike OnHandlerCompletion, this may fire more than once). 
         */
        private void OnRequestNotificationCompletion(IAsyncResult ar) {
            try {
                OnRequestNotificationCompletionHelper(ar); 
            }
            catch(Exception e) { 
                ApplicationManager.RecordFatalException(e); 
                throw;
            } 
        }

        private void OnRequestNotificationCompletionHelper(IAsyncResult ar) {
            if (ar.CompletedSynchronously) { 
                Debug.Trace("PipelineRuntime", "OnRequestNotificationCompletion: completed synchronously");
                return; 
            } 

            Debug.Trace("PipelineRuntime", "OnRequestNotificationCompletion: completed asynchronously"); 

            RequestNotificationStatus status = RequestNotificationStatus.Continue;
            HttpContext context = (HttpContext) ar.AsyncState;
            IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest; 

            try { 
                context.ApplicationInstance.EndProcessRequestNotification(ar); 
            }
            catch (Exception e) { 
                status = RequestNotificationStatus.FinishRequest;
                context.AddError(e);
            }
 
            // RequestContext is set to null if this is the last notification, so we need to save it
            // for the call to PostCompletion 
            IntPtr requestContext = wr.RequestContext; 

            FinishRequestNotification(wr, context, ref status); 

            // set the notification context to null since we are exiting this notification
            context.NotificationContext = null;
 
            // Indicate completion to IIS, so that it can resume
            // request processing on an IIS thread 
            Debug.Trace("PipelineRuntime", "OnRequestNotificationCompletion(" + status + ")"); 
            int result = UnsafeIISMethods.MgdPostCompletion(requestContext, status);
            Misc.ThrowIfFailedHr(result); 
        }

        /*
         * Async completion of managed pipeline (called at most one time). 
         */
        private void OnHandlerCompletion(IAsyncResult ar) { 
            HttpContext context = (HttpContext)ar.AsyncState; 

            try { 
                context.AsyncAppHandler.EndProcessRequest(ar);
            }
            catch (Exception e) {
                context.AddError(e); 
            }
            finally { 
                // no longer keep AsyncAppHandler poiting to the application 
                // is only needed to call EndProcessRequest
                context.AsyncAppHandler = null; 
            }

            FinishRequest(context.WorkerRequest, context, context.Error);
        } 

        /* 
         * Notification from worker request that it is done writing from buffer 
         * so that the buffers can be recycled
         */ 
        private void EndOfSendCallback(HttpWorkerRequest wr, Object arg) {
            Debug.Trace("PipelineRuntime", "HttpRuntime.EndOfSendCallback");
            HttpContext context = (HttpContext)arg;
            context.Request.Dispose(); 
            context.Response.Dispose();
        } 
 
        /*
         * Notification when something in the bin directory changed 
         */
        private void OnCriticalDirectoryChange(Object sender, FileChangeEvent e) {
            // shutdown the app domain
            Debug.Trace("AppDomainFactory", "Shutting down appdomain because of bin dir change or directory rename." + 
                " FileName=" + e.FileName + " Action=" + e.Action);
 
            ApplicationShutdownReason reason = ApplicationShutdownReason.None; 
            string directoryName = new DirectoryInfo(e.FileName).Name;
 
            string message = directoryName + " dir change or directory rename";

            if (StringUtil.EqualsIgnoreCase(directoryName, CodeDirectoryName)) {
                reason = ApplicationShutdownReason.CodeDirChangeOrDirectoryRename; 
            }
            else if (StringUtil.EqualsIgnoreCase(directoryName, ResourcesDirectoryName)) { 
                reason = ApplicationShutdownReason.ResourcesDirChangeOrDirectoryRename; 
            }
            else if (StringUtil.EqualsIgnoreCase(directoryName, BrowsersDirectoryName)) { 
                reason = ApplicationShutdownReason.BrowsersDirChangeOrDirectoryRename;
            }
            else if (StringUtil.EqualsIgnoreCase(directoryName, BinDirectoryName)) {
                reason = ApplicationShutdownReason.BinDirChangeOrDirectoryRename; 
            }
 
            if (e.Action == FileAction.Added) { 
                // Make sure HttpRuntime does not ignore the appdomain shutdown if a file is added (VSWhidbey 363481)
                HttpRuntime.SetUserForcedShutdown(); 

                Debug.Trace("AppDomainFactorySpecial", "Call SetUserForcedShutdown: FileName=" + e.FileName + "; now=" + DateTime.Now);
            }
 
            ShutdownAppDomain(reason, message);
        } 
 
        /**
         * Coalesce file change notifications to minimize sharing violations and AppDomain restarts (ASURT 147492) 
         */
        private void CoalesceNotifications() {
            int waitChangeNotification = HttpRuntimeSection.DefaultWaitChangeNotification;
            int maxWaitChangeNotification = HttpRuntimeSection.DefaultMaxWaitChangeNotification; 
            try {
                HttpRuntimeSection config = RuntimeConfig.GetAppLKGConfig().HttpRuntime; 
                if (config != null) { 
                    waitChangeNotification = config.WaitChangeNotification;
                    maxWaitChangeNotification = config.MaxWaitChangeNotification; 
                }
            }
            catch {
            } 

            if (waitChangeNotification == 0 || maxWaitChangeNotification == 0) 
                return; 

            DateTime maxWait = DateTime.UtcNow.AddSeconds(maxWaitChangeNotification); 
            // Coalesce file change notifications
            try {
                while (DateTime.UtcNow < maxWait) {
                    if (DateTime.UtcNow > LastShutdownAttemptTime.AddSeconds(waitChangeNotification)) 
                        break;
 
                    Thread.Sleep(250); 
                }
            } 
            catch {
            }
        }
 
        // appdomain shutdown eventhandler
        internal static event BuildManagerHostUnloadEventHandler AppDomainShutdown; 
 
        internal static void OnAppDomainShutdown(BuildManagerHostUnloadEventArgs e) {
            if (AppDomainShutdown != null) { 
                AppDomainShutdown(_theRuntime, e);
            }
        }
 
        internal static void SetUserForcedShutdown() {
            _theRuntime._userForcedShutdown = true; 
        } 

        /* 
         * Shutdown the current app domain
         */
        internal static bool ShutdownAppDomain(ApplicationShutdownReason reason, string message) {
            return ShutdownAppDomainWithStackTrace(reason, message, null /*stackTrace*/); 
        }
 
        /* 
         * Shutdown the current app domain with a stack trace.  This is useful for callers that are running
         * on a QUWI callback, and wouldn't provide a meaningful stack trace by default. 
         */
        internal static bool ShutdownAppDomainWithStackTrace(ApplicationShutdownReason reason, string message, string stackTrace) {
            SetShutdownReason(reason, message);
            return ShutdownAppDomain(stackTrace); 
        }
 
        private static bool ShutdownAppDomain(string stackTrace) { 
            // Ignore notifications during the processing of the first request (ASURT 100335)
            if (!_theRuntime._firstRequestCompleted && !_theRuntime._userForcedShutdown) { 
                // check the timeout (don't disable notifications forever
                int delayTimeoutSec = HttpRuntimeSection.DefaultDelayNotificationTimeout;

                try { 
                    RuntimeConfig runtimeConfig = RuntimeConfig.GetAppLKGConfig();
                    if (runtimeConfig != null) { 
                        HttpRuntimeSection runtimeSection = runtimeConfig.HttpRuntime; 
                        if (runtimeSection != null) {
                            delayTimeoutSec = (int)runtimeSection.DelayNotificationTimeout.TotalSeconds; 

                            if (DateTime.UtcNow < _theRuntime._firstRequestStartTime.AddSeconds(delayTimeoutSec)) {
                                Debug.Trace("AppDomainFactory", "ShutdownAppDomain IGNORED (1st request is not done yet), Id = " + AppDomainAppIdInternal);
                                return false; 
                            }
                        } 
                    } 
                }
                catch { 
                }
            }

            try { 
                _theRuntime.RaiseShutdownWebEventOnce();
            } 
            catch { 
                // VSWhidbey 444472: if an exception is thrown, we consume it and continue executing the following code.
            } 

            // Update last time ShutdownAppDomain was called
            _theRuntime.LastShutdownAttemptTime = DateTime.UtcNow;
 
            _theRuntime.CoalesceNotifications();
 
            if (!HostingEnvironment.ShutdownInitiated) { 
                // This shutdown is not triggered by hosting environment - let it do the job
                HostingEnvironment.InitiateShutdown(); 
                return true;
            }

            //WOS 1400290: CantUnloadAppDomainException in ISAPI mode, wait until HostingEnvironment.ShutdownThisAppDomainOnce completes 
            if (HostingEnvironment.ShutdownInProgress) {
                return false; 
            } 

            // Make sure we don't go through shutdown logic many times 
            if (!_theRuntime.InitiateShutdownOnce())
                return false;

            Debug.Trace("AppDomainFactory", "ShutdownAppDomain, Id = " + AppDomainAppIdInternal + ", ShutdownInProgress=" + ShutdownInProgress 
                        + ", ShutdownMessage=" + _theRuntime._shutDownMessage);
 
            if (String.IsNullOrEmpty(stackTrace)) { 
                // Instrument to be able to see what's causing a shutdown
                new EnvironmentPermission(PermissionState.Unrestricted).Assert(); 
                try {
                    _theRuntime._shutDownStack = Environment.StackTrace;
                }
                finally { 
                    CodeAccessPermission.RevertAssert();
                } 
            } 
            else {
                _theRuntime._shutDownStack = stackTrace; 
            }

            // Notify when appdomain is about to shutdown.
            OnAppDomainShutdown(new BuildManagerHostUnloadEventArgs(_theRuntime._shutdownReason)); 

            // unload app domain from another CLR thread 
            ThreadPool.QueueUserWorkItem(_theRuntime._appDomainUnloadallback); 

            return true; 
        }

        internal static void RecoverFromUnexceptedAppDomainUnload() {
            if (_theRuntime._shutdownInProgress) 
                return;
 
            // someone unloaded app domain directly - tell unmanaged code 
            Debug.Trace("AppDomainFactory", "Unexpected AppDomainUnload");
            _theRuntime._shutdownInProgress = true; 

            // tell unmanaged code not to dispatch requests to this app domain
            try {
                ISAPIRuntime.RemoveThisAppDomainFromUnmanagedTable(); 
                PipelineRuntime.RemoveThisAppDomainFromUnmanagedTable();
                AddAppDomainTraceMessage("AppDomainRestart"); 
            } 
            finally {
                // release all resources 
                _theRuntime.Dispose();
            }
        }
 
        /*
         * Notification when app-level Config changed 
         */ 
        internal static void OnConfigChange() {
            Debug.Trace("AppDomainFactory", "Shutting down appdomain because of config change"); 
            ShutdownAppDomain(ApplicationShutdownReason.ConfigurationChange, "CONFIG change");
        }

        // Intrumentation to remember the overwhelming file change 
        internal static void SetShutdownReason(ApplicationShutdownReason reason, String message) {
            if (_theRuntime._shutdownReason == ApplicationShutdownReason.None) { 
                _theRuntime._shutdownReason = reason; 
            }
 
            SetShutdownMessage(message);
        }

        internal static void SetShutdownMessage(String message) { 
            if (message != null) {
                if (_theRuntime._shutDownMessage == null) 
                    _theRuntime._shutDownMessage = message; 
                else
                    _theRuntime._shutDownMessage += "\r\n" + message; 
            }
        }

 
        // public method is on HostingEnvironment
        internal static ApplicationShutdownReason ShutdownReason { 
            get { return _theRuntime._shutdownReason; } 
        }
 
        //
        // public static APIs
        //
 
        /*
         * Process one request 
         */ 

        ///  
        ///    The method that drives
        ///       all ASP.NET web processing execution.
        /// 
        [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)] 
        public static void ProcessRequest(HttpWorkerRequest wr) {
            if (wr == null) 
                throw new ArgumentNullException("wr"); 

            if (HttpRuntime.UseIntegratedPipeline) { 
                throw new PlatformNotSupportedException(SR.GetString(SR.Method_Not_Supported_By_Iis_Integrated_Mode, "HttpRuntime.ProcessRequest"));
            }

            ProcessRequestNoDemand(wr); 
        }
 
 
        internal static void ProcessRequestNoDemand(HttpWorkerRequest wr) {
            RequestQueue rq = _theRuntime._requestQueue; 

            if (rq != null)  // could be null before first request
                wr = rq.GetRequestToExecute(wr);
 
            if (wr != null) {
                CalculateWaitTimeAndUpdatePerfCounter(wr); 
                wr.ResetStartTime(); 
                ProcessRequestNow(wr);
            } 
        }


        private static void CalculateWaitTimeAndUpdatePerfCounter(HttpWorkerRequest wr) { 
            DateTime begin = wr.GetStartTime();
 
            TimeSpan elapsed = DateTime.UtcNow.Subtract(begin); 
            long milli = elapsed.Ticks / TimeSpan.TicksPerMillisecond;
 
            if (milli > Int32.MaxValue)
                milli = Int32.MaxValue;

            PerfCounters.SetGlobalCounter(GlobalPerfCounter.REQUEST_WAIT_TIME, (int)milli); 
            PerfCounters.SetCounter(AppPerfCounter.APP_REQUEST_WAIT_TIME, (int)milli);
        } 
 
        internal static void ProcessRequestNow(HttpWorkerRequest wr) {
            _theRuntime.ProcessRequestInternal(wr); 
        }

        internal static void RejectRequestNow(HttpWorkerRequest wr, bool silent) {
            _theRuntime.RejectRequestInternal(wr, silent); 
        }
 
 
        /// 
        ///       Removes all items from the cache and shuts down the runtime. 
        ///    
        [SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
        public static void Close() {
            Debug.Trace("AppDomainFactory", "HttpRuntime.Close, ShutdownInProgress=" + ShutdownInProgress); 
            if (_theRuntime.InitiateShutdownOnce()) {
                SetShutdownReason(ApplicationShutdownReason.HttpRuntimeClose, "HttpRuntime.Close is called"); 
 
                if (HostingEnvironment.IsHosted) {
                    // go throw initiate shutdown for hosted scenarios 
                    HostingEnvironment.InitiateShutdown();
                }
                else {
                    _theRuntime.Dispose(); 
                }
            } 
        } 

 
        /// 
        ///       Unloads the current app domain.
        ///    
        [SecurityPermission(SecurityAction.Demand, Unrestricted = true)] 
        public static void UnloadAppDomain() {
            _theRuntime._userForcedShutdown = true; 
            ShutdownAppDomain(ApplicationShutdownReason.UnloadAppDomainCalled, "User code called UnloadAppDomain"); 
        }
 
        private DateTime LastShutdownAttemptTime {
            get {
                DateTime dt;
                lock (this) { 
                    dt = _lastShutdownAttemptTime;
                } 
                return dt; 
            }
            set { 
                lock (this) {
                    _lastShutdownAttemptTime = value;
                }
            } 
        }
 
        internal static Profiler Profile { 
            get {
                return _theRuntime._profiler; 
            }
        }

        internal static bool IsTrustLevelInitialized { 
            get {
                return !HostingEnvironment.IsHosted || TrustLevel != null; 
            } 
        }
 
        internal static NamedPermissionSet NamedPermissionSet {
            get {
                // Make sure we have already initialized the trust level
                // 

 
                return _theRuntime._namedPermissionSet; 
            }
        } 

        [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Unrestricted)]
        public static NamedPermissionSet GetNamedPermissionSet() {
            NamedPermissionSet namedPermissionSet = _theRuntime._namedPermissionSet; 
            if (namedPermissionSet == null) {
                return null; 
            } 
            else {
                return new NamedPermissionSet(namedPermissionSet); 
            }
        }

 
        internal static bool IsFullTrust {
            get { 
                // Make sure we have already initialized the trust level 
                Debug.Assert(IsTrustLevelInitialized);
 
                return (_theRuntime._namedPermissionSet == null);
            }
        }
 
        /*
         * Check that the current trust level allows access to a virtual path.  Throw if it doesn't, 
         */ 
        internal static void CheckVirtualFilePermission(string virtualPath) {
            string physicalPath = HostingEnvironment.MapPath(virtualPath); 
            CheckFilePermission(physicalPath);
        }

        /* 
         * Check that the current trust level allows access to a path.  Throw if it doesn't,
         */ 
        internal static void CheckFilePermission(string path) { 
            CheckFilePermission(path, false);
        } 

        internal static void CheckFilePermission(string path, bool writePermissions) {
            if (!HasFilePermission(path, writePermissions)) {
                throw new HttpException(SR.GetString(SR.Access_denied_to_path, GetSafePath(path))); 
            }
        } 
 
        internal static bool HasFilePermission(string path) {
            return HasFilePermission(path, false); 
        }

        internal static bool HasFilePermission(string path, bool writePermissions) {
            // WOS #1523618: need to skip this check for HttpResponse.ReportRuntimeError when reporting an 
            // InitializationException (e.g., necessary to display line info for ConfigurationException).
 
            if (TrustLevel == null && InitializationException != null) { 
                return true;
            } 

            // Make sure we have already initialized the trust level
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted, "TrustLevel != null || !HostingEnvironment.IsHosted");
 
            // If we don't have a NamedPermissionSet, we're in full trust
            if (NamedPermissionSet == null) 
                return true; 

            bool fAccess = false; 

            // Check that the user has permission to the path
            IPermission allowedPermission = NamedPermissionSet.GetPermission(typeof(FileIOPermission));
            if (allowedPermission != null) { 
                IPermission askedPermission = null;
                try { 
                    if (!writePermissions) 
                        askedPermission = new FileIOPermission(FileIOPermissionAccess.Read, path);
                    else 
                        askedPermission = new FileIOPermission(FileIOPermissionAccess.AllAccess, path);
                }
                catch {
                    // This could happen if the path is not absolute 
                    return false;
                } 
                fAccess = askedPermission.IsSubsetOf(allowedPermission); 
            }
 
            return fAccess;
        }

        internal static bool HasWebPermission(Uri uri) { 

            // Make sure we have already initialized the trust level 
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted); 

            // If we don't have a NamedPermissionSet, we're in full trust 
            if (NamedPermissionSet == null)
                return true;

            bool fAccess = false; 

            // Check that the user has permission to the URI 
            IPermission allowedPermission = NamedPermissionSet.GetPermission(typeof(WebPermission)); 
            if (allowedPermission != null) {
                IPermission askedPermission = null; 
                try {
                    askedPermission = new WebPermission(NetworkAccess.Connect, uri.ToString());
                }
                catch { 
                    return false;
                } 
                fAccess = askedPermission.IsSubsetOf(allowedPermission); 
            }
 
            return fAccess;
        }

        internal static bool HasDbPermission(DbProviderFactory factory) { 

            // Make sure we have already initialized the trust level 
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted); 

            // If we don't have a NamedPermissionSet, we're in full trust 
            if (NamedPermissionSet == null)
                return true;

            bool fAccess = false; 

            // Check that the user has permission to the provider 
            CodeAccessPermission askedPermission = factory.CreatePermission(PermissionState.Unrestricted); 
            if (askedPermission != null) {
                IPermission allowedPermission = NamedPermissionSet.GetPermission(askedPermission.GetType()); 
                if (allowedPermission != null) {
                    fAccess = askedPermission.IsSubsetOf(allowedPermission);
                }
            } 

            return fAccess; 
        } 

        internal static bool HasPathDiscoveryPermission(string path) { 
            // WOS #1523618: need to skip this check for HttpResponse.ReportRuntimeError when reporting an
            // InitializationException (e.g., necessary to display line info for ConfigurationException).

            if (TrustLevel == null && InitializationException != null) { 
                return true;
            } 
 
            // Make sure we have already initialized the trust level
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted); 

            // If we don't have a NamedPermissionSet, we're in full trust
            if (NamedPermissionSet == null)
                return true; 

            bool fAccess = false; 
 
            // Check that the user has permission to the path
            IPermission allowedPermission = NamedPermissionSet.GetPermission(typeof(FileIOPermission)); 
            if (allowedPermission != null) {
                IPermission askedPermission = new FileIOPermission(FileIOPermissionAccess.PathDiscovery, path);
                fAccess = askedPermission.IsSubsetOf(allowedPermission);
            } 

            return fAccess; 
 
        }
 
        internal static bool HasAppPathDiscoveryPermission() {
            return HasPathDiscoveryPermission(HttpRuntime.AppDomainAppPathInternal);
        }
 
        internal static string GetSafePath(string path) {
            if (String.IsNullOrEmpty(path)) 
                return path; 

            try { 
                if (HasPathDiscoveryPermission(path)) // could throw on bad filenames
                    return path;
            }
            catch { 
            }
 
            return Path.GetFileName(path); 
        }
 
        /*
         * Check that the current trust level allows Unmanaged access
         */
        internal static bool HasUnmanagedPermission() { 

            // Make sure we have already initialized the trust level 
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted); 

            // If we don't have a NamedPermissionSet, we're in full trust 
            if (NamedPermissionSet == null)
                return true;

            SecurityPermission securityPermission = (SecurityPermission)NamedPermissionSet.GetPermission( 
                typeof(SecurityPermission));
            if (securityPermission == null) 
                return false; 

            return (securityPermission.Flags & SecurityPermissionFlag.UnmanagedCode) != 0; 
        }

        internal static bool HasAspNetHostingPermission(AspNetHostingPermissionLevel level) {
 
            // Make sure we have already initialized the trust level
            // 
 

 
            // If we don't have a NamedPermissionSet, we're in full trust
            if (NamedPermissionSet == null)
                return true;
 
            AspNetHostingPermission permission = (AspNetHostingPermission)NamedPermissionSet.GetPermission(
                typeof(AspNetHostingPermission)); 
            if (permission == null) 
                return false;
 
            return (permission.Level >= level);
        }

        internal static void CheckAspNetHostingPermission(AspNetHostingPermissionLevel level, String errorMessageId) { 
            if (!HasAspNetHostingPermission(level)) {
                throw new HttpException(SR.GetString(errorMessageId)); 
            } 
        }
 
        // If we're not in full trust, fail if the passed in type doesn't have the APTCA bit
        internal static void FailIfNoAPTCABit(Type t, ElementInformation elemInfo, string propertyName) {

            if (!IsTypeAllowedInConfig(t)) { 
                if (null != elemInfo) {
                    PropertyInformation propInfo = elemInfo.Properties[propertyName]; 
 
                    throw new ConfigurationErrorsException(SR.GetString(SR.Type_from_untrusted_assembly, t.FullName),
                    propInfo.Source, propInfo.LineNumber); 
                }
                else {
                    throw new ConfigurationErrorsException(SR.GetString(SR.Type_from_untrusted_assembly, t.FullName));
                } 
            }
        } 
 
        // If we're not in full trust, fail if the passed in type doesn't have the APTCA bit
        internal static void FailIfNoAPTCABit(Type t, XmlNode node) { 

            if (!IsTypeAllowedInConfig(t)) {
                throw new ConfigurationErrorsException(SR.GetString(SR.Type_from_untrusted_assembly, t.FullName),
                    node); 
            }
        } 
 
        private static bool HasAPTCABit(Assembly assembly) {
            Object[] attrs = assembly.GetCustomAttributes( 
                typeof(System.Security.AllowPartiallyTrustedCallersAttribute), /*inherit*/ false);
            return (attrs != null && attrs.Length > 0);
        }
 
        // Check if the type is allowed to be used in config by checking the APTCA bit
        internal static bool IsTypeAllowedInConfig(Type t) { 
 
            // Allow everything in full trust
            if (HttpRuntime.HasAspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted)) 
                return true;

            Assembly assembly = t.Assembly;
 
            // The APTCA bit is only relevant for assemblies living in the GAC, since the rest runs
            // under partial trust (VSWhidbey 422183) 
            if (!assembly.GlobalAssemblyCache) 
                return true;
 
            // If it has the APTCA bit, allow it
            if (HttpRuntime.HasAPTCABit(assembly))
                return true;
 
            // It's a GAC type without APTCA in partial trust scenario: block it
            return false; 
        } 

        internal static FileChangesMonitor FileChangesMonitor { 
            get { return _theRuntime._fcm; }
        }

#if ORCAS 
        internal static IHttpDataStorageProvider HttpDataStorageProvider {
            get { return _theRuntime._httpDataStorageProvider;} 
        } 
#endif
 
        internal static RequestTimeoutManager RequestTimeoutManager {
            get { return _theRuntime._timeoutManager; }
        }
 

        ///  
        ///    Provides access to the cache. 
        /// 
        public static Cache Cache { 
            get {

                if (HttpRuntime.AspInstallDirectoryInternal == null) {
                    throw new HttpException(SR.GetString(SR.Aspnet_not_installed, VersionInfo.SystemWebVersion)); 
                }
 
                // In a web app, ReadCacheInternalConfig() is called from HttpRuntime.HostingInit. 
                // However, if the cache is used by a non-http app, HttpRuntime.HostingInit won't
                // be called and we need to find a way to call ReadCacheInternalConfig(). 
                // The safe and inexpensive place to call it is when the non-http app accesses the
                // Cache thru HttpRuntime.Cache.
                //
                // ReadCacheInternalConfig() protects itself from being read multiple times. 
                //
                Cache cachePublic = _theRuntime._cachePublic; 
                if (cachePublic == null) { 
                    CacheInternal cacheInternal = CacheInternal;
                    CacheSection cacheSection = RuntimeConfig.GetAppConfig().Cache; 
                    cacheInternal.ReadCacheInternalConfig(cacheSection);
                    _theRuntime._cachePublic = cacheInternal.CachePublic;
                    cachePublic = _theRuntime._cachePublic;
                } 

                return cachePublic; 
            } 
        }
 
        private void CreateCache() {
            lock (this) {
                if (_cacheInternal == null) {
                    _cacheInternal = CacheInternal.Create(); 
                }
            } 
        } 

        internal static CacheInternal CacheInternal { 
            get {
                // Note that we only create the cache on first access,
                // not in HttpRuntime initialization.
                // This prevents cache timers from running when 
                // the cache is not used.
                CacheInternal cacheInternal = _theRuntime._cacheInternal; 
                if (cacheInternal == null) { 
                    _theRuntime.CreateCache();
                    cacheInternal = _theRuntime._cacheInternal; 
                }

                return cacheInternal;
            } 
        }
#if SITECOUNTERS 
        internal static SiteCounters SiteCounters { 
            get { return _theRuntime._siteCounters; }
        } 
#endif

        /// 
        ///    [To be supplied.] 
        /// 
        public static string AspInstallDirectory { 
            get { 
                String path = AspInstallDirectoryInternal;
 
                if (path == null) {
                    throw new HttpException(SR.GetString(SR.Aspnet_not_installed, VersionInfo.SystemWebVersion));
                }
 
                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path; 
            } 
        }
 
        internal static string AspInstallDirectoryInternal {
            get { return s_installDirectory; }
        }
 
        //
        // Return the client script virtual path, e.g. "/aspnet_client/system_web/2_0_50217" 
        // 
        public static string AspClientScriptVirtualPath {
            get { 
                if (_theRuntime._clientScriptVirtualPath == null) {
                    string aspNetVersion = VersionInfo.SystemWebVersion;
                    string clientScriptVirtualPath = AspNetClientFilesParentVirtualPath + aspNetVersion.Substring(0, aspNetVersion.LastIndexOf('.')).Replace('.', '_');
 
                    _theRuntime._clientScriptVirtualPath = clientScriptVirtualPath;
                } 
 
                return _theRuntime._clientScriptVirtualPath;
            } 
        }

        public static string AspClientScriptPhysicalPath {
            get { 
                String path = AspClientScriptPhysicalPathInternal;
 
                if (path == null) { 
                    throw new HttpException(SR.GetString(SR.Aspnet_not_installed, VersionInfo.SystemWebVersion));
                } 

                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path;
            } 
        }
 
        // 
        // Return the client script physical path, e.g. @"c:\windows\microsoft.net\framework\v2.0.50217.0\asp.netclientfiles"
        // 
        internal static string AspClientScriptPhysicalPathInternal {
            get {
                if (_theRuntime._clientScriptPhysicalPath == null) {
                    string clientScriptPhysicalPath = System.IO.Path.Combine(AspInstallDirectoryInternal, AspNetClientFilesSubDirectory); 

                    _theRuntime._clientScriptPhysicalPath = clientScriptPhysicalPath; 
                } 

                return _theRuntime._clientScriptPhysicalPath; 
            }
        }

 
        /// 
        ///    [To be supplied.] 
        ///  
        public static string ClrInstallDirectory {
            get { 
                String path = ClrInstallDirectoryInternal;
                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path;
            } 
        }
 
        internal static string ClrInstallDirectoryInternal { 
            get { return HttpConfigurationSystem.MsCorLibDirectory; }
        } 



        ///  
        ///    [To be supplied.]
        ///  
        public static string MachineConfigurationDirectory { 
            get {
                String path = MachineConfigurationDirectoryInternal; 
                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path;
            }
        } 

        internal static string MachineConfigurationDirectoryInternal { 
            get { return HttpConfigurationSystem.MachineConfigurationDirectory; } 
        }
 
        internal static bool IsEngineLoaded {
            get { return s_isEngineLoaded; }
        }
 

        // 
        //  Static app domain related properties 
        //
 

        /// 
        ///    [To be supplied.]
        ///  
        public static String CodegenDir {
            get { 
                String path = CodegenDirInternal; 
                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path; 
            }
        }

        internal static string CodegenDirInternal { 
            get { return _theRuntime._codegenDir; }
        } 
 
        internal static string TempDirInternal {
            get { return _theRuntime._tempDir; } 
        }


        ///  
        ///    [To be supplied.]
        ///  
        public static String AppDomainAppId { 
            [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
            get { 
                return AppDomainAppIdInternal;
            }
        }
 
        internal static string AppDomainAppIdInternal {
            get { return _theRuntime._appDomainAppId; } 
        } 

        internal static bool IsAspNetAppDomain { 
            get { return AppDomainAppIdInternal != null; }
        }

 

        ///  
        ///    [To be supplied.] 
        /// 
        public static String AppDomainAppPath { 
            get {
                InternalSecurityPermissions.AppPathDiscovery.Demand();
                return AppDomainAppPathInternal;
            } 
        }
 
        internal static string AppDomainAppPathInternal { 
            get { return _theRuntime._appDomainAppPath; }
        } 


        /// 
        ///    [To be supplied.] 
        /// 
        public static String AppDomainAppVirtualPath { 
            get { 
                return VirtualPath.GetVirtualPathStringNoTrailingSlash(_theRuntime._appDomainAppVPath);
            } 
        }

        // Save as AppDomainAppVirtualPath, but includes the trailng slash.  We can't change
        // AppDomainAppVirtualPath since it's public. 
        internal static String AppDomainAppVirtualPathString {
            get { 
                return VirtualPath.GetVirtualPathString(_theRuntime._appDomainAppVPath); 
            }
        } 

        internal static VirtualPath AppDomainAppVirtualPathObject {
            get {
                return _theRuntime._appDomainAppVPath; 
            }
        } 
 
        internal static bool IsPathWithinAppRoot(String path) {
            if (AppDomainIdInternal == null) 
                return true;    // app domain not initialized

            return UrlPath.IsEqualOrSubpath(AppDomainAppVirtualPathString, path);
        } 

 
        ///  
        ///    [To be supplied.]
        ///  
        public static String AppDomainId {
            [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
            get {
                return AppDomainIdInternal; 
            }
        } 
 
        internal static string AppDomainIdInternal {
            get { return _theRuntime._appDomainId; } 
        }


 
        /// 
        ///    [To be supplied.] 
        ///  
        public static String BinDirectory {
            get { 
                String path = BinDirectoryInternal;
                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path;
            } 
        }
 
        internal static string BinDirectoryInternal { 
            get { return Path.Combine(_theRuntime._appDomainAppPath, BinDirectoryName) + Path.DirectorySeparatorChar; }
 
        }

        internal static VirtualPath CodeDirectoryVirtualPath {
            get { return _theRuntime._appDomainAppVPath.SimpleCombineWithDir(CodeDirectoryName); } 
        }
 
        internal static VirtualPath ResourcesDirectoryVirtualPath { 
            get { return _theRuntime._appDomainAppVPath.SimpleCombineWithDir(ResourcesDirectoryName); }
        } 

        internal static VirtualPath WebRefDirectoryVirtualPath {
            get { return _theRuntime._appDomainAppVPath.SimpleCombineWithDir(WebRefDirectoryName); }
        } 

 
        ///  
        ///    [To be supplied.]
        ///  
        public static bool IsOnUNCShare {
            [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)]
            get {
                return IsOnUNCShareInternal; 
            }
        } 
 
        internal static bool IsOnUNCShareInternal {
            get { return _theRuntime._isOnUNCShare; } 
        }


        // 
        //  Static helper to retrieve app domain values
        // 
 
        private static String GetAppDomainString(String key) {
            Object x = Thread.GetDomain().GetData(key); 

            return x as String;
        }
 
        internal static void AddAppDomainTraceMessage(String message) {
            const String appDomainTraceKey = "ASP.NET Domain Trace"; 
            AppDomain d = Thread.GetDomain(); 
            String m = d.GetData(appDomainTraceKey) as String;
            d.SetData(appDomainTraceKey, (m != null) ? m + " ... " + message : message); 
        }


        // 
        //  Flags
        // 
 
        internal static bool DebuggingEnabled {
            get { return _theRuntime._debuggingEnabled; } 
        }

        internal static bool ConfigInited {
            get { return _theRuntime._configInited; } 
        }
 
        internal static bool FusionInited { 
            get { return _theRuntime._fusionInited; }
        } 

        internal static bool ApartmentThreading {
            get { return _theRuntime._apartmentThreading; }
        } 

        internal static bool ShutdownInProgress { 
            get { return _theRuntime._shutdownInProgress; } 
        }
 
        internal static string TrustLevel {
            get { return _theRuntime._trustLevel; }
        }
 
        internal static string WpUserId {
            get { return _theRuntime._wpUserId; } 
        } 

 
        private void SetTrustLevel(TrustSection trustSection, SecurityPolicySection securityPolicySection) {
            if (trustSection == null || String.IsNullOrEmpty(trustSection.Level)) {
                throw new ConfigurationErrorsException(SR.GetString(SR.Config_section_not_present, "trust"));
            } 

            // Use a temporary variable, since we use the field as a signal that the trust has really 
            // been set, which is not the case until later in this method. 
            string trustLevel = trustSection.Level;
 
            if (trustSection.Level == "Full") {
                _trustLevel = trustLevel;
                return;
            } 

            if (securityPolicySection == null || securityPolicySection.TrustLevels[trustSection.Level] == null) { 
                throw new ConfigurationErrorsException(SR.GetString(SR.Unable_to_get_policy_file, trustSection.Level), String.Empty, 0); 
                //             Do not give out configuration information since we don't know what trust level we are
                //             supposed to be running at.  If the information below is added to the error it might expose 
                //             part of the config file that the users does not have permissions to see. VS261145
                //            ,trustSection.ElementInformation.Properties["level"].Source,
                //            trustSection.ElementInformation.Properties["level"].LineNumber);
            } 
            String file = (String)securityPolicySection.TrustLevels[trustSection.Level].PolicyFileExpanded;
            if (file == null || !FileUtil.FileExists(file)) { 
                //if HttpContext.Current.IsCustomErrorEnabled 
                throw new HttpException(SR.GetString(SR.Unable_to_get_policy_file, trustSection.Level));
                //else 
                //    throw new ConfigurationErrorsException(SR.GetString(SR.Unable_to_get_policy_file, trustSection.Level),
                //        trustSection.Filename, trustSection.LineNumber);
            }
 
            bool foundGacToken = false;
            PolicyLevel policyLevel = CreatePolicyLevel(file, AppDomainAppPathInternal, CodegenDirInternal, trustSection.OriginUrl, out foundGacToken); 
 
            // see if the policy file contained a v1.x UrlMembershipCondition containing
            // a GAC token.  If so, let's upgrade it by adding a code group granting 
            // full trust to code from the GAC
            if (foundGacToken) {
                // walk the code groups at the app domain level and look for one that grants
                // access to the GAC with an UrlMembershipCondition. 
                CodeGroup rootGroup = policyLevel.RootCodeGroup;
                bool foundGacCondition = false; 
                foreach (CodeGroup childGroup in rootGroup.Children) { 
                    if (childGroup.MembershipCondition is GacMembershipCondition) {
                        foundGacCondition = true; 

                        // if we found the GAC token and also have the GacMembershipCondition
                        // the policy file needs to be upgraded to just include the GacMembershipCondition
                        Debug.Assert(!foundGacCondition); 
                        break;
                    } 
                } 

                // add one as a child of the toplevel group after 
                // some sanity checking to make sure it's an ASP.NET policy file
                // which always begins with a FirstMatchCodeGroup granting nothing
                // this might not upgrade some custom policy files
                if (!foundGacCondition) { 
                    if (rootGroup is FirstMatchCodeGroup) {
                        FirstMatchCodeGroup firstMatch = (FirstMatchCodeGroup)rootGroup; 
                        if (firstMatch.MembershipCondition is AllMembershipCondition && 
                           firstMatch.PermissionSetName == "Nothing") {
                            PermissionSet fullTrust = new PermissionSet(PermissionState.Unrestricted); 

                            CodeGroup gacGroup = new UnionCodeGroup(new GacMembershipCondition(),
                                                                    new PolicyStatement(fullTrust));
 

                            // now, walk the current groups and insert our new group 
                            // immediately before the old Gac group 
                            // we'll need to use heuristics for this:
                            // it will be an UrlMembershipCondition group with full trust 
                            CodeGroup newRoot = new FirstMatchCodeGroup(rootGroup.MembershipCondition, rootGroup.PolicyStatement);
                            foreach (CodeGroup childGroup in rootGroup.Children) {

                                // is this the target old $Gac$ group? 
                                // insert our new GacMembershipCondition group ahead of it
                                if ((childGroup is UnionCodeGroup) && 
                                   (childGroup.MembershipCondition is UrlMembershipCondition) && 
                                   childGroup.PolicyStatement.PermissionSet.IsUnrestricted()) {
                                    if (null != gacGroup) { 
                                        newRoot.AddChild(gacGroup);
                                        gacGroup = null;
                                    }
                                } 

                                // append this group to the root group 
                                // AddChild itself does a deep Copy to get any 
                                // child groups so we don't need one here
                                newRoot.AddChild(childGroup); 
                            }

                            policyLevel.RootCodeGroup = newRoot;
                            //Debug.Trace("internal", "PolicyLevel: " + policyLevel.ToXml()); 
                        }
                    } 
                } 
            }
 

            AppDomain.CurrentDomain.SetAppDomainPolicy(policyLevel);
            _namedPermissionSet = policyLevel.GetNamedPermissionSet("ASP.Net");
 
            _trustLevel = trustLevel;
 
            _fcm.StartMonitoringFile(file, new FileChangeEventHandler(this.OnSecurityPolicyFileChange)); 
        }
 
        private static PolicyLevel CreatePolicyLevel(String configFile, String appDir, String binDir, String strOriginUrl, out bool foundGacToken) {
            // Read in the config file to a string.
            FileStream file = new FileStream(configFile, FileMode.Open, FileAccess.Read);
            StreamReader reader = new StreamReader(file, Encoding.UTF8); 
            String strFileData = reader.ReadToEnd();
 
            reader.Close(); 

            appDir = FileUtil.RemoveTrailingDirectoryBackSlash(appDir); 
            binDir = FileUtil.RemoveTrailingDirectoryBackSlash(binDir);

            strFileData = strFileData.Replace("$AppDir$", appDir);
            strFileData = strFileData.Replace("$AppDirUrl$", MakeFileUrl(appDir)); 
            strFileData = strFileData.Replace("$CodeGen$", MakeFileUrl(binDir));
            if (strOriginUrl == null) 
                strOriginUrl = String.Empty; 
            strFileData = strFileData.Replace("$OriginHost$", strOriginUrl);
 
            // see if the file contains a GAC token
            // if so, do the replacement and record the
            // fact so that we later add a GacMembershipCondition
            // codegroup to the PolicyLevel 
            int ndx = strFileData.IndexOf("$Gac$", StringComparison.Ordinal);
            if (ndx != -1) { 
                string gacLocation = GetGacLocation(); 
                if (gacLocation != null)
                    gacLocation = MakeFileUrl(gacLocation); 
                if (gacLocation == null)
                    gacLocation = String.Empty;

                strFileData = strFileData.Replace("$Gac$", gacLocation); 
                foundGacToken = true;
            } 
            else { 
                foundGacToken = false;
            } 

            return SecurityManager.LoadPolicyLevelFromString(strFileData, PolicyLevelType.AppDomain);
        }
 
        /*
         * Notification when something in the code-access security policy file changed 
         */ 
        private void OnSecurityPolicyFileChange(Object sender, FileChangeEvent e) {
            // shutdown the app domain 
            Debug.Trace("AppDomainFactory", "Shutting down appdomain because code-access security policy file changed");
            ShutdownAppDomain(ApplicationShutdownReason.ChangeInSecurityPolicyFile,
                                "Change in code-access security policy file");
        } 

 
        // notification when app_offline.htm file changed or created 
        private void OnAppOfflineFileChange(Object sender, FileChangeEvent e) {
            // shutdown the app domain 
            Debug.Trace("AppOffline", AppOfflineFileName + " changed - shutting down the app domain");
            Debug.Trace("AppDomainFactory", "Shutting down appdomain because " + AppOfflineFileName + " file changed");
            // WOS 1948399: set _userForcedShutdown to avoid DelayNotificationTimeout, since first request has not completed yet in integrated mode;
            SetUserForcedShutdown(); 
            ShutdownAppDomain(ApplicationShutdownReason.ConfigurationChange, "Change in " + AppOfflineFileName);
        } 
 
        private static String MakeFileUrl(String path) {
            Uri uri = new Uri(path); 
            return uri.ToString();
        }

        private static String GetGacLocation() { 

            StringBuilder buf = new StringBuilder(262); 
            int iSize = 260; 

            // 

            if (UnsafeNativeMethods.GetCachePath(2, buf, ref iSize) >= 0)
                return buf.ToString();
            throw new HttpException(SR.GetString(SR.GetGacLocaltion_failed)); 
        }
 
 
        /*
         * Remove from metabase all read/write/browse permission from certain subdirs 
         *
         */
        internal static void RestrictIISFolders(HttpContext context) {
            int ret; 

            HttpWorkerRequest wr = context.WorkerRequest; 
 
            Debug.Assert(AppDomainAppIdInternal != null);
 
            // Don't do it if we are not running on IIS
            if (wr == null || !(wr is System.Web.Hosting.ISAPIWorkerRequest)) {
                return;
            } 

            // Do it only for IIS 5 
#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features 
            if (!(wr is System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6))
#endif // !FEATURE_PAL 
 {
                byte[] bufin;
                byte[] bufout = new byte[1];   // Just to keep EcbCallISAPI happy
 
                bufin = BitConverter.GetBytes(UnsafeNativeMethods.RESTRICT_BIN);
                ret = context.CallISAPI(UnsafeNativeMethods.CallISAPIFunc.RestrictIISFolders, bufin, bufout); 
                if (ret != 1) { 
                    // Cannot pass back any HR from inetinfo.exe because CSyncPipeManager::GetDataFromIIS
                    // does not support passing back any value when there is an error. 
                    Debug.Trace("RestrictIISFolders", "Cannot restrict folder access for '" + AppDomainAppIdInternal + "'.");
                }
            }
        } 

        // 
        // Helper to create instances (public vs. internal/private ctors, see 89781) 
        //
 
        internal static Object CreateNonPublicInstance(Type type) {
            return CreateNonPublicInstance(type, null);
        }
 
        internal static Object CreateNonPublicInstance(Type type, Object[] args) {
            return Activator.CreateInstance( 
                type, 
                BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.CreateInstance,
                null, 
                args,
                null);
        }
 
        internal static Object CreatePublicInstance(Type type) {
            return Activator.CreateInstance(type); 
        } 

#if !DONTUSEFACTORYGENERATOR 
        // Cache instances of IWebObjectFactory for each Type, which allow us
        // to instantiate the objects very efficiently, compared to calling
        // Activator.CreateInstance on every call.
        private static FactoryGenerator s_factoryGenerator; 
        private static Hashtable s_factoryCache;
        private static bool s_initializedFactory; 
        private static object s_factoryLock = new Object(); 

#endif // DONTUSEFACTORYGENERATOR 

        /*
         * Faster implementation of CreatePublicInstance.  It generates bits of IL
         * on the fly to achieve the improve performance.  this should only be used 
         * in cases where the number of different types to be created is well bounded.
         * Otherwise, we would create too much IL, which can bloat the process. 
         */ 
        internal static Object FastCreatePublicInstance(Type type) {
 
#if DONTUSEFACTORYGENERATOR
            return CreatePublicInstance(type);
#else
 
            // Only use the factory logic if the assembly is in the GAC, to avoid getting
            // assembly conflicts (VSWhidbey 405086) 
            if (!type.Assembly.GlobalAssemblyCache) { 
                return CreatePublicInstance(type);
            } 

            // Create the factory generator on demand
            if (!s_initializedFactory) {
 
                // Devdiv 90810 - Synchronize to avoid race condition
                lock (s_factoryLock) { 
                    if (!s_initializedFactory) { 
                        s_factoryGenerator = new FactoryGenerator();
 
                        // Create the factory cache
                        s_factoryCache = Hashtable.Synchronized(new Hashtable());

                        s_initializedFactory = true; 
                    }
                } 
            } 

            // First, check if it's cached 
            IWebObjectFactory factory = (IWebObjectFactory)s_factoryCache[type];

            if (factory == null) {
 
                Debug.Trace("FastCreatePublicInstance", "Creating generator for type " + type.FullName);
 
                // Create the object factory 
                factory = s_factoryGenerator.CreateFactory(type);
 
                // Cache the factory
                s_factoryCache[type] = factory;
            }
 
            return factory.CreateInstance();
#endif // DONTUSEFACTORYGENERATOR 
        } 

        internal static Object CreatePublicInstance(Type type, Object[] args) { 
            if (args == null)
                return Activator.CreateInstance(type);

            return Activator.CreateInstance(type, args); 
        }
 
        static string GetCurrentUserName() { 
            try {
                return WindowsIdentity.GetCurrent().Name; 
            }
            catch {
                return null;
            } 
        }
 
        void RaiseShutdownWebEventOnce() { 
            if (!_shutdownWebEventRaised) {
                lock (this) { 
                    if (!_shutdownWebEventRaised) {
                        // Raise Web Event
                        WebBaseEvent.RaiseSystemEvent(this, WebEventCodes.ApplicationShutdown,
                                WebApplicationLifetimeEvent.DetailCodeFromShutdownReason(ShutdownReason)); 

                        _shutdownWebEventRaised = true; 
                    } 
                }
            } 
        }
    }

 
    public enum ApplicationShutdownReason {
 
        None = 0, 

        HostingEnvironment = 1, 

        ChangeInGlobalAsax = 2,

        ConfigurationChange = 3, 

        UnloadAppDomainCalled = 4, 
 
        ChangeInSecurityPolicyFile = 5,
 
        BinDirChangeOrDirectoryRename = 6,

        BrowsersDirChangeOrDirectoryRename = 7,
 
        CodeDirChangeOrDirectoryRename = 8,
 
        ResourcesDirChangeOrDirectoryRename = 9, 

        IdleTimeout = 10, 

        PhysicalApplicationPathChanged = 11,

        HttpRuntimeClose = 12, 

        InitializationError = 13, 
 
        MaxRecompilationsReached = 14,
 
        BuildManagerChange = 15,
    };

 
}

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

/* 
 * The ASP.NET runtime services 
 *
 * Copyright (c) 1998 Microsoft Corporation 
 */

namespace System.Web {
    using System.Text; 
    using System.Threading;
    using System.Data; 
    using System.Data.Common; 
    using System.IO;
    using System.Collections; 
    using System.Configuration;
    using System.Globalization;
    using System.Net;
    using System.Xml; 
    using System.Reflection;
    using System.Resources; 
    using System.Security; 
    using System.Security.Permissions;
    using System.Security.Policy; 
    using System.Web;
    using System.Web.UI;
#if ORCAS
    using System.Web.UI.Imaging; 
#endif
    using System.Web.Compilation; 
    using System.Web.Util; 
    using System.Web.Configuration;
    using System.Web.Caching; 
    using System.Web.Hosting;
    using System.Web.Security;
    using System.Web.Management;
    using System.Runtime.Remoting.Messaging; 
    using Microsoft.Win32;
    using System.Security.Cryptography; 
    using System.Security.Principal; 
    using System.Runtime.InteropServices;
 

    /// 
    ///    Provides a set of ASP.NET runtime services.
    ///  
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    public sealed class HttpRuntime { 
 
        private const string codegenDirName = "Temporary ASP.NET Files";
 
        private static HttpRuntime _theRuntime;   // single instance of the class
        internal static byte[] s_autogenKeys = new byte[88];

        // 
        // Names of special ASP.NET directories
        // 
 
        internal const string BinDirectoryName = "bin";
        internal const string CodeDirectoryName = "App_Code"; 
        internal const string WebRefDirectoryName = "App_WebReferences";
        internal const string ResourcesDirectoryName = "App_GlobalResources";
        internal const string LocalResourcesDirectoryName = "App_LocalResources";
        internal const string DataDirectoryName = "App_Data"; 
        internal const string ThemesDirectoryName = "App_Themes";
        internal const string GlobalThemesDirectoryName = "Themes"; 
        internal const string BrowsersDirectoryName = "App_Browsers"; 

        private static string DirectorySeparatorString = new string(Path.DirectorySeparatorChar, 1); 
        private static string DoubleDirectorySeparatorString = new string(Path.DirectorySeparatorChar, 2);


#if OLD 
        // For s_forbiddenDirs and s_forbiddenDirsConstant, see
        // ndll.h, and RestrictIISFolders in regiis.cxx 
 
        internal static string[]    s_forbiddenDirs =   {
                                        BinDirectoryName, 
                                        CodeDirectoryName,
                                        DataDirectoryName,
                                        ResourcesDirectoryName,
                                        WebRefDirectoryName, 
                                    };
 
        internal static Int32[]     s_forbiddenDirsConstant = { 
                                        UnsafeNativeMethods.RESTRICT_BIN,
                                        UnsafeNativeMethods.RESTRICT_CODE, 
                                        UnsafeNativeMethods.RESTRICT_DATA,
                                        UnsafeNativeMethods.RESTRICT_RESOURCES,
                                        UnsafeNativeMethods.RESTRICT_WEBREFERENCES,
                                    }; 
#endif
 
        static HttpRuntime() { 
            AddAppDomainTraceMessage("*HttpRuntime::cctor");
 
            StaticInit();

            _theRuntime = new HttpRuntime();
 
            _theRuntime.Init();
 
            AddAppDomainTraceMessage("HttpRuntime::cctor*"); 
        }
 
        [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
        public HttpRuntime() {
        }
 
        //
        // static initialization to get hooked up to the unmanaged code 
        // get installation directory, etc. 
        //
 
        private static bool s_initialized = false;
        private static String s_installDirectory;
        private static bool s_isEngineLoaded = false;
 
        // Force the static initialization of this class.
        internal static void ForceStaticInit() { } 
 
        private static void StaticInit() {
            if (s_initialized) { 
                // already initialized
                return;
            }
 
            bool isEngineLoaded = false;
            bool wasEngineLoadedHere = false; 
            String installDir = null; 

            // load webengine.dll if it is not loaded already 

#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features

            installDir = RuntimeEnvironment.GetRuntimeDirectory(); 

            if (UnsafeNativeMethods.GetModuleHandle(ModName.ENGINE_FULL_NAME) != IntPtr.Zero) { 
                isEngineLoaded = true; 
            }
 
            // Load webengine.dll if not loaded already

            if (!isEngineLoaded) {
                String fullPath = installDir + Path.DirectorySeparatorChar + ModName.ENGINE_FULL_NAME; 

                if (UnsafeNativeMethods.LoadLibrary(fullPath) != IntPtr.Zero) { 
                    isEngineLoaded = true; 
                    wasEngineLoadedHere = true;
                } 
            }

            if (isEngineLoaded) {
                UnsafeNativeMethods.InitializeLibrary(); 

                if (wasEngineLoadedHere) { 
                    UnsafeNativeMethods.PerfCounterInitialize(); 
                }
            } 

#else // !FEATURE_PAL
            string p = typeof(object).Module.FullyQualifiedName;
            installDir = Path.GetDirectoryName(p); 
#endif // !FEATURE_PAL
 
            s_installDirectory = installDir; 
            s_isEngineLoaded = isEngineLoaded;
            s_initialized = true; 

            AddAppDomainTraceMessage("Initialize");
        }
 
        //
        // Runtime services 
        // 

        private NamedPermissionSet _namedPermissionSet; 
        private FileChangesMonitor _fcm;
        private CacheInternal _cacheInternal;
        private Cache _cachePublic;
        private bool _isOnUNCShare; 
        private Profiler _profiler;
        private RequestTimeoutManager _timeoutManager; 
        private RequestQueue _requestQueue; 
        private bool _apartmentThreading;
 
#if ORCAS
        private IHttpDataStorageProvider _httpDataStorageProvider;
        private HttpDataStorageCleanup _httpDataStorageCleanup;
#endif 

#if SITECOUNTERS 
        private SiteCounters            _siteCounters; 
#endif
        private bool _processRequestInApplicationTrust; 
        //
        // Counters
        //
 
        private bool _beforeFirstRequest = true;
        private DateTime _firstRequestStartTime; 
        private bool _firstRequestCompleted; 
        private bool _userForcedShutdown;
        private bool _configInited; 
        private bool _fusionInited;
        private int _activeRequestCount;
        private DateTime _lastShutdownAttemptTime;
        private bool _shutdownInProgress; 
        private String _shutDownStack;
        private String _shutDownMessage; 
        private ApplicationShutdownReason _shutdownReason = ApplicationShutdownReason.None; 
        private string _trustLevel;
        private string _wpUserId; 
        private bool _shutdownWebEventRaised;

        //
        // Header Newlines 
        //
        private bool _enableHeaderChecking; 
 
        //
        // Callbacks 
        //

        private AsyncCallback _requestNotificationCompletionCallback;
        private AsyncCallback _handlerCompletionCallback; 
        private HttpWorkerRequest.EndOfSendNotification _asyncEndOfSendCallback;
        private WaitCallback _appDomainUnloadallback; 
 
        //
        // Initialization error (to be reported on subsequent requests) 
        //

        private Exception _initializationError;
        private bool _hostingInitFailed; // make such errors non-sticky 
        private Timer _appDomainShutdownTimer = null;
 
 
        //
        // App domain related 
        //

        private String _tempDir;
        private String _codegenDir; 
        private String _appDomainAppId;
        private String _appDomainAppPath; 
        private VirtualPath _appDomainAppVPath; 
        private String _appDomainId;
 
        //
        // Debugging support
        //
 
        private bool _debuggingEnabled = false;
 
        // 
        // App_Offline.htm support
        // 

        private const string AppOfflineFileName = "App_Offline.htm";
        private const long MaxAppOfflineFileLength = 1024 * 1024;
        private byte[] _appOfflineMessage; 

        // 
        // Client script support 
        //
 
        private const string AspNetClientFilesSubDirectory = "asp.netclientfiles";
        private const string AspNetClientFilesParentVirtualPath = "/aspnet_client/system_web/";
        private string _clientScriptVirtualPath;
        private string _clientScriptPhysicalPath; 

        // 
        //  Integrated pipeline mode 
        //
        private static bool _useIntegratedPipeline; 

        /////////////////////////////////////////////////////////////////////////
        // 3 steps of initialization:
        //     Init() is called from HttpRuntime cctor 
        //     HostingInit() is called by the Hosting Environment
        //     FirstRequestInit() is called on first HTTP request 
        // 

        /* 
         * Context-less initialization (on app domain creation)
         */
        private void Init() {
            try { 
#if !FEATURE_PAL
                if (Environment.OSVersion.Platform != PlatformID.Win32NT) 
                    throw new PlatformNotSupportedException(SR.GetString(SR.RequiresNT)); 
#else // !FEATURE_PAL
                // ROTORTODO 
                // Do nothing: FEATURE_PAL environment will always support ASP.NET hosting
#endif // !FEATURE_PAL

                _profiler = new Profiler(); 
                _timeoutManager = new RequestTimeoutManager();
                _wpUserId = GetCurrentUserName(); 
 
                _requestNotificationCompletionCallback = new AsyncCallback(this.OnRequestNotificationCompletion);
                _handlerCompletionCallback = new AsyncCallback(this.OnHandlerCompletion); 
                _asyncEndOfSendCallback = new HttpWorkerRequest.EndOfSendNotification(this.EndOfSendCallback);
                _appDomainUnloadallback = new WaitCallback(this.ReleaseResourcesAndUnloadAppDomain);

 
                // appdomain values
                if (GetAppDomainString(".appDomain") != null) { 
 
                    Debug.Assert(HostingEnvironment.IsHosted);
 
                    _appDomainAppId = GetAppDomainString(".appId");
                    _appDomainAppPath = GetAppDomainString(".appPath");
                    _appDomainAppVPath = VirtualPath.CreateNonRelativeTrailingSlash(GetAppDomainString(".appVPath"));
                    _appDomainId = GetAppDomainString(".domainId"); 

                    _isOnUNCShare = StringUtil.StringStartsWith(_appDomainAppPath, "\\\\"); 
 
                    // init perf counters for this appdomain
                    PerfCounters.Open(_appDomainAppId); 
                }
                else {
                    Debug.Assert(!HostingEnvironment.IsHosted);
                } 

                // _appDomainAppPath should be set before file change notifications are initialized 
                _fcm = new FileChangesMonitor(); 
            }
            catch (Exception e) { 
                // remember static initalization error
                InitializationException = e;
            }
        } 

        private void SetUpDataDirectory() { 
 
            // Set the DataDirectory (see VSWhidbey 226834) with permission (DevDiv 29614)
            string dataDirectory = Path.Combine(_appDomainAppPath, DataDirectoryName); 
            AppDomain.CurrentDomain.SetData("DataDirectory", dataDirectory,
                    new FileIOPermission(FileIOPermissionAccess.PathDiscovery, dataDirectory));
        }
 
        private void DisposeAppDomainShutdownTimer() {
            Timer timer = _appDomainShutdownTimer; 
            if (timer != null && Interlocked.CompareExchange(ref _appDomainShutdownTimer, null, timer) == timer) { 
                timer.Dispose();
            } 
        }

        private void AppDomainShutdownTimerCallback(Object state) {
            try { 
                DisposeAppDomainShutdownTimer();
                ShutdownAppDomain(ApplicationShutdownReason.InitializationError, "Initialization Error"); 
            } 
            catch { } // ignore exceptions
        } 

        /*
         * Restart the AppDomain in 10 seconds
         */ 
        private void StartAppDomainShutdownTimer() {
            if (_appDomainShutdownTimer == null && !_shutdownInProgress) { 
                lock (this) { 
                    if (_appDomainShutdownTimer == null && !_shutdownInProgress) {
                        _appDomainShutdownTimer = new Timer( 
                            new TimerCallback(this.AppDomainShutdownTimerCallback),
                            null,
                            10 * 1000,
                            0); 
                    }
                } 
            } 
        }
 

        /*
         * Initialization from HostingEnvironment of HTTP independent features
         */ 
        private void HostingInit(HostingEnvironmentFlags hostingFlags) {
            using (new ApplicationImpersonationContext()) { 
                try { 
                    // To ignore FCN during initialization
                    _firstRequestStartTime = DateTime.UtcNow; 

                    SetUpDataDirectory();

                    // Throw an exception about lack of access to app directory early on 
                    EnsureAccessToApplicationDirectory();
 
                    // Monitor renames to directories we are watching, and notifications on the bin directory 
                    //
                    // Note that this must be the first monitoring that we do of the application directory. 
                    // There is a bug in Windows 2000 Server where notifications on UNC shares do not
                    // happen correctly if:
                    //      1. the directory is monitored for regular notifications
                    //      2. the directory is then monitored for directory renames 
                    //      3. the directory is monitored again for regular notifications
                    StartMonitoringDirectoryRenamesAndBinDirectory(); 
 
                    //
                    // Get the configuration needed to minimally initialize 
                    // the components required for a complete configuration system,
                    // especially SetTrustLevel.
                    //
                    // We want to do this before calling SetUpCodegenDirectory(), 
                    // to remove the risk of the config system loading
                    // codegen assemblies in full trust (VSWhidbey 460506) 
                    // 
                    CacheSection cacheSection;
                    TrustSection trustSection; 
                    SecurityPolicySection securityPolicySection;
                    CompilationSection compilationSection;
                    HostingEnvironmentSection hostingEnvironmentSection;
                    Exception configInitException; 

                    GetInitConfigSections( 
                            out cacheSection, 
                            out trustSection,
                            out securityPolicySection, 
                            out compilationSection,
                            out hostingEnvironmentSection,
                            out configInitException);
 
                    // Once the configuration system is initialized, we can read
                    // the cache configuration settings. 
                    // 
                    // Note that we must do this after we start monitoring directory renames,
                    // as reading config will cause file monitoring on the application directory 
                    // to occur.
                    HttpRuntime.CacheInternal.ReadCacheInternalConfig(cacheSection);

                    // Set up the codegen directory for the app.  This needs to be done before we process 
                    // the policy file, because it needs to replace the $CodeGen$ token.
                    SetUpCodegenDirectory(compilationSection); 
 
                    // NOTE: after calling SetUpCodegenDirectory(), and until we call SetTrustLevel(), we are at
                    // risk of codegen assemblies being loaded in full trust.  No code that might cause 
                    // assembly loading should be added here!

                    try {
                        // Set code access policy on the app domain 
                        SetTrustLevel(trustSection, securityPolicySection);
 
                    } 
                    catch {
                        // throw the original config exception if it exists 
                        if (configInitException != null) {
                            throw configInitException;
                        }
                        throw; 
                    }
 
                    // Configure fusion to use directories set in the app config 
                    InitFusion(hostingEnvironmentSection);
 
                    // Complete initialization of configuration.
                    // Note that this needs to be called after SetTrustLevel,
                    // as it indicates that we have the permission set needed
                    // to correctly run configuration section handlers. 
                    // As little config should be read before CompleteInit() as possible.
                    // No section that runs before CompleteInit() should demand permissions, 
                    // as the permissions set has not yet determined until SetTrustLevel() 
                    // is called.
                    HttpConfigurationSystem.CompleteInit(); 

                    //
                    // If an exception occurred loading configuration,
                    // we are now ready to handle exception processing 
                    // with the correct trust level set.
                    // 
                    if (configInitException != null) { 
                        throw configInitException;
                    } 

                    SetThreadPoolLimits();

                    SetAutogenKeys(); 

                    // Initialize the build manager 
                    BuildManager.InitializeBuildManager(); 

                    // Determine apartment threading setting 
                    InitApartmentThreading();

                    // Init debugging
                    InitDebuggingSupport(); 
#if SITECOUNTERS
                    if (!BuildManagerHost.InClientBuildManager) { 
                        // create siteCounters object according to config 
                        InitSiteCounters();
                    } 
#endif
                    _processRequestInApplicationTrust = trustSection.ProcessRequestInApplicationTrust;
                }
                catch (Exception e) { 
                    _hostingInitFailed = true;
                    InitializationException = e; 
 
                    Debug.Trace("AppDomainFactory", "HostingInit failed. " + e.ToString());
 
                    if ((hostingFlags & HostingEnvironmentFlags.ThrowHostingInitErrors) != 0)
                        throw;
                }
            } 
        }
 
        internal static Exception InitializationException { 
            get {
                return _theRuntime._initializationError; 
            }

            // The exception is "cached" for 10 seconds, then the AppDomain is restarted.
            set { 
                _theRuntime._initializationError = value;
                // In v2.0, we shutdown immediately if hostingInitFailed...so we don't need the timer 
                if (!HostingInitFailed) { 
                    _theRuntime.StartAppDomainShutdownTimer();
                } 
            }
        }

        internal static bool HostingInitFailed { 
            get {
                return _theRuntime._hostingInitFailed; 
            } 
        }
 
        internal static void InitializeHostingFeatures(HostingEnvironmentFlags hostingFlags) {
            _theRuntime.HostingInit(hostingFlags);
        }
 
        internal static bool EnableHeaderChecking {
            get { 
                return _theRuntime._enableHeaderChecking; 
            }
        } 

        internal static bool ProcessRequestInApplicationTrust {
            get {
                return _theRuntime._processRequestInApplicationTrust; 
            }
        } 
 
        internal static byte[] AppOfflineMessage {
            get { 
                return _theRuntime._appOfflineMessage;
            }
        }
 
        /*
         * Initialization on first request (context available) 
         */ 
        private void FirstRequestInit(HttpContext context) {
            Exception error = null; 

            if (InitializationException == null && _appDomainId != null) {
#if DBG
                HttpContext.SetDebugAssertOnAccessToCurrent(true); 
#endif
                try { 
                    using (new ApplicationImpersonationContext()) { 
                        // Is this necessary?  See InitHttpConfiguration
                        CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture; 
                        CultureInfo savedUICulture = Thread.CurrentThread.CurrentUICulture;

                        try {
                            // Ensure config system is initialized 
                            InitHttpConfiguration(); // be sure config system is set
 
                            // Check if applicaton is enabled 
                            CheckApplicationEnabled();
 
                            // Check access to temp compilation directory (under hosting identity)
                            CheckAccessToTempDirectory();

                            // Initialize health monitoring 
                            InitializeHealthMonitoring();
 
                            // Init request queue (after reading config) 
                            InitRequestQueue();
 
                            // configure the profiler according to config
                            InitTrace(context);

#if ORCAS 
                            // Initialize the HttpDataStore and cleanup process
                            InitHttpDataStore(); 
#endif 

                            // Start heatbeat for Web Event Health Monitoring 
                            HealthMonitoringManager.StartHealthMonitoringHeartbeat();

                            // Remove read and browse access of the bin directory
                            RestrictIISFolders(context); 

                            // Preload all assemblies from bin (only if required).  ASURT 114486 
                            PreloadAssembliesFromBin(); 

                            // Decide whether or not to encode headers.  VsWhidbey 257154 
                            InitHeaderEncoding();

                            if (context.WorkerRequest is ISAPIWorkerRequestOutOfProc) {
                                // Make sure that the  section has no errors 
                                ProcessModelSection processModel = RuntimeConfig.GetMachineConfig().ProcessModel;
                            } 
                        } 
                        finally {
                            Thread.CurrentThread.CurrentUICulture = savedUICulture; 
                            Thread.CurrentThread.CurrentCulture = savedCulture;
                        }
                    }
                } 
                catch (ConfigurationException e) {
                    error = e; 
                } 
                catch (Exception e) {
                    // remember second-phase initialization error 
                    error = new HttpException(SR.GetString(SR.XSP_init_error, e.Message), e);
                }
                finally {
#if DBG 
                    HttpContext.SetDebugAssertOnAccessToCurrent(false);
#endif 
                } 
            }
 
            if (InitializationException != null) {
                // throw cached exception.  We need to wrap it in a new exception, otherwise
                // we lose the original stack.
                throw new HttpException(InitializationException.Message, InitializationException); 
            }
            else if (error != null) { 
                InitializationException = error; 
                // throw new exception
                throw error; 
            }

            AddAppDomainTraceMessage("FirstRequestInit");
        } 

        private void EnsureFirstRequestInit(HttpContext context) { 
            if (_beforeFirstRequest) { 
                lock (this) {
                    if (_beforeFirstRequest) { 
                        _firstRequestStartTime = DateTime.UtcNow;
                        FirstRequestInit(context);
                        _beforeFirstRequest = false;
                    } 
                }
            } 
        } 

        private void EnsureAccessToApplicationDirectory() { 
            if (!FileUtil.DirectoryAccessible(_appDomainAppPath)) {
                //
                if (_appDomainAppPath.IndexOf('?') >= 0) {
                    // Possible Unicode when not supported 
                    throw new HttpException(SR.GetString(SR.Access_denied_to_unicode_app_dir, _appDomainAppPath));
                } 
                else { 
                    throw new HttpException(SR.GetString(SR.Access_denied_to_app_dir, _appDomainAppPath));
                } 
            }
        }

        private void StartMonitoringDirectoryRenamesAndBinDirectory() { 
            _fcm.StartMonitoringDirectoryRenamesAndBinDirectory(AppDomainAppPathInternal, new FileChangeEventHandler(this.OnCriticalDirectoryChange));
        } 
 
        //
        // Monitor a local resources subdirectory and unload appdomain when it changes 
        //
        internal static void StartListeningToLocalResourcesDirectory(VirtualPath virtualDir) {
#if !FEATURE_PAL // FEATURE_PAL does not enable file change notification
            _theRuntime._fcm.StartListeningToLocalResourcesDirectory(virtualDir); 
#endif // !FEATURE_PAL
        } 
 
        //
        // Get the configuration needed to minimally initialize 
        // the components required for a complete configuration system,
        //
        // Note that if the application configuration file has an error,
        // AppLKGConfig will still retreive any valid configuration from 
        // that file, or from location directives that apply to the
        // application path. This implies that an administrator can 
        // lock down an application's trust level in root web.config, 
        // and it will still take effect if the application's web.config
        // has errors. 
        //
        private void GetInitConfigSections(
                out CacheSection cacheSection,
                out TrustSection trustSection, 
                out SecurityPolicySection securityPolicySection,
                out CompilationSection compilationSection, 
                out HostingEnvironmentSection hostingEnvironmentSection, 
                out Exception initException) {
 
            cacheSection = null;
            trustSection = null;
            securityPolicySection = null;
            compilationSection = null; 
            hostingEnvironmentSection = null;
            initException = null; 
 
            // AppLKGConfig is guaranteed to not throw an exception.
            RuntimeConfig appLKGConfig = RuntimeConfig.GetAppLKGConfig(); 

            // AppConfig may throw an exception.
            RuntimeConfig appConfig = null;
            try { 
                appConfig = RuntimeConfig.GetAppConfig();
            } 
            catch (Exception e) { 
                initException = e;
            } 

            // Cache section
            if (appConfig != null) {
                try { 
                    cacheSection = appConfig.Cache;
                } 
                catch (Exception e) { 
                    if (initException == null) {
                        initException = e; 
                    }
                }
            }
 
            if (cacheSection == null) {
                cacheSection = appLKGConfig.Cache; 
            } 

            // Trust section 
            if (appConfig != null) {
                try {
                    trustSection = appConfig.Trust;
                } 
                catch (Exception e) {
                    if (initException == null) { 
                        initException = e; 
                    }
                } 
            }

            if (trustSection == null) {
                trustSection = appLKGConfig.Trust; 
            }
 
            // SecurityPolicy section 
            if (appConfig != null) {
                try { 
                    securityPolicySection = appConfig.SecurityPolicy;
                }
                catch (Exception e) {
                    if (initException == null) { 
                        initException = e;
                    } 
                } 
            }
 
            if (securityPolicySection == null) {
                securityPolicySection = appLKGConfig.SecurityPolicy;
            }
 
            // Compilation section
            if (appConfig != null) { 
                try { 
                    compilationSection = appConfig.Compilation;
                } 
                catch (Exception e) {
                    if (initException == null) {
                        initException = e;
                    } 
                }
            } 
 
            if (compilationSection == null) {
                compilationSection = appLKGConfig.Compilation; 
            }

            // HostingEnvironment section
            if (appConfig != null) { 
                try {
                    hostingEnvironmentSection = appConfig.HostingEnvironment; 
                } 
                catch (Exception e) {
                    if (initException == null) { 
                        initException = e;
                    }
                }
            } 

            if (hostingEnvironmentSection == null) { 
                hostingEnvironmentSection = appLKGConfig.HostingEnvironment; 
            }
        } 

        // Set up the codegen directory for the app
        private void SetUpCodegenDirectory(CompilationSection compilationSection) {
            AppDomain appDomain = Thread.GetDomain(); 

            string codegenBase; 
 
            string simpleAppName = System.Web.Hosting.AppManagerAppDomainFactory.ConstructSimpleAppName(
                AppDomainAppVirtualPath); 

            string tempDirectory = null;

            // These variables are used for error handling 
            string tempDirAttribName = null;
            string configFileName = null; 
            int configLineNumber = 0; 

            if (compilationSection != null && !String.IsNullOrEmpty(compilationSection.TempDirectory)) { 
                tempDirectory = compilationSection.TempDirectory;

                compilationSection.GetTempDirectoryErrorInfo(out tempDirAttribName,
                    out configFileName, out configLineNumber); 
            }
 
            if (tempDirectory != null) { 
                tempDirectory = tempDirectory.Trim();
 
                if (!Path.IsPathRooted(tempDirectory)) {
                    // Make sure the path is not relative (VSWhidbey 260075)
                    tempDirectory = null;
                } 
                else {
                    try { 
                        // Canonicalize it to avoid problems with spaces (VSWhidbey 229873) 
                        tempDirectory = new DirectoryInfo(tempDirectory).FullName;
                    } 
                    catch {
                        tempDirectory = null;
                    }
                } 

                if (tempDirectory == null) { 
                    throw new ConfigurationErrorsException( 
                        SR.GetString(SR.Invalid_temp_directory, tempDirAttribName),
                        configFileName, configLineNumber); 
                }
#if FEATURE_PAL
            } else {
                System.UInt32 length = 0; 
                StringBuilder sb = null;
                bool bRet; 
 
                // Get the required length
                bRet = UnsafeNativeMethods.GetUserTempDirectory( 
                                    UnsafeNativeMethods.DeploymentDirectoryType.ddtInstallationDependentDirectory,
                                    null, ref length);

                if (true == bRet) { 
                    // now, allocate the string
                    sb = new StringBuilder ((int)length); 
 
                    // call again to get the value
                    bRet = UnsafeNativeMethods.GetUserTempDirectory( 
                                    UnsafeNativeMethods.DeploymentDirectoryType.ddtInstallationDependentDirectory,
                                    sb, ref length);
                }
 
                if (false == bRet) {
                    throw new ConfigurationException( 
                        HttpRuntime.FormatResourceString(SR.Invalid_temp_directory, tempDirAttribName)); 
                }
 
                tempDirectory = Path.Combine(sb.ToString(), codegenDirName);
            }

            // Always try to create the ASP.Net temp directory for FEATURE_PAL 
#endif // FEATURE_PAL
 
                // Create the config-specified directory if needed 
                try {
                    Directory.CreateDirectory(tempDirectory); 
                }
                catch (Exception e) {
                    throw new ConfigurationErrorsException(
                        SR.GetString(SR.Invalid_temp_directory, tempDirAttribName), 
                        e,
                        configFileName, configLineNumber); 
                } 
#if !FEATURE_PAL
            } 
            else {
                tempDirectory = Path.Combine(s_installDirectory, codegenDirName);
            }
#endif // !FEATURE_PAL 

            // If we don't have write access to the codegen dir, use the TEMP dir instead. 
            // This will allow non-admin users to work in hosting scenarios (e.g. Venus, aspnet_compiler) 
            if (!System.Web.UI.Util.HasWriteAccessToDirectory(tempDirectory)) {
 
                // Don't do this if we're in a service (!UserInteractive), as TEMP
                // could point to unwanted places.

#if !FEATURE_PAL // always fail here 
                if (!Environment.UserInteractive)
#endif // !FEATURE_PAL 
 { 
                    throw new HttpException(SR.GetString(SR.No_codegen_access,
                        System.Web.UI.Util.GetCurrentAccountName(), tempDirectory)); 
                }

                tempDirectory = Path.GetTempPath();
                Debug.Assert(System.Web.UI.Util.HasWriteAccessToDirectory(tempDirectory)); 
                tempDirectory = Path.Combine(tempDirectory, codegenDirName);
            } 
 
            _tempDir = tempDirectory;
 
            codegenBase = Path.Combine(tempDirectory, simpleAppName);

#pragma warning disable 0618    // To avoid deprecation warning
            appDomain.SetDynamicBase(codegenBase); 
#pragma warning restore 0618
 
            _codegenDir = Thread.GetDomain().DynamicDirectory; 

            // Create the codegen directory if needed 
            Directory.CreateDirectory(_codegenDir);
        }

        private void InitFusion(HostingEnvironmentSection hostingEnvironmentSection) { 

            AppDomain appDomain = Thread.GetDomain(); 
 
            // If there is a double backslash in the string, get rid of it (ASURT 122191)
            // Make sure to skip the first char, to avoid breaking the UNC case 
            string appDomainAppPath = _appDomainAppPath;
            if (appDomainAppPath.IndexOf(DoubleDirectorySeparatorString, 1, StringComparison.Ordinal) >= 1) {
                appDomainAppPath = appDomainAppPath[0] + appDomainAppPath.Substring(1).Replace(DoubleDirectorySeparatorString,
                    DirectorySeparatorString); 
            }
 
#pragma warning disable 0618    // To avoid deprecation warning 
            // Allow assemblies from 'bin' to be loaded
            appDomain.AppendPrivatePath(appDomainAppPath + BinDirectoryName); 
#pragma warning restore 0618

            // If shadow copying was disabled via config, turn it off (DevDiv 30864)
            if (hostingEnvironmentSection != null && !hostingEnvironmentSection.ShadowCopyBinAssemblies) { 
#pragma warning disable 0618    // To avoid deprecation warning
                appDomain.ClearShadowCopyPath(); 
#pragma warning restore 0618 
            }
            else { 
                // enable shadow-copying from bin
#pragma warning disable 0618    // To avoid deprecation warning
                appDomain.SetShadowCopyPath(appDomainAppPath + BinDirectoryName);
#pragma warning restore 0618 
            }
 
            // Get rid of the last part of the directory (the app name), since it will 
            // be re-appended.
            string parentDir = Directory.GetParent(_codegenDir).FullName; 
#pragma warning disable 0618    // To avoid deprecation warning
            appDomain.SetCachePath(parentDir);
#pragma warning restore 0618
 
            _fusionInited = true;
        } 
 
        private void InitRequestQueue() {
            RuntimeConfig config = RuntimeConfig.GetAppConfig(); 
            HttpRuntimeSection runtimeConfig = config.HttpRuntime;
            ProcessModelSection processConfig = config.ProcessModel;

            if (processConfig.AutoConfig) { 
                _requestQueue = new RequestQueue(
                    88 * processConfig.CpuCount, 
                    76 * processConfig.CpuCount, 
                    runtimeConfig.AppRequestQueueLimit,
                    processConfig.ClientConnectedCheck); 
            }
            else {

                // Configuration section handlers cannot validate values based on values 
                // in other configuration sections, so we validate minFreeThreads and
                // minLocalRequestFreeThreads here. 
                int maxThreads = (processConfig.MaxWorkerThreadsTimesCpuCount < processConfig.MaxIoThreadsTimesCpuCount) ? processConfig.MaxWorkerThreadsTimesCpuCount : processConfig.MaxIoThreadsTimesCpuCount; 
                // validate minFreeThreads
                if (runtimeConfig.MinFreeThreads >= maxThreads) { 
                    if (runtimeConfig.ElementInformation.Properties["minFreeThreads"].LineNumber == 0) {
                        if (processConfig.ElementInformation.Properties["maxWorkerThreads"].LineNumber != 0) {
                            throw new ConfigurationErrorsException(SR.GetString(SR.Thread_pool_limit_must_be_greater_than_minFreeThreads, runtimeConfig.MinFreeThreads.ToString(CultureInfo.InvariantCulture)),
                                                                   processConfig.ElementInformation.Properties["maxWorkerThreads"].Source, 
                                                                   processConfig.ElementInformation.Properties["maxWorkerThreads"].LineNumber);
                        } 
                        else { 
                            throw new ConfigurationErrorsException(SR.GetString(SR.Thread_pool_limit_must_be_greater_than_minFreeThreads, runtimeConfig.MinFreeThreads.ToString(CultureInfo.InvariantCulture)),
                                                                   processConfig.ElementInformation.Properties["maxIoThreads"].Source, 
                                                                   processConfig.ElementInformation.Properties["maxIoThreads"].LineNumber);
                        }
                    }
                    else { 
                        throw new ConfigurationErrorsException(SR.GetString(SR.Min_free_threads_must_be_under_thread_pool_limits, maxThreads.ToString(CultureInfo.InvariantCulture)),
                                                               runtimeConfig.ElementInformation.Properties["minFreeThreads"].Source, 
                                                               runtimeConfig.ElementInformation.Properties["minFreeThreads"].LineNumber); 
                    }
                } 
                // validate minLocalRequestFreeThreads
                if (runtimeConfig.MinLocalRequestFreeThreads > runtimeConfig.MinFreeThreads) {
                    if (runtimeConfig.ElementInformation.Properties["minLocalRequestFreeThreads"].LineNumber == 0) {
                        throw new ConfigurationErrorsException(SR.GetString(SR.Local_free_threads_cannot_exceed_free_threads), 
                                                               processConfig.ElementInformation.Properties["minFreeThreads"].Source,
                                                               processConfig.ElementInformation.Properties["minFreeThreads"].LineNumber); 
                    } 
                    else {
                        throw new ConfigurationErrorsException(SR.GetString(SR.Local_free_threads_cannot_exceed_free_threads), 
                                                               runtimeConfig.ElementInformation.Properties["minLocalRequestFreeThreads"].Source,
                                                               runtimeConfig.ElementInformation.Properties["minLocalRequestFreeThreads"].LineNumber);
                    }
                } 

                _requestQueue = new RequestQueue( 
                    runtimeConfig.MinFreeThreads, 
                    runtimeConfig.MinLocalRequestFreeThreads,
                    runtimeConfig.AppRequestQueueLimit, 
                    processConfig.ClientConnectedCheck);
            }
        }
 
#if ORCAS
        private void InitHttpDataStore() { 
            ImageGenerationSection igConfig = RuntimeConfig.GetAppConfig().ImageGeneration; 
            IDictionary settings = new Hashtable();
            int imageStorageExpiration = 300; 
            StorageType storageType = igConfig.StorageType;

            if (storageType == StorageType.Disk) {
                _httpDataStorageProvider = new DiskHttpDataStorageProvider(); 
                settings["storagePath"] = igConfig.StoragePath;
            } 
 
            int imageExp = (int) igConfig.StorageExpiration.TotalSeconds;
            if (imageExp > 0) { 
                imageStorageExpiration = imageExp;
            }

            if (_httpDataStorageProvider == null) { 
                _httpDataStorageProvider = new CacheHttpDataStorageProvider();
            } 
 
            try {
                _httpDataStorageProvider.Initialize(imageStorageExpiration, settings); 
            }
            catch (Exception e) {
                throw new ConfigurationErrorsException(e.Message, e, igConfig.SourceFileName, igConfig.SourceLineNumber);
            } 

            _httpDataStorageCleanup = new HttpDataStorageCleanup(imageStorageExpiration * 1000, _httpDataStorageProvider); 
        } 
#endif
 
        private void InitApartmentThreading() {
            HttpRuntimeSection runtimeConfig = RuntimeConfig.GetAppConfig().HttpRuntime;

            if (runtimeConfig != null) { 
                _apartmentThreading = runtimeConfig.ApartmentThreading;
            } 
            else { 
                _apartmentThreading = false;
            } 
        }

        private void InitTrace(HttpContext context) {
            TraceSection traceConfig = RuntimeConfig.GetAppConfig().Trace; 

            Profile.RequestsToProfile = traceConfig.RequestLimit; 
            Profile.PageOutput = traceConfig.PageOutput; 
            Profile.OutputMode = TraceMode.SortByTime;
            if (traceConfig.TraceMode == TraceDisplayMode.SortByCategory) 
                Profile.OutputMode = TraceMode.SortByCategory;

            Profile.LocalOnly = traceConfig.LocalOnly;
            Profile.IsEnabled = traceConfig.Enabled; 
            Profile.MostRecent = traceConfig.MostRecent;
            Profile.Reset(); 
 
            // the first request's context is created before InitTrace, so
            // we need to set this manually. (ASURT 93730) 
            context.TraceIsEnabled = traceConfig.Enabled;
            TraceContext.SetWriteToDiagnosticsTrace(traceConfig.WriteToDiagnosticsTrace);
        }
 
        private void InitDebuggingSupport() {
            CompilationSection compConfig = RuntimeConfig.GetAppConfig().Compilation; 
            _debuggingEnabled = compConfig.Debug; 
        }
 
#if SITECOUNTERS
        internal void InitSiteCounters() {
            SiteCountersSection siteCountersConfig = RuntimeConfig.GetAppConfig().SiteCounters;
            Type type; 
#if FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features
 		siteCountersConfig.Enabled = false; 
#endif // FEATURE_PAL 
            if (siteCountersConfig.Enabled) {
                type = siteCountersConfig.TypeInternal; 
            }
            else {
                type = BuildManager.GetType("System.Web.SiteCounters", true, false);
            } 

            _siteCounters = (SiteCounters) CreateNonPublicInstance(type); 
            _siteCounters.Initialize(); 
        }
#endif 
        /*
         * Pre-load all the bin assemblies if we're impersonated.  This way, if user code
         * calls Assembly.Load while impersonated, the assembly will already be loaded, and
         * we won't fail due to lack of permissions on the codegen dir (see ASURT 114486) 
         */
        private void PreloadAssembliesFromBin() { 
            bool appClientImpersonationEnabled = false; 

            if (!_isOnUNCShare) { 
                // if not on UNC share check if config has impersonation enabled (without userName)
                IdentitySection c = RuntimeConfig.GetAppConfig().Identity;
                if (c.Impersonate && c.ImpersonateToken == IntPtr.Zero)
                    appClientImpersonationEnabled = true; 
            }
 
            if (!appClientImpersonationEnabled) 
                return;
 
            // Get the path to the bin directory
            string binPath = HttpRuntime.BinDirectoryInternal;

            DirectoryInfo binPathDirectory = new DirectoryInfo(binPath); 

            if (!binPathDirectory.Exists) 
                return; 

            PreloadAssembliesFromBinRecursive(binPathDirectory); 
        }

        private void PreloadAssembliesFromBinRecursive(DirectoryInfo dirInfo) {
 
            FileInfo[] binDlls = dirInfo.GetFiles("*.dll");
 
            // Pre-load all the assemblies, ignoring all exceptions 
            foreach (FileInfo fi in binDlls) {
                try { Assembly.Load(System.Web.UI.Util.GetAssemblyNameFromFileName(fi.Name)); } 
                catch (FileNotFoundException) {
                    // If Load failed, try LoadFrom (VSWhidbey 493725)
                    try { Assembly.LoadFrom(fi.FullName); }
                    catch { } 
                }
                catch { } 
            } 

            // Recurse on the subdirectories 
            DirectoryInfo[] subDirs = dirInfo.GetDirectories();
            foreach (DirectoryInfo di in subDirs) {
                PreloadAssembliesFromBinRecursive(di);
            } 
        }
 
        private void SetAutoConfigLimits(ProcessModelSection pmConfig) { 
            // check if the current limits are ok
            int workerMax, ioMax; 
            ThreadPool.GetMaxThreads(out workerMax, out ioMax);

            // only set if different
            if (pmConfig.DefaultMaxWorkerThreadsForAutoConfig != workerMax || pmConfig.DefaultMaxIoThreadsForAutoConfig != ioMax) { 
                Debug.Trace("ThreadPool", "SetThreadLimit: from " + workerMax + "," + ioMax + " to " + pmConfig.DefaultMaxWorkerThreadsForAutoConfig + "," + pmConfig.DefaultMaxIoThreadsForAutoConfig);
                UnsafeNativeMethods.SetClrThreadPoolLimits(pmConfig.DefaultMaxWorkerThreadsForAutoConfig, pmConfig.DefaultMaxIoThreadsForAutoConfig); 
            } 

            // this is the code equivalent of setting maxconnection 
            System.Net.ServicePointManager.DefaultConnectionLimit = 12 * pmConfig.CpuCount;

            // we call InitRequestQueue later, from FirstRequestInit, and set minFreeThreads and minLocalRequestFreeThreads
        } 

        private void SetThreadPoolLimits() { 
            try { 
                ProcessModelSection pmConfig = RuntimeConfig.GetMachineConfig().ProcessModel;
 
                if (pmConfig.AutoConfig) {
                    // use recommendation in http://support.microsoft.com/?id=821268
                    SetAutoConfigLimits(pmConfig);
                } 
                else if (pmConfig.MaxWorkerThreadsTimesCpuCount > 0 && pmConfig.MaxIoThreadsTimesCpuCount > 0) {
                    // check if the current limits are ok 
                    int workerMax, ioMax; 
                    ThreadPool.GetMaxThreads(out workerMax, out ioMax);
 
                    // only set if different
                    if (pmConfig.MaxWorkerThreadsTimesCpuCount != workerMax || pmConfig.MaxIoThreadsTimesCpuCount != ioMax) {
                        Debug.Trace("ThreadPool", "SetThreadLimit: from " + workerMax + "," + ioMax + " to " + pmConfig.MaxWorkerThreadsTimesCpuCount + "," + pmConfig.MaxIoThreadsTimesCpuCount);
                        UnsafeNativeMethods.SetClrThreadPoolLimits(pmConfig.MaxWorkerThreadsTimesCpuCount, pmConfig.MaxIoThreadsTimesCpuCount); 
                    }
                } 
 
                if (pmConfig.MinWorkerThreadsTimesCpuCount > 0 || pmConfig.MinIoThreadsTimesCpuCount > 0) {
                    int currentMinWorkerThreads, currentMinIoThreads; 
                    ThreadPool.GetMinThreads(out currentMinWorkerThreads, out currentMinIoThreads);

                    int newMinWorkerThreads = pmConfig.MinWorkerThreadsTimesCpuCount > 0 ? pmConfig.MinWorkerThreadsTimesCpuCount : currentMinWorkerThreads;
                    int newMinIoThreads = pmConfig.MinIoThreadsTimesCpuCount > 0 ? pmConfig.MinIoThreadsTimesCpuCount : currentMinIoThreads; 

                    if (newMinWorkerThreads > 0 && newMinIoThreads > 0 
                        && (newMinWorkerThreads != currentMinWorkerThreads || newMinIoThreads != currentMinIoThreads)) 
                        ThreadPool.SetMinThreads(newMinWorkerThreads, newMinIoThreads);
                } 
            }
            catch {
            }
        } 

        internal static void CheckApplicationEnabled() { 
            // process App_Offline.htm file 
            string appOfflineFile = Path.Combine(_theRuntime._appDomainAppPath, AppOfflineFileName);
            bool appOfflineFileFound = false; 

            // monitor even if doesn't exist
            _theRuntime._fcm.StartMonitoringFile(appOfflineFile, new FileChangeEventHandler(_theRuntime.OnAppOfflineFileChange));
 
            // read the file into memory
            try { 
                if (File.Exists(appOfflineFile)) { 
                    Debug.Trace("AppOffline", "File " + appOfflineFile + " exists. Using it.");
 
                    using (FileStream fs = new FileStream(appOfflineFile, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                        if (fs.Length <= MaxAppOfflineFileLength) {
                            int length = (int)fs.Length;
 
                            if (length > 0) {
                                byte[] message = new byte[length]; 
 
                                if (fs.Read(message, 0, length) == length) {
                                    // remember the message 
                                    _theRuntime._appOfflineMessage = message;
                                    appOfflineFileFound = true;
                                }
                            } 
                            else {
                                // empty file 
                                appOfflineFileFound = true; 
                            }
                        } 
                    }
                }
            }
            catch { 
                // ignore any IO errors reading the file
            } 
 
            // throw if there is a valid App_Offline file
            if (appOfflineFileFound) { 
                throw new HttpException(404, String.Empty);
            }

            // process the config setting 
            HttpRuntimeSection runtimeConfig = RuntimeConfig.GetAppConfig().HttpRuntime;
            if (!runtimeConfig.Enable) { 
                // throw 404 on first request init -- this will get cached until config changes 
                throw new HttpException(404, String.Empty);
            } 
        }

        private void CheckAccessToTempDirectory() {
            // The original check (in HostingInit) was done under process identity 
            // this time we do it under hosting identity
            if (HostingEnvironment.HasHostingIdentity) { 
                using (new ApplicationImpersonationContext()) { 
                    if (!System.Web.UI.Util.HasWriteAccessToDirectory(_tempDir)) {
                        throw new HttpException(SR.GetString(SR.No_codegen_access, 
                            System.Web.UI.Util.GetCurrentAccountName(), _tempDir));
                    }
                }
            } 
        }
 
        private void InitializeHealthMonitoring() { 
#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features
            ProcessModelSection pmConfig = RuntimeConfig.GetMachineConfig().ProcessModel; 
            int deadLockInterval = (int)pmConfig.ResponseDeadlockInterval.TotalSeconds;
            int requestQueueLimit = pmConfig.RequestQueueLimit;
            Debug.Trace("HealthMonitor", "Initalizing: ResponseDeadlockInterval=" + deadLockInterval);
            UnsafeNativeMethods.InitializeHealthMonitor(deadLockInterval, requestQueueLimit); 
#endif // !FEATURE_PAL
        } 
 
        private static void InitHttpConfiguration() {
            if (!_theRuntime._configInited) { 
                _theRuntime._configInited = true;

                HttpConfigurationSystem.EnsureInit(null, true, true);
 
                // whenever possible report errors in the user's culture (from machine.config)
                // Note: this thread's culture is saved/restored during FirstRequestInit, so this is safe 
                // see ASURT 81655 

                GlobalizationSection globConfig = RuntimeConfig.GetAppLKGConfig().Globalization; 
                if (globConfig != null) {
                    if (!String.IsNullOrEmpty(globConfig.Culture) &&
                        !StringUtil.StringStartsWithIgnoreCase(globConfig.Culture, "auto"))
                        Thread.CurrentThread.CurrentCulture = HttpServerUtility.CreateReadOnlyCultureInfo(globConfig.Culture); 

                    if (!String.IsNullOrEmpty(globConfig.UICulture) && 
                        !StringUtil.StringStartsWithIgnoreCase(globConfig.UICulture, "auto")) 
                        Thread.CurrentThread.CurrentUICulture = HttpServerUtility.CreateReadOnlyCultureInfo(globConfig.UICulture);
                } 

                // check for errors in  section
                RuntimeConfig appConfig = RuntimeConfig.GetAppConfig();
                object section = appConfig.ProcessModel; 
                // check for errors in  section
                section = appConfig.HostingEnvironment; 
            } 
        }
 
        private void InitHeaderEncoding() {
            HttpRuntimeSection runtimeConfig = RuntimeConfig.GetAppConfig().HttpRuntime;
            _enableHeaderChecking = runtimeConfig.EnableHeaderChecking;
        } 

        private static void SetAutogenKeys() { 
#if !FEATURE_PAL // FEATURE_PAL does not enable cryptography 
            byte[] bKeysRandom = new byte[s_autogenKeys.Length];
            byte[] bKeysStored = new byte[s_autogenKeys.Length]; 
            bool fGetStoredKeys = false;
            RNGCryptoServiceProvider randgen = new RNGCryptoServiceProvider();

            // Gernerate random keys 
            randgen.GetBytes(bKeysRandom);
 
            // If getting stored keys via WorkerRequest object failed, get it directly 
            if (!fGetStoredKeys)
                fGetStoredKeys = (UnsafeNativeMethods.EcbCallISAPI(IntPtr.Zero, UnsafeNativeMethods.CallISAPIFunc.GetAutogenKeys, 
                                                                   bKeysRandom, bKeysRandom.Length, bKeysStored, bKeysStored.Length) == 1);

            // If we managed to get stored keys, copy them in; else use random keys
            if (fGetStoredKeys) 
                Buffer.BlockCopy(bKeysStored, 0, s_autogenKeys, 0, s_autogenKeys.Length);
            else 
                Buffer.BlockCopy(bKeysRandom, 0, s_autogenKeys, 0, s_autogenKeys.Length); 
#endif // !FEATURE_PAL
        } 

        internal static void IncrementActivePipelineCount() {
            Interlocked.Increment(ref _theRuntime._activeRequestCount);
            HostingEnvironment.IncrementBusyCount(); 
        }
 
        internal static void DecrementActivePipelineCount() { 
            HostingEnvironment.DecrementBusyCount();
            Interlocked.Decrement(ref _theRuntime._activeRequestCount); 
        }

        // DevDivBugs 190952: public method for querying runtime pipeline mode
        public static bool UsingIntegratedPipeline { 
            get {
                return UseIntegratedPipeline; 
            } 
        }
 
        internal static bool UseIntegratedPipeline {
            get {
                return _useIntegratedPipeline;
            } 
            set {
                _useIntegratedPipeline = value; 
            } 
        }
 

        /*
         * Process one step of the integrated pipeline
         * 
         */
 
        internal static RequestNotificationStatus ProcessRequestNotification(IIS7WorkerRequest wr, HttpContext context) 
        {
            return _theRuntime.ProcessRequestNotificationPrivate(wr, context); 
        }

        private RequestNotificationStatus ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) {
            RequestNotificationStatus status = RequestNotificationStatus.Pending; 
            try {
                // setup the HttpContext for this event/module combo 
                context.CurrentModuleIndex = UnsafeIISMethods.MgdGetCurrentModuleIndex(wr.RequestContext); 
                context.IsPostNotification = UnsafeIISMethods.MgdIsCurrentNotificationPost(wr.RequestContext);
                context.CurrentNotification = (RequestNotification)UnsafeIISMethods.MgdGetCurrentNotification(wr.RequestContext); 
#if DBG
                Debug.Trace("PipelineRuntime", "HttpRuntime::ProcessRequestNotificationPrivate: notification=" + context.CurrentNotification.ToString()
                            + ", isPost=" + context.IsPostNotification
                            + ", moduleIndex=" + context.CurrentModuleIndex); 
#endif
 
                IHttpHandler handler = null; 
                if (context.NeedToInitializeApp()) {
                    // First request initialization 
                    try {
                        EnsureFirstRequestInit(context);
                    }
                    catch { 
                        // If we are handling a DEBUG request, ignore the FirstRequestInit exception.
                        // This allows the HttpDebugHandler to execute, and lets the debugger attach to 
                        // the process (VSWhidbey 358135) 
                        if (!context.Request.IsDebuggingRequest) {
                            throw; 
                        }
                    }

                    context.Response.InitResponseWriter(); 
                    handler = HttpApplicationFactory.GetApplicationInstance(context);
                    if (handler == null) 
                        throw new HttpException(SR.GetString(SR.Unable_create_app_object)); 

                    if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, handler.GetType().FullName, "Start"); 

                    HttpApplication app = handler as HttpApplication;
                    if (app != null) {
                        // associate the context with an application instance 
                        app.AssignContext(context);
                    } 
                } 

                // this may throw, and should be called after app initialization 
                wr.SynchronizeVariables(context);

                if (context.ApplicationInstance != null) {
                    // process request 
                    IAsyncResult ar = context.ApplicationInstance.BeginProcessRequestNotification(context, _requestNotificationCompletionCallback);
 
                    if (ar.CompletedSynchronously) { 
                        status = RequestNotificationStatus.Continue;
                    } 
                }
                else if (handler != null) {
                    // HttpDebugHandler is processed here
                    handler.ProcessRequest(context); 
                    status = RequestNotificationStatus.FinishRequest;
                } 
                else { 
                    status = RequestNotificationStatus.Continue;
                } 
            }
            catch (Exception e) {
                status = RequestNotificationStatus.FinishRequest;
                context.Response.InitResponseWriter(); 
                // errors are handled in HttpRuntime::FinishRequestNotification
                context.AddError(e); 
            } 

            if (status != RequestNotificationStatus.Pending) { 
                // we completed synchronously
                FinishRequestNotification(wr, context, ref status);
            }
 
#if DBG
            Debug.Trace("PipelineRuntime", "HttpRuntime::ProcessRequestNotificationPrivate: status=" + status.ToString()); 
#endif 

            return status; 
        }

        private void FinishRequestNotification(IIS7WorkerRequest wr, HttpContext context, ref RequestNotificationStatus status) {
 
            Debug.Assert(status != RequestNotificationStatus.Pending, "status != RequestNotificationStatus.Pending");
 
            HttpApplication app = context.ApplicationInstance; 

            if (context.NotificationContext.RequestCompleted) { 
                status = RequestNotificationStatus.FinishRequest;
            }

            // check if the app offline or whether an error has occurred, and report the condition 
            context.ReportRuntimeErrorIfExists(ref status);
 
            // we do not return FinishRequest for LogRequest or EndRequest 
            if (status == RequestNotificationStatus.FinishRequest
                && (context.CurrentNotification == RequestNotification.LogRequest 
                    || context.CurrentNotification == RequestNotification.EndRequest)) {
                status = RequestNotificationStatus.Continue;
            }
 
            IntPtr requestContext = wr.RequestContext;
            bool sendHeaders = UnsafeIISMethods.MgdIsLastNotification(requestContext, status); 
            try { 
                context.Response.UpdateNativeResponse(sendHeaders);
            } 
            catch(Exception e) {
                // if we catch an exception here then
                // i) clear cached response body bytes on the worker request
                // ii) clear the managed headers, the IIS native headers, the mangaged httpwriter response buffers, and the native IIS response buffers 
                // iii) attempt to format the exception and write it to the response
                wr.UnlockCachedResponseBytes(); 
                context.AddError(e); 
                context.ReportRuntimeErrorIfExists(ref status);
                context.Response.UpdateNativeResponse(sendHeaders); 
            }

            if (sendHeaders) {
                context.FinishPipelineRequest(); 
            }
 
            // Perf optimization: dispose managed context if possible (no need to try if status is pending) 
            if (status != RequestNotificationStatus.Pending) {
                PipelineRuntime.DisposeHandler(context, requestContext, status); 
            }
        }

        internal static void FinishPipelineRequest(HttpContext context) { 
            // Remember that first request is done
            _theRuntime._firstRequestCompleted = true; 
            context.Request.Dispose(); 
            context.Response.Dispose();
            HttpApplication app = context.ApplicationInstance; 
            if(null != app) {
                HttpApplication.ThreadContext threadContext = context.IndicateCompletionContext;
                if (threadContext != null) {
                    if (!threadContext.HasLeaveBeenCalled) { 
                        lock (threadContext) {
                            if (!threadContext.HasLeaveBeenCalled) { 
                                threadContext.Leave(); 
                                context.IndicateCompletionContext = null;
                                context.InIndicateCompletion = false; 
                            }
                        }
                    }
                } 
                app.ReleaseAppInstance();
            } 
 
            SetExecutionTimePerformanceCounter(context);
            UpdatePerfCounters(context.Response.StatusCode); 
            if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_END_HANDLER, context.WorkerRequest);

            // In case of a HostingInit() error, app domain should not stick around
            if (HostingInitFailed) { 
                Debug.Trace("AppDomainFactory", "Shutting down appdomain because of HostingInit error");
                ShutdownAppDomain(ApplicationShutdownReason.HostingEnvironment, "HostingInit error"); 
            } 
        }
 

        /*
         * Process one request
         */ 
        private void ProcessRequestInternal(HttpWorkerRequest wr) {
            // Construct the Context on HttpWorkerRequest, hook everything together 
            HttpContext context; 

            try { 
                context = new HttpContext(wr, false /* initResponseWriter */);
            }
            catch {
                // If we fail to create the context for any reason, send back a 400 to make sure 
                // the request is correctly closed (relates to VSUQFE3962)
                wr.SendStatus(400, "Bad Request"); 
                wr.SendKnownResponseHeader(HttpWorkerRequest.HeaderContentType, "text/html; charset=utf-8"); 
                byte[] body = Encoding.ASCII.GetBytes("Bad Request");
                wr.SendResponseFromMemory(body, body.Length); 
                wr.FlushResponse(true);
                wr.EndOfRequest();
                return;
            } 

            wr.SetEndOfSendNotification(_asyncEndOfSendCallback, context); 
 
            // Count active requests
            Interlocked.Increment(ref _activeRequestCount); 
            HostingEnvironment.IncrementBusyCount();

            try {
                // First request initialization 
                try {
                    EnsureFirstRequestInit(context); 
                } 
                catch {
                    // If we are handling a DEBUG request, ignore the FirstRequestInit exception. 
                    // This allows the HttpDebugHandler to execute, and lets the debugger attach to
                    // the process (VSWhidbey 358135)
                    if (!context.Request.IsDebuggingRequest) {
                        throw; 
                    }
                } 
 
                // Init response writer (after we have config in first request init)
                // no need for impersonation as it is handled in config system 
                context.Response.InitResponseWriter();

                // Get application instance
                IHttpHandler app = HttpApplicationFactory.GetApplicationInstance(context); 

                if (app == null) 
                    throw new HttpException(SR.GetString(SR.Unable_create_app_object)); 

                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, app.GetType().FullName, "Start"); 

                // Process the request

                if (app is IHttpAsyncHandler) { 
                    // asynchronous handler
                    IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler)app; 
                    context.AsyncAppHandler = asyncHandler; 
                    asyncHandler.BeginProcessRequest(context, _handlerCompletionCallback, context);
                } 
                else {
                    // synchronous handler
                    app.ProcessRequest(context);
                    FinishRequest(context.WorkerRequest, context, null); 
                }
            } 
            catch (Exception e) { 
                context.Response.InitResponseWriter();
                FinishRequest(wr, context, e); 
            }
        }

        private void RejectRequestInternal(HttpWorkerRequest wr, bool silent) { 
            // Construct the Context on HttpWorkerRequest, hook everything together
            HttpContext context = new HttpContext(wr, false /* initResponseWriter */); 
            wr.SetEndOfSendNotification(_asyncEndOfSendCallback, context); 

            // Count active requests 
            Interlocked.Increment(ref _activeRequestCount);
            HostingEnvironment.IncrementBusyCount();

            if (silent) { 
                context.Response.InitResponseWriter();
                FinishRequest(wr, context, null); 
            } 
            else {
                PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.REQUESTS_REJECTED); 
                PerfCounters.IncrementCounter(AppPerfCounter.APP_REQUESTS_REJECTED);
                try {
                    throw new HttpException(503, SR.GetString(SR.Server_too_busy));
                } 
                catch (Exception e) {
                    context.Response.InitResponseWriter(); 
                    FinishRequest(wr, context, e); 
                }
            } 
        }


        /* 
         * Finish processing request, [....] or async
         */ 
        private void FinishRequest(HttpWorkerRequest wr, HttpContext context, Exception e) { 
            HttpResponse response = context.Response;
 
            if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_END_HANDLER, context.WorkerRequest);

            SetExecutionTimePerformanceCounter(context);
 
            // Flush in case of no error
            if (e == null) { 
                // impersonate around PreSendHeaders / PreSendContent 
                using (new ClientImpersonationContext(context, false)) {
                    try { 
                        // this sends the actual content in most cases
                        response.FinalFlushAtTheEndOfRequestProcessing();
                    }
                    catch (Exception eFlush) { 
                        e = eFlush;
                    } 
                } 
            }
 
            // Report error if any
            if (e != null) {
                if (_appOfflineMessage != null) {
                    try { 
                        response.StatusCode = 404;
                        response.OutputStream.Write(_appOfflineMessage, 0, _appOfflineMessage.Length); 
                        response.FinalFlushAtTheEndOfRequestProcessing(); 
                    }
                    catch { 
                    }
                }
                else {
                    using (new HttpContextWrapper(context)) { 
                        // when application is on UNC share the code below must
                        // be run while impersonating the token given by IIS 
                        using (new ApplicationImpersonationContext()) { 
                            try {
                                try { 
                                    // try to report error in a way that could possibly throw (a config exception)
                                    response.ReportRuntimeError(e, true /*canThrow*/, false);
                                }
                                catch (Exception eReport) { 
                                    // report the config error in a way that would not throw
                                    response.ReportRuntimeError(eReport, false /*canThrow*/, false); 
                                } 

                                response.FinalFlushAtTheEndOfRequestProcessing(); 
                            }
                            catch {
                            }
                        } 
                    }
                } 
            } 

            // Remember that first request is done 
            _firstRequestCompleted = true;


            // In case we reporting HostingInit() error, app domain should not stick around 
            if (_hostingInitFailed) {
                Debug.Trace("AppDomainFactory", "Shutting down appdomain because of HostingInit error"); 
                ShutdownAppDomain(ApplicationShutdownReason.HostingEnvironment, "HostingInit error"); 
            }
 
            // Check status code and increment proper counter
            // If it's an error status code (i.e. 400 or higher), increment the proper perf counters
            int statusCode = response.StatusCode;
            UpdatePerfCounters(statusCode); 

            context.FinishRequestForCachedPathData(statusCode); 
 
            wr.EndOfRequest();
 
            // Count active requests
            HostingEnvironment.DecrementBusyCount();
            Interlocked.Decrement(ref _activeRequestCount);
 
            // Schedule more work if some requests are queued
            if (_requestQueue != null) 
                _requestQueue.ScheduleMoreWorkIfNeeded(); 
        }
 
        //
        // Make sure shutdown happens only once
        //
 
        private bool InitiateShutdownOnce() {
            if (_shutdownInProgress) 
                return false; 

            lock (this) { 
                if (_shutdownInProgress)
                    return false;
                _shutdownInProgress = true;
            } 

            return true; 
        } 

        // 
        // Shutdown this and restart new app domain
        //

        private void ReleaseResourcesAndUnloadAppDomain(Object state /*not used*/) { 
            Debug.Trace("AppDomainFactory", "ReleaseResourcesAndUnloadAppDomain, Id=" + _appDomainAppId
                        + " DomainId = " + _appDomainId 
                        + " Stack = " + Environment.StackTrace ); 

            try { 
                PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.APPLICATION_RESTARTS);
            }
            catch {
            } 

            // Release all resources 
            try { 
                Dispose();
            } 
            catch {
            }

            Thread.Sleep(250); 

            AddAppDomainTraceMessage("before Unload"); 
 
            for (; ; ) {
                try { 
                    AppDomain.Unload(Thread.GetDomain());
                }
                catch (CannotUnloadAppDomainException) {
                    Debug.Assert(false); 
                }
                catch (Exception e) { 
                    Debug.Trace("AppDomainFactory", "AppDomain.Unload exception: " + e + "; Id=" + _appDomainAppId); 
                    AddAppDomainTraceMessage("Unload Exception: " + e);
                    throw; 
                }
            }
        }
 
        private static void SetExecutionTimePerformanceCounter(HttpContext context) {
            // Set the Request Execution time perf counter 
            TimeSpan elapsed = DateTime.UtcNow.Subtract(context.WorkerRequest.GetStartTime()); 
            long milli = elapsed.Ticks / TimeSpan.TicksPerMillisecond;
 
            if (milli > Int32.MaxValue)
                milli = Int32.MaxValue;

            PerfCounters.SetGlobalCounter(GlobalPerfCounter.REQUEST_EXECUTION_TIME, (int)milli); 
            PerfCounters.SetCounter(AppPerfCounter.APP_REQUEST_EXEC_TIME, (int)milli);
        } 
 
        private static void UpdatePerfCounters(int statusCode) {
            if (400 <= statusCode) { 
                PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_FAILED);
                switch (statusCode) {
                    case 401: // Not authorized
                        PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_AUTHORIZED); 
                        break;
                    case 404: // Not found 
                    case 414: // Not found 
                        PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_FOUND);
                        break; 
                }
            }
            else {
                // If status code is not in the 400-599 range (i.e. 200-299 success or 300-399 redirection), 
                // count it as a successful request.
                PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_SUCCEDED); 
            } 
        }
 
        private void WaitForRequestsToFinish(int waitTimeoutMs) {
            DateTime waitLimit = DateTime.UtcNow.AddMilliseconds(waitTimeoutMs);

            for (; ; ) { 
                if (_activeRequestCount == 0 && (_requestQueue == null || _requestQueue.IsEmpty))
                    break; 
 
                Thread.Sleep(250);
 
                // only apply timeout if a managed debugger is not attached
                if (!System.Diagnostics.Debugger.IsAttached && DateTime.UtcNow > waitLimit) {
                    break; // give it up
                } 
            }
        } 
 
        /*
         * Cleanup of all unmananged state 
         */
        private void Dispose() {
            // get shutdown timeout from config
            int drainTimeoutSec = HttpRuntimeSection.DefaultShutdownTimeout; 
            HttpRuntimeSection runtimeConfig = RuntimeConfig.GetAppLKGConfig().HttpRuntime;
            if (runtimeConfig != null) { 
                drainTimeoutSec = (int)runtimeConfig.ShutdownTimeout.TotalSeconds; 
            }
 
            // before aborting compilation give time to drain (new requests are no longer coming at this point)
            WaitForRequestsToFinish(drainTimeoutSec * 1000);

            // reject remaining queued requests 
            if (_requestQueue != null)
                _requestQueue.Drain(); 
 
            // give it a little more time to drain
            WaitForRequestsToFinish((drainTimeoutSec * 1000) / 6); 


            // wait for pending async io to complete,  prior to aborting requests
            // this isn't necessary for IIS 7, where the async sends are always done 
            // from native code with native buffers
            System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.WaitForPendingAsyncIo(); 
 
            // For IIS7 integrated pipeline, wait until GL_APPLICATION_STOP fires and
            // there are no active calls to IndicateCompletion before unloading the AppDomain 
            if (HttpRuntime.UseIntegratedPipeline) {
                PipelineRuntime.WaitForRequestsToDrain();
            }
 
#if ORCAS
            // Kill the HttpDataStore cleanup thread and dispose the storage provider 
            if (_httpDataStorageCleanup != null) { 
                _httpDataStorageCleanup.Stop();
            } 

            if (_httpDataStorageProvider != null) {
                _httpDataStorageProvider.Dispose();
            } 
#endif
 
            // Dispose AppDomainShutdownTimer 
            DisposeAppDomainShutdownTimer();
 
            // kill all remaining requests (and the timeout timer)
            _timeoutManager.Stop();

            // give it a little more time to drain 
            WaitForRequestsToFinish((drainTimeoutSec * 1000) / 6);
 
#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features 
            // double check for pending async io
            System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.WaitForPendingAsyncIo(); 

            // stop sqlcachedependency polling
            SqlCacheDependencyManager.Dispose((drainTimeoutSec * 1000) / 2);
#endif // !FEATURE_PAL 
            // cleanup cache (this ends all sessions)
            if (_cacheInternal != null) { 
                _cacheInternal.Dispose(); 
            }
#if SITECOUNTERS 

            // cleanup siteCounters (this flushes all counter data)
            if (_siteCounters != null) {
                _siteCounters.Dispose(); 
            }
#endif 
            // app on end, cleanup app instances 
            HttpApplicationFactory.EndApplication();  // call app_onEnd
 
            // stop file changes monitor
            _fcm.Stop();

            // stop health monitoring timer 
            HealthMonitoringManager.Shutdown();
        } 
 
        /*
         * Async completion of IIS7 pipeline (unlike OnHandlerCompletion, this may fire more than once). 
         */
        private void OnRequestNotificationCompletion(IAsyncResult ar) {
            try {
                OnRequestNotificationCompletionHelper(ar); 
            }
            catch(Exception e) { 
                ApplicationManager.RecordFatalException(e); 
                throw;
            } 
        }

        private void OnRequestNotificationCompletionHelper(IAsyncResult ar) {
            if (ar.CompletedSynchronously) { 
                Debug.Trace("PipelineRuntime", "OnRequestNotificationCompletion: completed synchronously");
                return; 
            } 

            Debug.Trace("PipelineRuntime", "OnRequestNotificationCompletion: completed asynchronously"); 

            RequestNotificationStatus status = RequestNotificationStatus.Continue;
            HttpContext context = (HttpContext) ar.AsyncState;
            IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest; 

            try { 
                context.ApplicationInstance.EndProcessRequestNotification(ar); 
            }
            catch (Exception e) { 
                status = RequestNotificationStatus.FinishRequest;
                context.AddError(e);
            }
 
            // RequestContext is set to null if this is the last notification, so we need to save it
            // for the call to PostCompletion 
            IntPtr requestContext = wr.RequestContext; 

            FinishRequestNotification(wr, context, ref status); 

            // set the notification context to null since we are exiting this notification
            context.NotificationContext = null;
 
            // Indicate completion to IIS, so that it can resume
            // request processing on an IIS thread 
            Debug.Trace("PipelineRuntime", "OnRequestNotificationCompletion(" + status + ")"); 
            int result = UnsafeIISMethods.MgdPostCompletion(requestContext, status);
            Misc.ThrowIfFailedHr(result); 
        }

        /*
         * Async completion of managed pipeline (called at most one time). 
         */
        private void OnHandlerCompletion(IAsyncResult ar) { 
            HttpContext context = (HttpContext)ar.AsyncState; 

            try { 
                context.AsyncAppHandler.EndProcessRequest(ar);
            }
            catch (Exception e) {
                context.AddError(e); 
            }
            finally { 
                // no longer keep AsyncAppHandler poiting to the application 
                // is only needed to call EndProcessRequest
                context.AsyncAppHandler = null; 
            }

            FinishRequest(context.WorkerRequest, context, context.Error);
        } 

        /* 
         * Notification from worker request that it is done writing from buffer 
         * so that the buffers can be recycled
         */ 
        private void EndOfSendCallback(HttpWorkerRequest wr, Object arg) {
            Debug.Trace("PipelineRuntime", "HttpRuntime.EndOfSendCallback");
            HttpContext context = (HttpContext)arg;
            context.Request.Dispose(); 
            context.Response.Dispose();
        } 
 
        /*
         * Notification when something in the bin directory changed 
         */
        private void OnCriticalDirectoryChange(Object sender, FileChangeEvent e) {
            // shutdown the app domain
            Debug.Trace("AppDomainFactory", "Shutting down appdomain because of bin dir change or directory rename." + 
                " FileName=" + e.FileName + " Action=" + e.Action);
 
            ApplicationShutdownReason reason = ApplicationShutdownReason.None; 
            string directoryName = new DirectoryInfo(e.FileName).Name;
 
            string message = directoryName + " dir change or directory rename";

            if (StringUtil.EqualsIgnoreCase(directoryName, CodeDirectoryName)) {
                reason = ApplicationShutdownReason.CodeDirChangeOrDirectoryRename; 
            }
            else if (StringUtil.EqualsIgnoreCase(directoryName, ResourcesDirectoryName)) { 
                reason = ApplicationShutdownReason.ResourcesDirChangeOrDirectoryRename; 
            }
            else if (StringUtil.EqualsIgnoreCase(directoryName, BrowsersDirectoryName)) { 
                reason = ApplicationShutdownReason.BrowsersDirChangeOrDirectoryRename;
            }
            else if (StringUtil.EqualsIgnoreCase(directoryName, BinDirectoryName)) {
                reason = ApplicationShutdownReason.BinDirChangeOrDirectoryRename; 
            }
 
            if (e.Action == FileAction.Added) { 
                // Make sure HttpRuntime does not ignore the appdomain shutdown if a file is added (VSWhidbey 363481)
                HttpRuntime.SetUserForcedShutdown(); 

                Debug.Trace("AppDomainFactorySpecial", "Call SetUserForcedShutdown: FileName=" + e.FileName + "; now=" + DateTime.Now);
            }
 
            ShutdownAppDomain(reason, message);
        } 
 
        /**
         * Coalesce file change notifications to minimize sharing violations and AppDomain restarts (ASURT 147492) 
         */
        private void CoalesceNotifications() {
            int waitChangeNotification = HttpRuntimeSection.DefaultWaitChangeNotification;
            int maxWaitChangeNotification = HttpRuntimeSection.DefaultMaxWaitChangeNotification; 
            try {
                HttpRuntimeSection config = RuntimeConfig.GetAppLKGConfig().HttpRuntime; 
                if (config != null) { 
                    waitChangeNotification = config.WaitChangeNotification;
                    maxWaitChangeNotification = config.MaxWaitChangeNotification; 
                }
            }
            catch {
            } 

            if (waitChangeNotification == 0 || maxWaitChangeNotification == 0) 
                return; 

            DateTime maxWait = DateTime.UtcNow.AddSeconds(maxWaitChangeNotification); 
            // Coalesce file change notifications
            try {
                while (DateTime.UtcNow < maxWait) {
                    if (DateTime.UtcNow > LastShutdownAttemptTime.AddSeconds(waitChangeNotification)) 
                        break;
 
                    Thread.Sleep(250); 
                }
            } 
            catch {
            }
        }
 
        // appdomain shutdown eventhandler
        internal static event BuildManagerHostUnloadEventHandler AppDomainShutdown; 
 
        internal static void OnAppDomainShutdown(BuildManagerHostUnloadEventArgs e) {
            if (AppDomainShutdown != null) { 
                AppDomainShutdown(_theRuntime, e);
            }
        }
 
        internal static void SetUserForcedShutdown() {
            _theRuntime._userForcedShutdown = true; 
        } 

        /* 
         * Shutdown the current app domain
         */
        internal static bool ShutdownAppDomain(ApplicationShutdownReason reason, string message) {
            return ShutdownAppDomainWithStackTrace(reason, message, null /*stackTrace*/); 
        }
 
        /* 
         * Shutdown the current app domain with a stack trace.  This is useful for callers that are running
         * on a QUWI callback, and wouldn't provide a meaningful stack trace by default. 
         */
        internal static bool ShutdownAppDomainWithStackTrace(ApplicationShutdownReason reason, string message, string stackTrace) {
            SetShutdownReason(reason, message);
            return ShutdownAppDomain(stackTrace); 
        }
 
        private static bool ShutdownAppDomain(string stackTrace) { 
            // Ignore notifications during the processing of the first request (ASURT 100335)
            if (!_theRuntime._firstRequestCompleted && !_theRuntime._userForcedShutdown) { 
                // check the timeout (don't disable notifications forever
                int delayTimeoutSec = HttpRuntimeSection.DefaultDelayNotificationTimeout;

                try { 
                    RuntimeConfig runtimeConfig = RuntimeConfig.GetAppLKGConfig();
                    if (runtimeConfig != null) { 
                        HttpRuntimeSection runtimeSection = runtimeConfig.HttpRuntime; 
                        if (runtimeSection != null) {
                            delayTimeoutSec = (int)runtimeSection.DelayNotificationTimeout.TotalSeconds; 

                            if (DateTime.UtcNow < _theRuntime._firstRequestStartTime.AddSeconds(delayTimeoutSec)) {
                                Debug.Trace("AppDomainFactory", "ShutdownAppDomain IGNORED (1st request is not done yet), Id = " + AppDomainAppIdInternal);
                                return false; 
                            }
                        } 
                    } 
                }
                catch { 
                }
            }

            try { 
                _theRuntime.RaiseShutdownWebEventOnce();
            } 
            catch { 
                // VSWhidbey 444472: if an exception is thrown, we consume it and continue executing the following code.
            } 

            // Update last time ShutdownAppDomain was called
            _theRuntime.LastShutdownAttemptTime = DateTime.UtcNow;
 
            _theRuntime.CoalesceNotifications();
 
            if (!HostingEnvironment.ShutdownInitiated) { 
                // This shutdown is not triggered by hosting environment - let it do the job
                HostingEnvironment.InitiateShutdown(); 
                return true;
            }

            //WOS 1400290: CantUnloadAppDomainException in ISAPI mode, wait until HostingEnvironment.ShutdownThisAppDomainOnce completes 
            if (HostingEnvironment.ShutdownInProgress) {
                return false; 
            } 

            // Make sure we don't go through shutdown logic many times 
            if (!_theRuntime.InitiateShutdownOnce())
                return false;

            Debug.Trace("AppDomainFactory", "ShutdownAppDomain, Id = " + AppDomainAppIdInternal + ", ShutdownInProgress=" + ShutdownInProgress 
                        + ", ShutdownMessage=" + _theRuntime._shutDownMessage);
 
            if (String.IsNullOrEmpty(stackTrace)) { 
                // Instrument to be able to see what's causing a shutdown
                new EnvironmentPermission(PermissionState.Unrestricted).Assert(); 
                try {
                    _theRuntime._shutDownStack = Environment.StackTrace;
                }
                finally { 
                    CodeAccessPermission.RevertAssert();
                } 
            } 
            else {
                _theRuntime._shutDownStack = stackTrace; 
            }

            // Notify when appdomain is about to shutdown.
            OnAppDomainShutdown(new BuildManagerHostUnloadEventArgs(_theRuntime._shutdownReason)); 

            // unload app domain from another CLR thread 
            ThreadPool.QueueUserWorkItem(_theRuntime._appDomainUnloadallback); 

            return true; 
        }

        internal static void RecoverFromUnexceptedAppDomainUnload() {
            if (_theRuntime._shutdownInProgress) 
                return;
 
            // someone unloaded app domain directly - tell unmanaged code 
            Debug.Trace("AppDomainFactory", "Unexpected AppDomainUnload");
            _theRuntime._shutdownInProgress = true; 

            // tell unmanaged code not to dispatch requests to this app domain
            try {
                ISAPIRuntime.RemoveThisAppDomainFromUnmanagedTable(); 
                PipelineRuntime.RemoveThisAppDomainFromUnmanagedTable();
                AddAppDomainTraceMessage("AppDomainRestart"); 
            } 
            finally {
                // release all resources 
                _theRuntime.Dispose();
            }
        }
 
        /*
         * Notification when app-level Config changed 
         */ 
        internal static void OnConfigChange() {
            Debug.Trace("AppDomainFactory", "Shutting down appdomain because of config change"); 
            ShutdownAppDomain(ApplicationShutdownReason.ConfigurationChange, "CONFIG change");
        }

        // Intrumentation to remember the overwhelming file change 
        internal static void SetShutdownReason(ApplicationShutdownReason reason, String message) {
            if (_theRuntime._shutdownReason == ApplicationShutdownReason.None) { 
                _theRuntime._shutdownReason = reason; 
            }
 
            SetShutdownMessage(message);
        }

        internal static void SetShutdownMessage(String message) { 
            if (message != null) {
                if (_theRuntime._shutDownMessage == null) 
                    _theRuntime._shutDownMessage = message; 
                else
                    _theRuntime._shutDownMessage += "\r\n" + message; 
            }
        }

 
        // public method is on HostingEnvironment
        internal static ApplicationShutdownReason ShutdownReason { 
            get { return _theRuntime._shutdownReason; } 
        }
 
        //
        // public static APIs
        //
 
        /*
         * Process one request 
         */ 

        ///  
        ///    The method that drives
        ///       all ASP.NET web processing execution.
        /// 
        [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)] 
        public static void ProcessRequest(HttpWorkerRequest wr) {
            if (wr == null) 
                throw new ArgumentNullException("wr"); 

            if (HttpRuntime.UseIntegratedPipeline) { 
                throw new PlatformNotSupportedException(SR.GetString(SR.Method_Not_Supported_By_Iis_Integrated_Mode, "HttpRuntime.ProcessRequest"));
            }

            ProcessRequestNoDemand(wr); 
        }
 
 
        internal static void ProcessRequestNoDemand(HttpWorkerRequest wr) {
            RequestQueue rq = _theRuntime._requestQueue; 

            if (rq != null)  // could be null before first request
                wr = rq.GetRequestToExecute(wr);
 
            if (wr != null) {
                CalculateWaitTimeAndUpdatePerfCounter(wr); 
                wr.ResetStartTime(); 
                ProcessRequestNow(wr);
            } 
        }


        private static void CalculateWaitTimeAndUpdatePerfCounter(HttpWorkerRequest wr) { 
            DateTime begin = wr.GetStartTime();
 
            TimeSpan elapsed = DateTime.UtcNow.Subtract(begin); 
            long milli = elapsed.Ticks / TimeSpan.TicksPerMillisecond;
 
            if (milli > Int32.MaxValue)
                milli = Int32.MaxValue;

            PerfCounters.SetGlobalCounter(GlobalPerfCounter.REQUEST_WAIT_TIME, (int)milli); 
            PerfCounters.SetCounter(AppPerfCounter.APP_REQUEST_WAIT_TIME, (int)milli);
        } 
 
        internal static void ProcessRequestNow(HttpWorkerRequest wr) {
            _theRuntime.ProcessRequestInternal(wr); 
        }

        internal static void RejectRequestNow(HttpWorkerRequest wr, bool silent) {
            _theRuntime.RejectRequestInternal(wr, silent); 
        }
 
 
        /// 
        ///       Removes all items from the cache and shuts down the runtime. 
        ///    
        [SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
        public static void Close() {
            Debug.Trace("AppDomainFactory", "HttpRuntime.Close, ShutdownInProgress=" + ShutdownInProgress); 
            if (_theRuntime.InitiateShutdownOnce()) {
                SetShutdownReason(ApplicationShutdownReason.HttpRuntimeClose, "HttpRuntime.Close is called"); 
 
                if (HostingEnvironment.IsHosted) {
                    // go throw initiate shutdown for hosted scenarios 
                    HostingEnvironment.InitiateShutdown();
                }
                else {
                    _theRuntime.Dispose(); 
                }
            } 
        } 

 
        /// 
        ///       Unloads the current app domain.
        ///    
        [SecurityPermission(SecurityAction.Demand, Unrestricted = true)] 
        public static void UnloadAppDomain() {
            _theRuntime._userForcedShutdown = true; 
            ShutdownAppDomain(ApplicationShutdownReason.UnloadAppDomainCalled, "User code called UnloadAppDomain"); 
        }
 
        private DateTime LastShutdownAttemptTime {
            get {
                DateTime dt;
                lock (this) { 
                    dt = _lastShutdownAttemptTime;
                } 
                return dt; 
            }
            set { 
                lock (this) {
                    _lastShutdownAttemptTime = value;
                }
            } 
        }
 
        internal static Profiler Profile { 
            get {
                return _theRuntime._profiler; 
            }
        }

        internal static bool IsTrustLevelInitialized { 
            get {
                return !HostingEnvironment.IsHosted || TrustLevel != null; 
            } 
        }
 
        internal static NamedPermissionSet NamedPermissionSet {
            get {
                // Make sure we have already initialized the trust level
                // 

 
                return _theRuntime._namedPermissionSet; 
            }
        } 

        [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Unrestricted)]
        public static NamedPermissionSet GetNamedPermissionSet() {
            NamedPermissionSet namedPermissionSet = _theRuntime._namedPermissionSet; 
            if (namedPermissionSet == null) {
                return null; 
            } 
            else {
                return new NamedPermissionSet(namedPermissionSet); 
            }
        }

 
        internal static bool IsFullTrust {
            get { 
                // Make sure we have already initialized the trust level 
                Debug.Assert(IsTrustLevelInitialized);
 
                return (_theRuntime._namedPermissionSet == null);
            }
        }
 
        /*
         * Check that the current trust level allows access to a virtual path.  Throw if it doesn't, 
         */ 
        internal static void CheckVirtualFilePermission(string virtualPath) {
            string physicalPath = HostingEnvironment.MapPath(virtualPath); 
            CheckFilePermission(physicalPath);
        }

        /* 
         * Check that the current trust level allows access to a path.  Throw if it doesn't,
         */ 
        internal static void CheckFilePermission(string path) { 
            CheckFilePermission(path, false);
        } 

        internal static void CheckFilePermission(string path, bool writePermissions) {
            if (!HasFilePermission(path, writePermissions)) {
                throw new HttpException(SR.GetString(SR.Access_denied_to_path, GetSafePath(path))); 
            }
        } 
 
        internal static bool HasFilePermission(string path) {
            return HasFilePermission(path, false); 
        }

        internal static bool HasFilePermission(string path, bool writePermissions) {
            // WOS #1523618: need to skip this check for HttpResponse.ReportRuntimeError when reporting an 
            // InitializationException (e.g., necessary to display line info for ConfigurationException).
 
            if (TrustLevel == null && InitializationException != null) { 
                return true;
            } 

            // Make sure we have already initialized the trust level
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted, "TrustLevel != null || !HostingEnvironment.IsHosted");
 
            // If we don't have a NamedPermissionSet, we're in full trust
            if (NamedPermissionSet == null) 
                return true; 

            bool fAccess = false; 

            // Check that the user has permission to the path
            IPermission allowedPermission = NamedPermissionSet.GetPermission(typeof(FileIOPermission));
            if (allowedPermission != null) { 
                IPermission askedPermission = null;
                try { 
                    if (!writePermissions) 
                        askedPermission = new FileIOPermission(FileIOPermissionAccess.Read, path);
                    else 
                        askedPermission = new FileIOPermission(FileIOPermissionAccess.AllAccess, path);
                }
                catch {
                    // This could happen if the path is not absolute 
                    return false;
                } 
                fAccess = askedPermission.IsSubsetOf(allowedPermission); 
            }
 
            return fAccess;
        }

        internal static bool HasWebPermission(Uri uri) { 

            // Make sure we have already initialized the trust level 
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted); 

            // If we don't have a NamedPermissionSet, we're in full trust 
            if (NamedPermissionSet == null)
                return true;

            bool fAccess = false; 

            // Check that the user has permission to the URI 
            IPermission allowedPermission = NamedPermissionSet.GetPermission(typeof(WebPermission)); 
            if (allowedPermission != null) {
                IPermission askedPermission = null; 
                try {
                    askedPermission = new WebPermission(NetworkAccess.Connect, uri.ToString());
                }
                catch { 
                    return false;
                } 
                fAccess = askedPermission.IsSubsetOf(allowedPermission); 
            }
 
            return fAccess;
        }

        internal static bool HasDbPermission(DbProviderFactory factory) { 

            // Make sure we have already initialized the trust level 
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted); 

            // If we don't have a NamedPermissionSet, we're in full trust 
            if (NamedPermissionSet == null)
                return true;

            bool fAccess = false; 

            // Check that the user has permission to the provider 
            CodeAccessPermission askedPermission = factory.CreatePermission(PermissionState.Unrestricted); 
            if (askedPermission != null) {
                IPermission allowedPermission = NamedPermissionSet.GetPermission(askedPermission.GetType()); 
                if (allowedPermission != null) {
                    fAccess = askedPermission.IsSubsetOf(allowedPermission);
                }
            } 

            return fAccess; 
        } 

        internal static bool HasPathDiscoveryPermission(string path) { 
            // WOS #1523618: need to skip this check for HttpResponse.ReportRuntimeError when reporting an
            // InitializationException (e.g., necessary to display line info for ConfigurationException).

            if (TrustLevel == null && InitializationException != null) { 
                return true;
            } 
 
            // Make sure we have already initialized the trust level
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted); 

            // If we don't have a NamedPermissionSet, we're in full trust
            if (NamedPermissionSet == null)
                return true; 

            bool fAccess = false; 
 
            // Check that the user has permission to the path
            IPermission allowedPermission = NamedPermissionSet.GetPermission(typeof(FileIOPermission)); 
            if (allowedPermission != null) {
                IPermission askedPermission = new FileIOPermission(FileIOPermissionAccess.PathDiscovery, path);
                fAccess = askedPermission.IsSubsetOf(allowedPermission);
            } 

            return fAccess; 
 
        }
 
        internal static bool HasAppPathDiscoveryPermission() {
            return HasPathDiscoveryPermission(HttpRuntime.AppDomainAppPathInternal);
        }
 
        internal static string GetSafePath(string path) {
            if (String.IsNullOrEmpty(path)) 
                return path; 

            try { 
                if (HasPathDiscoveryPermission(path)) // could throw on bad filenames
                    return path;
            }
            catch { 
            }
 
            return Path.GetFileName(path); 
        }
 
        /*
         * Check that the current trust level allows Unmanaged access
         */
        internal static bool HasUnmanagedPermission() { 

            // Make sure we have already initialized the trust level 
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted); 

            // If we don't have a NamedPermissionSet, we're in full trust 
            if (NamedPermissionSet == null)
                return true;

            SecurityPermission securityPermission = (SecurityPermission)NamedPermissionSet.GetPermission( 
                typeof(SecurityPermission));
            if (securityPermission == null) 
                return false; 

            return (securityPermission.Flags & SecurityPermissionFlag.UnmanagedCode) != 0; 
        }

        internal static bool HasAspNetHostingPermission(AspNetHostingPermissionLevel level) {
 
            // Make sure we have already initialized the trust level
            // 
 

 
            // If we don't have a NamedPermissionSet, we're in full trust
            if (NamedPermissionSet == null)
                return true;
 
            AspNetHostingPermission permission = (AspNetHostingPermission)NamedPermissionSet.GetPermission(
                typeof(AspNetHostingPermission)); 
            if (permission == null) 
                return false;
 
            return (permission.Level >= level);
        }

        internal static void CheckAspNetHostingPermission(AspNetHostingPermissionLevel level, String errorMessageId) { 
            if (!HasAspNetHostingPermission(level)) {
                throw new HttpException(SR.GetString(errorMessageId)); 
            } 
        }
 
        // If we're not in full trust, fail if the passed in type doesn't have the APTCA bit
        internal static void FailIfNoAPTCABit(Type t, ElementInformation elemInfo, string propertyName) {

            if (!IsTypeAllowedInConfig(t)) { 
                if (null != elemInfo) {
                    PropertyInformation propInfo = elemInfo.Properties[propertyName]; 
 
                    throw new ConfigurationErrorsException(SR.GetString(SR.Type_from_untrusted_assembly, t.FullName),
                    propInfo.Source, propInfo.LineNumber); 
                }
                else {
                    throw new ConfigurationErrorsException(SR.GetString(SR.Type_from_untrusted_assembly, t.FullName));
                } 
            }
        } 
 
        // If we're not in full trust, fail if the passed in type doesn't have the APTCA bit
        internal static void FailIfNoAPTCABit(Type t, XmlNode node) { 

            if (!IsTypeAllowedInConfig(t)) {
                throw new ConfigurationErrorsException(SR.GetString(SR.Type_from_untrusted_assembly, t.FullName),
                    node); 
            }
        } 
 
        private static bool HasAPTCABit(Assembly assembly) {
            Object[] attrs = assembly.GetCustomAttributes( 
                typeof(System.Security.AllowPartiallyTrustedCallersAttribute), /*inherit*/ false);
            return (attrs != null && attrs.Length > 0);
        }
 
        // Check if the type is allowed to be used in config by checking the APTCA bit
        internal static bool IsTypeAllowedInConfig(Type t) { 
 
            // Allow everything in full trust
            if (HttpRuntime.HasAspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted)) 
                return true;

            Assembly assembly = t.Assembly;
 
            // The APTCA bit is only relevant for assemblies living in the GAC, since the rest runs
            // under partial trust (VSWhidbey 422183) 
            if (!assembly.GlobalAssemblyCache) 
                return true;
 
            // If it has the APTCA bit, allow it
            if (HttpRuntime.HasAPTCABit(assembly))
                return true;
 
            // It's a GAC type without APTCA in partial trust scenario: block it
            return false; 
        } 

        internal static FileChangesMonitor FileChangesMonitor { 
            get { return _theRuntime._fcm; }
        }

#if ORCAS 
        internal static IHttpDataStorageProvider HttpDataStorageProvider {
            get { return _theRuntime._httpDataStorageProvider;} 
        } 
#endif
 
        internal static RequestTimeoutManager RequestTimeoutManager {
            get { return _theRuntime._timeoutManager; }
        }
 

        ///  
        ///    Provides access to the cache. 
        /// 
        public static Cache Cache { 
            get {

                if (HttpRuntime.AspInstallDirectoryInternal == null) {
                    throw new HttpException(SR.GetString(SR.Aspnet_not_installed, VersionInfo.SystemWebVersion)); 
                }
 
                // In a web app, ReadCacheInternalConfig() is called from HttpRuntime.HostingInit. 
                // However, if the cache is used by a non-http app, HttpRuntime.HostingInit won't
                // be called and we need to find a way to call ReadCacheInternalConfig(). 
                // The safe and inexpensive place to call it is when the non-http app accesses the
                // Cache thru HttpRuntime.Cache.
                //
                // ReadCacheInternalConfig() protects itself from being read multiple times. 
                //
                Cache cachePublic = _theRuntime._cachePublic; 
                if (cachePublic == null) { 
                    CacheInternal cacheInternal = CacheInternal;
                    CacheSection cacheSection = RuntimeConfig.GetAppConfig().Cache; 
                    cacheInternal.ReadCacheInternalConfig(cacheSection);
                    _theRuntime._cachePublic = cacheInternal.CachePublic;
                    cachePublic = _theRuntime._cachePublic;
                } 

                return cachePublic; 
            } 
        }
 
        private void CreateCache() {
            lock (this) {
                if (_cacheInternal == null) {
                    _cacheInternal = CacheInternal.Create(); 
                }
            } 
        } 

        internal static CacheInternal CacheInternal { 
            get {
                // Note that we only create the cache on first access,
                // not in HttpRuntime initialization.
                // This prevents cache timers from running when 
                // the cache is not used.
                CacheInternal cacheInternal = _theRuntime._cacheInternal; 
                if (cacheInternal == null) { 
                    _theRuntime.CreateCache();
                    cacheInternal = _theRuntime._cacheInternal; 
                }

                return cacheInternal;
            } 
        }
#if SITECOUNTERS 
        internal static SiteCounters SiteCounters { 
            get { return _theRuntime._siteCounters; }
        } 
#endif

        /// 
        ///    [To be supplied.] 
        /// 
        public static string AspInstallDirectory { 
            get { 
                String path = AspInstallDirectoryInternal;
 
                if (path == null) {
                    throw new HttpException(SR.GetString(SR.Aspnet_not_installed, VersionInfo.SystemWebVersion));
                }
 
                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path; 
            } 
        }
 
        internal static string AspInstallDirectoryInternal {
            get { return s_installDirectory; }
        }
 
        //
        // Return the client script virtual path, e.g. "/aspnet_client/system_web/2_0_50217" 
        // 
        public static string AspClientScriptVirtualPath {
            get { 
                if (_theRuntime._clientScriptVirtualPath == null) {
                    string aspNetVersion = VersionInfo.SystemWebVersion;
                    string clientScriptVirtualPath = AspNetClientFilesParentVirtualPath + aspNetVersion.Substring(0, aspNetVersion.LastIndexOf('.')).Replace('.', '_');
 
                    _theRuntime._clientScriptVirtualPath = clientScriptVirtualPath;
                } 
 
                return _theRuntime._clientScriptVirtualPath;
            } 
        }

        public static string AspClientScriptPhysicalPath {
            get { 
                String path = AspClientScriptPhysicalPathInternal;
 
                if (path == null) { 
                    throw new HttpException(SR.GetString(SR.Aspnet_not_installed, VersionInfo.SystemWebVersion));
                } 

                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path;
            } 
        }
 
        // 
        // Return the client script physical path, e.g. @"c:\windows\microsoft.net\framework\v2.0.50217.0\asp.netclientfiles"
        // 
        internal static string AspClientScriptPhysicalPathInternal {
            get {
                if (_theRuntime._clientScriptPhysicalPath == null) {
                    string clientScriptPhysicalPath = System.IO.Path.Combine(AspInstallDirectoryInternal, AspNetClientFilesSubDirectory); 

                    _theRuntime._clientScriptPhysicalPath = clientScriptPhysicalPath; 
                } 

                return _theRuntime._clientScriptPhysicalPath; 
            }
        }

 
        /// 
        ///    [To be supplied.] 
        ///  
        public static string ClrInstallDirectory {
            get { 
                String path = ClrInstallDirectoryInternal;
                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path;
            } 
        }
 
        internal static string ClrInstallDirectoryInternal { 
            get { return HttpConfigurationSystem.MsCorLibDirectory; }
        } 



        ///  
        ///    [To be supplied.]
        ///  
        public static string MachineConfigurationDirectory { 
            get {
                String path = MachineConfigurationDirectoryInternal; 
                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path;
            }
        } 

        internal static string MachineConfigurationDirectoryInternal { 
            get { return HttpConfigurationSystem.MachineConfigurationDirectory; } 
        }
 
        internal static bool IsEngineLoaded {
            get { return s_isEngineLoaded; }
        }
 

        // 
        //  Static app domain related properties 
        //
 

        /// 
        ///    [To be supplied.]
        ///  
        public static String CodegenDir {
            get { 
                String path = CodegenDirInternal; 
                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path; 
            }
        }

        internal static string CodegenDirInternal { 
            get { return _theRuntime._codegenDir; }
        } 
 
        internal static string TempDirInternal {
            get { return _theRuntime._tempDir; } 
        }


        ///  
        ///    [To be supplied.]
        ///  
        public static String AppDomainAppId { 
            [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
            get { 
                return AppDomainAppIdInternal;
            }
        }
 
        internal static string AppDomainAppIdInternal {
            get { return _theRuntime._appDomainAppId; } 
        } 

        internal static bool IsAspNetAppDomain { 
            get { return AppDomainAppIdInternal != null; }
        }

 

        ///  
        ///    [To be supplied.] 
        /// 
        public static String AppDomainAppPath { 
            get {
                InternalSecurityPermissions.AppPathDiscovery.Demand();
                return AppDomainAppPathInternal;
            } 
        }
 
        internal static string AppDomainAppPathInternal { 
            get { return _theRuntime._appDomainAppPath; }
        } 


        /// 
        ///    [To be supplied.] 
        /// 
        public static String AppDomainAppVirtualPath { 
            get { 
                return VirtualPath.GetVirtualPathStringNoTrailingSlash(_theRuntime._appDomainAppVPath);
            } 
        }

        // Save as AppDomainAppVirtualPath, but includes the trailng slash.  We can't change
        // AppDomainAppVirtualPath since it's public. 
        internal static String AppDomainAppVirtualPathString {
            get { 
                return VirtualPath.GetVirtualPathString(_theRuntime._appDomainAppVPath); 
            }
        } 

        internal static VirtualPath AppDomainAppVirtualPathObject {
            get {
                return _theRuntime._appDomainAppVPath; 
            }
        } 
 
        internal static bool IsPathWithinAppRoot(String path) {
            if (AppDomainIdInternal == null) 
                return true;    // app domain not initialized

            return UrlPath.IsEqualOrSubpath(AppDomainAppVirtualPathString, path);
        } 

 
        ///  
        ///    [To be supplied.]
        ///  
        public static String AppDomainId {
            [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
            get {
                return AppDomainIdInternal; 
            }
        } 
 
        internal static string AppDomainIdInternal {
            get { return _theRuntime._appDomainId; } 
        }


 
        /// 
        ///    [To be supplied.] 
        ///  
        public static String BinDirectory {
            get { 
                String path = BinDirectoryInternal;
                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path;
            } 
        }
 
        internal static string BinDirectoryInternal { 
            get { return Path.Combine(_theRuntime._appDomainAppPath, BinDirectoryName) + Path.DirectorySeparatorChar; }
 
        }

        internal static VirtualPath CodeDirectoryVirtualPath {
            get { return _theRuntime._appDomainAppVPath.SimpleCombineWithDir(CodeDirectoryName); } 
        }
 
        internal static VirtualPath ResourcesDirectoryVirtualPath { 
            get { return _theRuntime._appDomainAppVPath.SimpleCombineWithDir(ResourcesDirectoryName); }
        } 

        internal static VirtualPath WebRefDirectoryVirtualPath {
            get { return _theRuntime._appDomainAppVPath.SimpleCombineWithDir(WebRefDirectoryName); }
        } 

 
        ///  
        ///    [To be supplied.]
        ///  
        public static bool IsOnUNCShare {
            [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)]
            get {
                return IsOnUNCShareInternal; 
            }
        } 
 
        internal static bool IsOnUNCShareInternal {
            get { return _theRuntime._isOnUNCShare; } 
        }


        // 
        //  Static helper to retrieve app domain values
        // 
 
        private static String GetAppDomainString(String key) {
            Object x = Thread.GetDomain().GetData(key); 

            return x as String;
        }
 
        internal static void AddAppDomainTraceMessage(String message) {
            const String appDomainTraceKey = "ASP.NET Domain Trace"; 
            AppDomain d = Thread.GetDomain(); 
            String m = d.GetData(appDomainTraceKey) as String;
            d.SetData(appDomainTraceKey, (m != null) ? m + " ... " + message : message); 
        }


        // 
        //  Flags
        // 
 
        internal static bool DebuggingEnabled {
            get { return _theRuntime._debuggingEnabled; } 
        }

        internal static bool ConfigInited {
            get { return _theRuntime._configInited; } 
        }
 
        internal static bool FusionInited { 
            get { return _theRuntime._fusionInited; }
        } 

        internal static bool ApartmentThreading {
            get { return _theRuntime._apartmentThreading; }
        } 

        internal static bool ShutdownInProgress { 
            get { return _theRuntime._shutdownInProgress; } 
        }
 
        internal static string TrustLevel {
            get { return _theRuntime._trustLevel; }
        }
 
        internal static string WpUserId {
            get { return _theRuntime._wpUserId; } 
        } 

 
        private void SetTrustLevel(TrustSection trustSection, SecurityPolicySection securityPolicySection) {
            if (trustSection == null || String.IsNullOrEmpty(trustSection.Level)) {
                throw new ConfigurationErrorsException(SR.GetString(SR.Config_section_not_present, "trust"));
            } 

            // Use a temporary variable, since we use the field as a signal that the trust has really 
            // been set, which is not the case until later in this method. 
            string trustLevel = trustSection.Level;
 
            if (trustSection.Level == "Full") {
                _trustLevel = trustLevel;
                return;
            } 

            if (securityPolicySection == null || securityPolicySection.TrustLevels[trustSection.Level] == null) { 
                throw new ConfigurationErrorsException(SR.GetString(SR.Unable_to_get_policy_file, trustSection.Level), String.Empty, 0); 
                //             Do not give out configuration information since we don't know what trust level we are
                //             supposed to be running at.  If the information below is added to the error it might expose 
                //             part of the config file that the users does not have permissions to see. VS261145
                //            ,trustSection.ElementInformation.Properties["level"].Source,
                //            trustSection.ElementInformation.Properties["level"].LineNumber);
            } 
            String file = (String)securityPolicySection.TrustLevels[trustSection.Level].PolicyFileExpanded;
            if (file == null || !FileUtil.FileExists(file)) { 
                //if HttpContext.Current.IsCustomErrorEnabled 
                throw new HttpException(SR.GetString(SR.Unable_to_get_policy_file, trustSection.Level));
                //else 
                //    throw new ConfigurationErrorsException(SR.GetString(SR.Unable_to_get_policy_file, trustSection.Level),
                //        trustSection.Filename, trustSection.LineNumber);
            }
 
            bool foundGacToken = false;
            PolicyLevel policyLevel = CreatePolicyLevel(file, AppDomainAppPathInternal, CodegenDirInternal, trustSection.OriginUrl, out foundGacToken); 
 
            // see if the policy file contained a v1.x UrlMembershipCondition containing
            // a GAC token.  If so, let's upgrade it by adding a code group granting 
            // full trust to code from the GAC
            if (foundGacToken) {
                // walk the code groups at the app domain level and look for one that grants
                // access to the GAC with an UrlMembershipCondition. 
                CodeGroup rootGroup = policyLevel.RootCodeGroup;
                bool foundGacCondition = false; 
                foreach (CodeGroup childGroup in rootGroup.Children) { 
                    if (childGroup.MembershipCondition is GacMembershipCondition) {
                        foundGacCondition = true; 

                        // if we found the GAC token and also have the GacMembershipCondition
                        // the policy file needs to be upgraded to just include the GacMembershipCondition
                        Debug.Assert(!foundGacCondition); 
                        break;
                    } 
                } 

                // add one as a child of the toplevel group after 
                // some sanity checking to make sure it's an ASP.NET policy file
                // which always begins with a FirstMatchCodeGroup granting nothing
                // this might not upgrade some custom policy files
                if (!foundGacCondition) { 
                    if (rootGroup is FirstMatchCodeGroup) {
                        FirstMatchCodeGroup firstMatch = (FirstMatchCodeGroup)rootGroup; 
                        if (firstMatch.MembershipCondition is AllMembershipCondition && 
                           firstMatch.PermissionSetName == "Nothing") {
                            PermissionSet fullTrust = new PermissionSet(PermissionState.Unrestricted); 

                            CodeGroup gacGroup = new UnionCodeGroup(new GacMembershipCondition(),
                                                                    new PolicyStatement(fullTrust));
 

                            // now, walk the current groups and insert our new group 
                            // immediately before the old Gac group 
                            // we'll need to use heuristics for this:
                            // it will be an UrlMembershipCondition group with full trust 
                            CodeGroup newRoot = new FirstMatchCodeGroup(rootGroup.MembershipCondition, rootGroup.PolicyStatement);
                            foreach (CodeGroup childGroup in rootGroup.Children) {

                                // is this the target old $Gac$ group? 
                                // insert our new GacMembershipCondition group ahead of it
                                if ((childGroup is UnionCodeGroup) && 
                                   (childGroup.MembershipCondition is UrlMembershipCondition) && 
                                   childGroup.PolicyStatement.PermissionSet.IsUnrestricted()) {
                                    if (null != gacGroup) { 
                                        newRoot.AddChild(gacGroup);
                                        gacGroup = null;
                                    }
                                } 

                                // append this group to the root group 
                                // AddChild itself does a deep Copy to get any 
                                // child groups so we don't need one here
                                newRoot.AddChild(childGroup); 
                            }

                            policyLevel.RootCodeGroup = newRoot;
                            //Debug.Trace("internal", "PolicyLevel: " + policyLevel.ToXml()); 
                        }
                    } 
                } 
            }
 

            AppDomain.CurrentDomain.SetAppDomainPolicy(policyLevel);
            _namedPermissionSet = policyLevel.GetNamedPermissionSet("ASP.Net");
 
            _trustLevel = trustLevel;
 
            _fcm.StartMonitoringFile(file, new FileChangeEventHandler(this.OnSecurityPolicyFileChange)); 
        }
 
        private static PolicyLevel CreatePolicyLevel(String configFile, String appDir, String binDir, String strOriginUrl, out bool foundGacToken) {
            // Read in the config file to a string.
            FileStream file = new FileStream(configFile, FileMode.Open, FileAccess.Read);
            StreamReader reader = new StreamReader(file, Encoding.UTF8); 
            String strFileData = reader.ReadToEnd();
 
            reader.Close(); 

            appDir = FileUtil.RemoveTrailingDirectoryBackSlash(appDir); 
            binDir = FileUtil.RemoveTrailingDirectoryBackSlash(binDir);

            strFileData = strFileData.Replace("$AppDir$", appDir);
            strFileData = strFileData.Replace("$AppDirUrl$", MakeFileUrl(appDir)); 
            strFileData = strFileData.Replace("$CodeGen$", MakeFileUrl(binDir));
            if (strOriginUrl == null) 
                strOriginUrl = String.Empty; 
            strFileData = strFileData.Replace("$OriginHost$", strOriginUrl);
 
            // see if the file contains a GAC token
            // if so, do the replacement and record the
            // fact so that we later add a GacMembershipCondition
            // codegroup to the PolicyLevel 
            int ndx = strFileData.IndexOf("$Gac$", StringComparison.Ordinal);
            if (ndx != -1) { 
                string gacLocation = GetGacLocation(); 
                if (gacLocation != null)
                    gacLocation = MakeFileUrl(gacLocation); 
                if (gacLocation == null)
                    gacLocation = String.Empty;

                strFileData = strFileData.Replace("$Gac$", gacLocation); 
                foundGacToken = true;
            } 
            else { 
                foundGacToken = false;
            } 

            return SecurityManager.LoadPolicyLevelFromString(strFileData, PolicyLevelType.AppDomain);
        }
 
        /*
         * Notification when something in the code-access security policy file changed 
         */ 
        private void OnSecurityPolicyFileChange(Object sender, FileChangeEvent e) {
            // shutdown the app domain 
            Debug.Trace("AppDomainFactory", "Shutting down appdomain because code-access security policy file changed");
            ShutdownAppDomain(ApplicationShutdownReason.ChangeInSecurityPolicyFile,
                                "Change in code-access security policy file");
        } 

 
        // notification when app_offline.htm file changed or created 
        private void OnAppOfflineFileChange(Object sender, FileChangeEvent e) {
            // shutdown the app domain 
            Debug.Trace("AppOffline", AppOfflineFileName + " changed - shutting down the app domain");
            Debug.Trace("AppDomainFactory", "Shutting down appdomain because " + AppOfflineFileName + " file changed");
            // WOS 1948399: set _userForcedShutdown to avoid DelayNotificationTimeout, since first request has not completed yet in integrated mode;
            SetUserForcedShutdown(); 
            ShutdownAppDomain(ApplicationShutdownReason.ConfigurationChange, "Change in " + AppOfflineFileName);
        } 
 
        private static String MakeFileUrl(String path) {
            Uri uri = new Uri(path); 
            return uri.ToString();
        }

        private static String GetGacLocation() { 

            StringBuilder buf = new StringBuilder(262); 
            int iSize = 260; 

            // 

            if (UnsafeNativeMethods.GetCachePath(2, buf, ref iSize) >= 0)
                return buf.ToString();
            throw new HttpException(SR.GetString(SR.GetGacLocaltion_failed)); 
        }
 
 
        /*
         * Remove from metabase all read/write/browse permission from certain subdirs 
         *
         */
        internal static void RestrictIISFolders(HttpContext context) {
            int ret; 

            HttpWorkerRequest wr = context.WorkerRequest; 
 
            Debug.Assert(AppDomainAppIdInternal != null);
 
            // Don't do it if we are not running on IIS
            if (wr == null || !(wr is System.Web.Hosting.ISAPIWorkerRequest)) {
                return;
            } 

            // Do it only for IIS 5 
#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features 
            if (!(wr is System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6))
#endif // !FEATURE_PAL 
 {
                byte[] bufin;
                byte[] bufout = new byte[1];   // Just to keep EcbCallISAPI happy
 
                bufin = BitConverter.GetBytes(UnsafeNativeMethods.RESTRICT_BIN);
                ret = context.CallISAPI(UnsafeNativeMethods.CallISAPIFunc.RestrictIISFolders, bufin, bufout); 
                if (ret != 1) { 
                    // Cannot pass back any HR from inetinfo.exe because CSyncPipeManager::GetDataFromIIS
                    // does not support passing back any value when there is an error. 
                    Debug.Trace("RestrictIISFolders", "Cannot restrict folder access for '" + AppDomainAppIdInternal + "'.");
                }
            }
        } 

        // 
        // Helper to create instances (public vs. internal/private ctors, see 89781) 
        //
 
        internal static Object CreateNonPublicInstance(Type type) {
            return CreateNonPublicInstance(type, null);
        }
 
        internal static Object CreateNonPublicInstance(Type type, Object[] args) {
            return Activator.CreateInstance( 
                type, 
                BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.CreateInstance,
                null, 
                args,
                null);
        }
 
        internal static Object CreatePublicInstance(Type type) {
            return Activator.CreateInstance(type); 
        } 

#if !DONTUSEFACTORYGENERATOR 
        // Cache instances of IWebObjectFactory for each Type, which allow us
        // to instantiate the objects very efficiently, compared to calling
        // Activator.CreateInstance on every call.
        private static FactoryGenerator s_factoryGenerator; 
        private static Hashtable s_factoryCache;
        private static bool s_initializedFactory; 
        private static object s_factoryLock = new Object(); 

#endif // DONTUSEFACTORYGENERATOR 

        /*
         * Faster implementation of CreatePublicInstance.  It generates bits of IL
         * on the fly to achieve the improve performance.  this should only be used 
         * in cases where the number of different types to be created is well bounded.
         * Otherwise, we would create too much IL, which can bloat the process. 
         */ 
        internal static Object FastCreatePublicInstance(Type type) {
 
#if DONTUSEFACTORYGENERATOR
            return CreatePublicInstance(type);
#else
 
            // Only use the factory logic if the assembly is in the GAC, to avoid getting
            // assembly conflicts (VSWhidbey 405086) 
            if (!type.Assembly.GlobalAssemblyCache) { 
                return CreatePublicInstance(type);
            } 

            // Create the factory generator on demand
            if (!s_initializedFactory) {
 
                // Devdiv 90810 - Synchronize to avoid race condition
                lock (s_factoryLock) { 
                    if (!s_initializedFactory) { 
                        s_factoryGenerator = new FactoryGenerator();
 
                        // Create the factory cache
                        s_factoryCache = Hashtable.Synchronized(new Hashtable());

                        s_initializedFactory = true; 
                    }
                } 
            } 

            // First, check if it's cached 
            IWebObjectFactory factory = (IWebObjectFactory)s_factoryCache[type];

            if (factory == null) {
 
                Debug.Trace("FastCreatePublicInstance", "Creating generator for type " + type.FullName);
 
                // Create the object factory 
                factory = s_factoryGenerator.CreateFactory(type);
 
                // Cache the factory
                s_factoryCache[type] = factory;
            }
 
            return factory.CreateInstance();
#endif // DONTUSEFACTORYGENERATOR 
        } 

        internal static Object CreatePublicInstance(Type type, Object[] args) { 
            if (args == null)
                return Activator.CreateInstance(type);

            return Activator.CreateInstance(type, args); 
        }
 
        static string GetCurrentUserName() { 
            try {
                return WindowsIdentity.GetCurrent().Name; 
            }
            catch {
                return null;
            } 
        }
 
        void RaiseShutdownWebEventOnce() { 
            if (!_shutdownWebEventRaised) {
                lock (this) { 
                    if (!_shutdownWebEventRaised) {
                        // Raise Web Event
                        WebBaseEvent.RaiseSystemEvent(this, WebEventCodes.ApplicationShutdown,
                                WebApplicationLifetimeEvent.DetailCodeFromShutdownReason(ShutdownReason)); 

                        _shutdownWebEventRaised = true; 
                    } 
                }
            } 
        }
    }

 
    public enum ApplicationShutdownReason {
 
        None = 0, 

        HostingEnvironment = 1, 

        ChangeInGlobalAsax = 2,

        ConfigurationChange = 3, 

        UnloadAppDomainCalled = 4, 
 
        ChangeInSecurityPolicyFile = 5,
 
        BinDirChangeOrDirectoryRename = 6,

        BrowsersDirChangeOrDirectoryRename = 7,
 
        CodeDirChangeOrDirectoryRename = 8,
 
        ResourcesDirChangeOrDirectoryRename = 9, 

        IdleTimeout = 10, 

        PhysicalApplicationPathChanged = 11,

        HttpRuntimeClose = 12, 

        InitializationError = 13, 
 
        MaxRecompilationsReached = 14,
 
        BuildManagerChange = 15,
    };

 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

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