HttpApplication.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / HttpApplication.cs / 1305376 / HttpApplication.cs

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

namespace System.Web { 
    using System.Runtime.Serialization.Formatters; 
    using System.IO;
    using System.Threading; 
    using System.Runtime.InteropServices;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Collections; 
    using System.Reflection;
    using System.Globalization; 
    using System.Security.Principal; 
    using System.Web;
    using System.Web.SessionState; 
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.Util;
    using System.Web.Configuration; 
    using System.Web.Configuration.Common;
    using System.Web.Hosting; 
    using System.Web.Management; 
    using System.Runtime.Remoting.Messaging;
    using System.Security; 
    using System.Security.Permissions;
    using System.Collections.Generic;
    using System.Web.Compilation;
 
    using IIS = System.Web.Hosting.UnsafeIISMethods;
 
 
    //
    // Async EventHandler support 
    //


    ///  
    ///    [To be supplied.]
    ///  
    public delegate IAsyncResult BeginEventHandler(object sender, EventArgs e, AsyncCallback cb, object extraData); 

    ///  
    ///    [To be supplied.]
    /// 
    public delegate void EndEventHandler(IAsyncResult ar);
 

    ///  
    ///     
    ///       The  HttpApplication class defines the methods, properties and events common to all
    ///       HttpApplication objects within the ASP.NET Framework. 
    ///    
    /// 
    [
    ToolboxItem(false) 
    ]
    public class HttpApplication : IHttpAsyncHandler, IComponent { 
        // application state dictionary 
        private HttpApplicationState _state;
 
        // context during init for config lookups
        private HttpContext _initContext;

        // async support 
        private HttpAsyncResult _ar; // currently pending async result for call into application
 
        // list of modules 
        private HttpModuleCollection  _moduleCollection;
 
        // event handlers
        private static readonly object EventDisposed = new object();
        private static readonly object EventErrorRecorded = new object();
        private static readonly object EventPreSendRequestHeaders = new object(); 
        private static readonly object EventPreSendRequestContent = new object();
 
        private static readonly object EventBeginRequest = new object(); 
        private static readonly object EventAuthenticateRequest = new object();
        private static readonly object EventDefaultAuthentication = new object(); 
        private static readonly object EventPostAuthenticateRequest = new object();
        private static readonly object EventAuthorizeRequest = new object();
        private static readonly object EventPostAuthorizeRequest = new object();
        private static readonly object EventResolveRequestCache = new object(); 
        private static readonly object EventPostResolveRequestCache = new object();
        private static readonly object EventMapRequestHandler = new object(); 
        private static readonly object EventPostMapRequestHandler = new object(); 
        private static readonly object EventAcquireRequestState = new object();
        private static readonly object EventPostAcquireRequestState = new object(); 
        private static readonly object EventPreRequestHandlerExecute = new object();
        private static readonly object EventPostRequestHandlerExecute = new object();
        private static readonly object EventReleaseRequestState = new object();
        private static readonly object EventPostReleaseRequestState = new object(); 
        private static readonly object EventUpdateRequestCache = new object();
        private static readonly object EventPostUpdateRequestCache = new object(); 
        private static readonly object EventLogRequest = new object(); 
        private static readonly object EventPostLogRequest = new object();
        private static readonly object EventEndRequest = new object(); 
        internal static readonly string AutoCulture = "auto";

        private EventHandlerList _events;
        private AsyncAppEventHandlersTable _asyncEvents; 

        // execution steps 
        private StepManager _stepManager; 

        // callback for Application ResumeSteps 
        #pragma warning disable 0649
        private WaitCallback _resumeStepsWaitCallback;
        #pragma warning restore 0649
 
        // event passed to modules
        private EventArgs _appEvent; 
 
        // list of handler mappings
        private Hashtable _handlerFactories = new Hashtable(); 

        // list of handler/factory pairs to be recycled
        private ArrayList _handlerRecycleList;
 
        // flag to hide request and response intrinsics
        private bool _hideRequestResponse; 
 
        // application execution variables
        private HttpContext _context; 
        private Exception _lastError;  // placeholder for the error when context not avail
        private bool _timeoutManagerInitialized;

        // session (supplied by session-on-end outside of context) 
        private HttpSessionState _session;
 
        // culture (needs to be set per thread) 
        private CultureInfo _appLevelCulture;
        private CultureInfo _appLevelUICulture; 
        private CultureInfo _savedAppLevelCulture;
        private CultureInfo _savedAppLevelUICulture;
        private bool _appLevelAutoCulture;
        private bool _appLevelAutoUICulture; 

        // pipeline event mappings 
        private Dictionary _pipelineEventMasks; 

 
        // IComponent support
        private ISite _site;

        // IIS7 specific fields 
        internal const string MANAGED_PRECONDITION = "managedHandler";
        internal const string IMPLICIT_FILTER_MODULE = "AspNetFilterModule"; 
        internal const string IMPLICIT_HANDLER = "ManagedPipelineHandler"; 

        // map modules to their index 
        private static Hashtable _moduleIndexMap = new Hashtable();
        private static bool _initSpecialCompleted;

        private bool _initInternalCompleted; 
        private RequestNotification _appRequestNotifications;
        private RequestNotification _appPostNotifications; 
 
        // Set the current module init key to the global.asax module to enable
        // the custom global.asax derivation constructor to register event handlers 
        private string _currentModuleCollectionKey = HttpApplicationFactory.applicationFileName;

        // module config is read once per app domain and used to initialize the per-instance _moduleContainers array
        private static List _moduleConfigInfo; 

        // this is the per instance list that contains the events for each module 
        private PipelineModuleStepContainer[] _moduleContainers; 

        // Byte array to be used by HttpRequest.GetEntireRawContent. Windows OS Bug 1632921 
        private byte[] _entityBuffer;

        //
        // Public Application properties 
        //
 
 
        /// 
        ///     
        ///          HTTPRuntime provided context object that provides access to additional
        ///          pipeline-module exposed objects.
        ///       
        ///     
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public HttpContext Context { 
            get {
                return(_context != null) ? _context : _initContext;
            }
        } 

        private bool IsContainerInitalizationAllowed { 
            get { 
                if (HttpRuntime.UseIntegratedPipeline && _initSpecialCompleted && !_initInternalCompleted) {
                    // return true if 
                    //      i) this is integrated pipeline mode,
                    //     ii) InitSpecial has been called at least once in this AppDomain to register events with IIS,
                    //    iii) InitInternal has not been invoked yet or is currently executing
                    return true; 
                }
                return false; 
            } 
        }
 
        private void ThrowIfEventBindingDisallowed() {
            if (HttpRuntime.UseIntegratedPipeline && _initSpecialCompleted && _initInternalCompleted) {
                // throw if we're using the integrated pipeline and both InitSpecial and InitInternal have completed.
                throw new InvalidOperationException(SR.GetString(SR.Event_Binding_Disallowed)); 
            }
        } 
 
        private PipelineModuleStepContainer[] ModuleContainers {
            get { 
                if (_moduleContainers == null) {

                    Debug.Assert(_moduleIndexMap != null && _moduleIndexMap.Count > 0, "_moduleIndexMap != null && _moduleIndexMap.Count > 0");
 
                    // At this point, all modules have been registered with IIS via RegisterIntegratedEvent.
                    // Now we need to create a container for each module and add execution steps. 
                    // The number of containers is the same as the number of modules that have been 
                    // registered (_moduleIndexMap.Count).
 
                    _moduleContainers = new PipelineModuleStepContainer[_moduleIndexMap.Count];

                    for (int i = 0; i < _moduleContainers.Length; i++) {
                        _moduleContainers[i] = new PipelineModuleStepContainer(); 
                    }
 
                } 

                return _moduleContainers; 
            }
        }

        ///  
        ///    [To be supplied.]
        ///  
        public event EventHandler Disposed { 
            add {
                Events.AddHandler(EventDisposed, value); 
            }

            remove {
                Events.RemoveHandler(EventDisposed, value); 
            }
        } 
 

        ///  
        ///    [To be supplied.]
        /// 
        protected EventHandlerList Events {
            get { 
                if (_events == null) {
                    _events = new EventHandlerList(); 
                } 
                return _events;
            } 
        }

        private AsyncAppEventHandlersTable AsyncEvents {
            get { 
                if (_asyncEvents == null)
                    _asyncEvents = new AsyncAppEventHandlersTable(); 
                return _asyncEvents; 
            }
        } 

        // Last error during the processing of the current request.
        internal Exception LastError {
            get { 
                // only temporaraly public (will be internal and not related context)
                return (_context != null) ? _context.Error : _lastError; 
            } 

        } 

        // Used by HttpRequest.GetEntireRawContent. Windows OS Bug 1632921
        internal byte[] EntityBuffer
        { 
            get
            { 
                if (_entityBuffer == null) 
                {
                    _entityBuffer = new byte[8 * 1024]; 
                }
                return _entityBuffer;
            }
        } 

        internal void ClearError() { 
            _lastError = null; 
        }
 
        /// 
        ///    HTTPRuntime provided request intrinsic object that provides access to incoming HTTP
        ///       request data.
        ///  
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public HttpRequest Request { 
            get {
                HttpRequest request = null;

                if (_context != null && !_hideRequestResponse) 
                    request = _context.Request;
 
                if (request == null) 
                    throw new HttpException(SR.GetString(SR.Request_not_available));
 
                return request;
            }
        }
 

        ///  
        ///    HTTPRuntime provided 
        ///       response intrinsic object that allows transmission of HTTP response data to a
        ///       client. 
        /// 
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public HttpResponse Response { 
            get { 
                HttpResponse response = null;
 
                if (_context != null && !_hideRequestResponse)
                    response = _context.Response;

                if (response == null) 
                    throw new HttpException(SR.GetString(SR.Response_not_available));
 
                return response; 
            }
        } 


        /// 
        ///     
        ///    HTTPRuntime provided session intrinsic.
        ///     
        ///  
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public HttpSessionState Session {
            get { 
                HttpSessionState session = null;
 
                if (_session != null) 
                    session = _session;
                else if (_context != null) 
                    session = _context.Session;

                if (session == null)
                    throw new HttpException(SR.GetString(SR.Session_not_available)); 

                return session; 
            } 
        }
 

        /// 
        ///    
        ///       Returns 
        ///          a reference to an HTTPApplication state bag instance.
        ///        
        ///     
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public HttpApplicationState Application {
            get { 
                Debug.Assert(_state != null);  // app state always available
                return _state; 
            } 
        }
 

        /// 
        ///    Provides the web server Intrinsic object.
        ///  
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public HttpServerUtility Server { 
            get {
                if (_context != null)
                    return _context.Server;
                else 
                    return new HttpServerUtility(this); // special Server for application only
            } 
        } 

 
        /// 
        ///    Provides the User Intrinsic object.
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ] 
        public IPrincipal User {
            get { 
                if (_context == null)
                    throw new HttpException(SR.GetString(SR.User_not_available));

                return _context.User; 
            }
        } 
 

        ///  
        ///    
        ///       Collection
        ///          of all IHTTPModules configured for the current application.
        ///        
        ///    
        [ 
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public HttpModuleCollection Modules {
            [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.High)]
            get {
                if (_moduleCollection == null) 
                    _moduleCollection = new HttpModuleCollection();
                return _moduleCollection; 
            } 
        }
 
        // event passed to all modules
        internal EventArgs AppEvent {
            get {
                if (_appEvent == null) 
                    _appEvent = EventArgs.Empty;
 
                return _appEvent; 
            }
 
            set {
                _appEvent = null;
            }
        } 

        // DevDiv Bugs 151914: Release session state before executing child request 
        internal void EnsureReleaseState() { 
            if (_moduleCollection != null) {
                for (int i = 0; i < _moduleCollection.Count; i++) { 
                    IHttpModule module = _moduleCollection.Get(i);
                    if (module is SessionStateModule) {
                        ((SessionStateModule) module).EnsureReleaseState(this);
                        break; 
                    }
                } 
            } 
        }
 
        /// 
        ///    [To be supplied.]
        /// 
        public void CompleteRequest() { 
            //
            // Request completion (force skipping all steps until RequestEnd 
            // 
            _stepManager.CompleteRequest();
        } 

        internal bool IsRequestCompleted {
            get {
                if (null == _stepManager) { 
                    return false;
                } 
 
                return _stepManager.IsCompleted;
            } 
        }

        // Dev10 745301: Asynchronous pipeline steps can start a new thread that triggers
        // a SendResponse notification.  E.g., it might call Flush when a module is registered 
        // for PreSendRequestHeaders/Content.  If the async pipeline step returns from ExecuteStep
        // while the SendResponse notification is executing, the NotificationContext can 
        // be corrupted.  To fix this, a lock is now taken to prevent multi-threaded access when 
        // the async pipeline step sets the NotificationContext.PendingAsyncCompletion field.
        // The SendResponse notification also acquires the lock when it enters managed code and 
        // releases the lock when it leaves.
        internal void AcquireNotifcationContextLock(ref bool locked) {
            Debug.Assert(HttpRuntime.UseIntegratedPipeline, "HttpRuntime.UseIntegratedPipeline");
            Monitor.Enter(_stepManager, ref locked); 
        }
 
        internal void ReleaseNotifcationContextLock() { 
            Debug.Assert(HttpRuntime.UseIntegratedPipeline, "HttpRuntime.UseIntegratedPipeline");
            Monitor.Exit(_stepManager); 
        }

        private void RaiseOnError() {
            EventHandler handler = (EventHandler)Events[EventErrorRecorded]; 
            if (handler != null) {
                try { 
                    handler(this, AppEvent); 
                }
                catch (Exception e) { 
                    if (_context != null) {
                        _context.AddError(e);
                    }
                } 
            }
        } 
 
        internal void RaiseOnPreSendRequestHeaders() {
            EventHandler handler = (EventHandler)Events[EventPreSendRequestHeaders]; 
            if (handler != null) {
                try {
                    handler(this, AppEvent);
                } 
                catch (Exception e) {
                    RecordError(e); 
                } 
            }
        } 

        internal void RaiseOnPreSendRequestContent() {
            EventHandler handler = (EventHandler)Events[EventPreSendRequestContent];
            if (handler != null) { 
                try {
                    handler(this, AppEvent); 
                } 
                catch (Exception e) {
                    RecordError(e); 
                }
            }
        }
 
        internal HttpAsyncResult AsyncResult {
            get { 
                if (HttpRuntime.UseIntegratedPipeline) { 
                    return (_context.NotificationContext != null) ? _context.NotificationContext.AsyncResult : null;
                } 
                else {
                    return _ar;
                }
            } 
            set {
                if (HttpRuntime.UseIntegratedPipeline) { 
                    _context.NotificationContext.AsyncResult = value; 
                }
                else { 
                    _ar = value;
                }
            }
        } 

        internal void AddSyncEventHookup(object key, Delegate handler, RequestNotification notification) { 
            AddSyncEventHookup(key, handler, notification, false); 
        }
 
        private PipelineModuleStepContainer CurrentModuleContainer { get { return ModuleContainers[_context.CurrentModuleIndex]; } }

        private PipelineModuleStepContainer GetModuleContainer(string moduleName) {
            object value = _moduleIndexMap[moduleName]; 

            if (value == null) { 
                return null; 
            }
 
            int moduleIndex = (int)value;

#if DBG
            Debug.Trace("PipelineRuntime", "GetModuleContainer: moduleName=" + moduleName + ", index=" + moduleIndex.ToString(CultureInfo.InvariantCulture) + "\r\n"); 
            Debug.Assert(moduleIndex >= 0 && moduleIndex < ModuleContainers.Length, "moduleIndex >= 0 && moduleIndex < ModuleContainers.Length");
#endif 
 
            PipelineModuleStepContainer container = ModuleContainers[moduleIndex];
 
            Debug.Assert(container != null, "container != null");

            return container;
        } 

        private void AddSyncEventHookup(object key, Delegate handler, RequestNotification notification, bool isPostNotification) { 
            ThrowIfEventBindingDisallowed(); 

            // add the event to the delegate invocation list 
            // this keeps non-pipeline ASP.NET hosts working
            Events.AddHandler(key, handler);

            // For integrated pipeline mode, add events to the IExecutionStep containers only if 
            // InitSpecial has completed and InitInternal has not completed.
            if (IsContainerInitalizationAllowed) { 
                // lookup the module index and add this notification 
                PipelineModuleStepContainer container = GetModuleContainer(CurrentModuleCollectionKey);
                //WOS 1985878: HttpModule unsubscribing an event handler causes AV in Integrated Mode 
                if (container != null) {
#if DBG
                    container.DebugModuleName = CurrentModuleCollectionKey;
#endif 
                    SyncEventExecutionStep step = new SyncEventExecutionStep(this, (EventHandler)handler);
                    container.AddEvent(notification, isPostNotification, step); 
                } 
            }
        } 

        internal void RemoveSyncEventHookup(object key, Delegate handler, RequestNotification notification) {
            RemoveSyncEventHookup(key, handler, notification, false);
        } 

        internal void RemoveSyncEventHookup(object key, Delegate handler, RequestNotification notification, bool isPostNotification) { 
            ThrowIfEventBindingDisallowed(); 

            Events.RemoveHandler(key, handler); 

            if (IsContainerInitalizationAllowed) {
                PipelineModuleStepContainer container = GetModuleContainer(CurrentModuleCollectionKey);
                //WOS 1985878: HttpModule unsubscribing an event handler causes AV in Integrated Mode 
                if (container != null) {
                    container.RemoveEvent(notification, isPostNotification, handler); 
                } 
            }
        } 

        private void AddSendResponseEventHookup(object key, Delegate handler) {
            ThrowIfEventBindingDisallowed();
 
            // add the event to the delegate invocation list
            // this keeps non-pipeline ASP.NET hosts working 
            Events.AddHandler(key, handler); 

            // For integrated pipeline mode, add events to the IExecutionStep containers only if 
            // InitSpecial has completed and InitInternal has not completed.
            if (IsContainerInitalizationAllowed) {
                // lookup the module index and add this notification
                PipelineModuleStepContainer container = GetModuleContainer(CurrentModuleCollectionKey); 
                //WOS 1985878: HttpModule unsubscribing an event handler causes AV in Integrated Mode
                if (container != null) { 
#if DBG 
                    container.DebugModuleName = CurrentModuleCollectionKey;
#endif 
                    bool isHeaders = (key == EventPreSendRequestHeaders);
                    SendResponseExecutionStep step = new SendResponseExecutionStep(this, (EventHandler)handler, isHeaders);
                    container.AddEvent(RequestNotification.SendResponse, false /*isPostNotification*/, step);
                } 
            }
        } 
 
        private void RemoveSendResponseEventHookup(object key, Delegate handler) {
            ThrowIfEventBindingDisallowed(); 

            Events.RemoveHandler(key, handler);

            if (IsContainerInitalizationAllowed) { 
                PipelineModuleStepContainer container = GetModuleContainer(CurrentModuleCollectionKey);
                //WOS 1985878: HttpModule unsubscribing an event handler causes AV in Integrated Mode 
                if (container != null) { 
                    container.RemoveEvent(RequestNotification.SendResponse, false /*isPostNotification*/, handler);
                } 
            }
        }

        // 
        // [....] event hookup
        // 
 

        /// [To be supplied.] 
        public event EventHandler BeginRequest {
            add { AddSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); }
            remove { RemoveSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); }
        } 

 
        /// [To be supplied.] 
        public event EventHandler AuthenticateRequest {
            add { AddSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); } 
            remove { RemoveSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); }
        }

        // internal - for back-stop module only 
        internal event EventHandler DefaultAuthentication {
            add { AddSyncEventHookup(EventDefaultAuthentication, value, RequestNotification.AuthenticateRequest); } 
            remove { RemoveSyncEventHookup(EventDefaultAuthentication, value, RequestNotification.AuthenticateRequest); } 
        }
 

        /// [To be supplied.]
        public event EventHandler PostAuthenticateRequest {
            add { AddSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); } 
            remove { RemoveSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); }
        } 
 

        /// [To be supplied.] 
        public event EventHandler AuthorizeRequest {
            add { AddSyncEventHookup(EventAuthorizeRequest, value, RequestNotification.AuthorizeRequest); }
            remove { RemoveSyncEventHookup(EventAuthorizeRequest, value, RequestNotification.AuthorizeRequest); }
        } 

 
        /// [To be supplied.] 
        public event EventHandler PostAuthorizeRequest {
            add { AddSyncEventHookup(EventPostAuthorizeRequest, value, RequestNotification.AuthorizeRequest, true); } 
            remove { RemoveSyncEventHookup(EventPostAuthorizeRequest, value, RequestNotification.AuthorizeRequest, true); }
        }

 
        /// [To be supplied.]
        public event EventHandler ResolveRequestCache { 
            add { AddSyncEventHookup(EventResolveRequestCache, value, RequestNotification.ResolveRequestCache); } 
            remove { RemoveSyncEventHookup(EventResolveRequestCache, value, RequestNotification.ResolveRequestCache); }
        } 


        /// [To be supplied.]
        public event EventHandler PostResolveRequestCache { 
            add { AddSyncEventHookup(EventPostResolveRequestCache, value, RequestNotification.ResolveRequestCache, true); }
            remove { RemoveSyncEventHookup(EventPostResolveRequestCache, value, RequestNotification.ResolveRequestCache, true); } 
        } 

        public event EventHandler MapRequestHandler { 
            add {
                if (!HttpRuntime.UseIntegratedPipeline) {
                    throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode));
                } 
                AddSyncEventHookup(EventMapRequestHandler, value, RequestNotification.MapRequestHandler);
            } 
            remove { 
                if (!HttpRuntime.UseIntegratedPipeline) {
                    throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
                }
                RemoveSyncEventHookup(EventMapRequestHandler, value, RequestNotification.MapRequestHandler);
            }
        } 

        /// [To be supplied.] 
        public event EventHandler PostMapRequestHandler { 
            add { AddSyncEventHookup(EventPostMapRequestHandler, value, RequestNotification.MapRequestHandler, true); }
            remove { RemoveSyncEventHookup(EventPostMapRequestHandler, value, RequestNotification.MapRequestHandler); } 
        }


        /// [To be supplied.] 
        public event EventHandler AcquireRequestState {
            add { AddSyncEventHookup(EventAcquireRequestState, value, RequestNotification.AcquireRequestState); } 
            remove { RemoveSyncEventHookup(EventAcquireRequestState, value, RequestNotification.AcquireRequestState); } 
        }
 

        /// [To be supplied.]
        public event EventHandler PostAcquireRequestState {
            add { AddSyncEventHookup(EventPostAcquireRequestState, value, RequestNotification.AcquireRequestState, true); } 
            remove { RemoveSyncEventHookup(EventPostAcquireRequestState, value, RequestNotification.AcquireRequestState, true); }
        } 
 

        /// [To be supplied.] 
        public event EventHandler PreRequestHandlerExecute {
            add { AddSyncEventHookup(EventPreRequestHandlerExecute, value, RequestNotification.PreExecuteRequestHandler); }
            remove { RemoveSyncEventHookup(EventPreRequestHandlerExecute, value, RequestNotification.PreExecuteRequestHandler); }
        } 

        /// [To be supplied.] 
        public event EventHandler PostRequestHandlerExecute { 
            add { AddSyncEventHookup(EventPostRequestHandlerExecute, value, RequestNotification.ExecuteRequestHandler, true); }
            remove { RemoveSyncEventHookup(EventPostRequestHandlerExecute, value, RequestNotification.ExecuteRequestHandler, true); } 
        }


        /// [To be supplied.] 
        public event EventHandler ReleaseRequestState {
            add { AddSyncEventHookup(EventReleaseRequestState, value, RequestNotification.ReleaseRequestState ); } 
            remove { RemoveSyncEventHookup(EventReleaseRequestState, value, RequestNotification.ReleaseRequestState); } 
        }
 

        /// [To be supplied.]
        public event EventHandler PostReleaseRequestState {
            add { AddSyncEventHookup(EventPostReleaseRequestState, value, RequestNotification.ReleaseRequestState, true); } 
            remove { RemoveSyncEventHookup(EventPostReleaseRequestState, value, RequestNotification.ReleaseRequestState, true); }
        } 
 

        /// [To be supplied.] 
        public event EventHandler UpdateRequestCache {
            add { AddSyncEventHookup(EventUpdateRequestCache, value, RequestNotification.UpdateRequestCache); }
            remove { RemoveSyncEventHookup(EventUpdateRequestCache, value, RequestNotification.UpdateRequestCache); }
        } 

 
        /// [To be supplied.] 
        public event EventHandler PostUpdateRequestCache {
            add { AddSyncEventHookup(EventPostUpdateRequestCache, value, RequestNotification.UpdateRequestCache, true); } 
            remove { RemoveSyncEventHookup(EventPostUpdateRequestCache, value, RequestNotification.UpdateRequestCache, true); }
        }

        public event EventHandler LogRequest { 
            add {
                if (!HttpRuntime.UseIntegratedPipeline) { 
                    throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
                }
                AddSyncEventHookup(EventLogRequest, value, RequestNotification.LogRequest); 
            }
            remove {
                if (!HttpRuntime.UseIntegratedPipeline) {
                    throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
                }
                RemoveSyncEventHookup(EventLogRequest, value, RequestNotification.LogRequest); 
            } 
        }
 
        public event EventHandler PostLogRequest {
            add {
                if (!HttpRuntime.UseIntegratedPipeline) {
                    throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
                }
                AddSyncEventHookup(EventPostLogRequest, value, RequestNotification.LogRequest, true); 
            } 
            remove {
                if (!HttpRuntime.UseIntegratedPipeline) { 
                    throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode));
                }
                RemoveSyncEventHookup(EventPostLogRequest, value, RequestNotification.LogRequest, true);
            } 
        }
 
        /// [To be supplied.] 
        public event EventHandler EndRequest {
            add { AddSyncEventHookup(EventEndRequest, value, RequestNotification.EndRequest); } 
            remove { RemoveSyncEventHookup(EventEndRequest, value, RequestNotification.EndRequest); }
        }

 
        /// [To be supplied.]
        public event EventHandler Error { 
            add { Events.AddHandler(EventErrorRecorded, value); } 
            remove { Events.RemoveHandler(EventErrorRecorded, value); }
        } 


        /// [To be supplied.]
        public event EventHandler PreSendRequestHeaders { 
            add { AddSendResponseEventHookup(EventPreSendRequestHeaders, value); }
            remove { RemoveSendResponseEventHookup(EventPreSendRequestHeaders, value); } 
        } 

 
        /// [To be supplied.]
        public event EventHandler PreSendRequestContent {
            add { AddSendResponseEventHookup(EventPreSendRequestContent, value); }
            remove { RemoveSendResponseEventHookup(EventPreSendRequestContent, value); } 
        }
 
        // 
        // Async event hookup
        // 

        public void AddOnBeginRequestAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnBeginRequestAsync(bh, eh, null);
        } 

        public void AddOnBeginRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) { 
            AsyncEvents.AddHandler(EventBeginRequest, beginHandler, endHandler, state, RequestNotification.BeginRequest, false, this); 
        }
 
        public void AddOnAuthenticateRequestAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnAuthenticateRequestAsync(bh, eh, null);
        }
 
        public void AddOnAuthenticateRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventAuthenticateRequest, beginHandler, endHandler, state, 
                                   RequestNotification.AuthenticateRequest, false, this); 
        }
 
        public void AddOnPostAuthenticateRequestAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnPostAuthenticateRequestAsync(bh, eh, null);
        }
 
        public void AddOnPostAuthenticateRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostAuthenticateRequest, beginHandler, endHandler, state, 
                                   RequestNotification.AuthenticateRequest, true, this); 
        }
 
        public void AddOnAuthorizeRequestAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnAuthorizeRequestAsync(bh, eh, null);
        }
 
        public void AddOnAuthorizeRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventAuthorizeRequest, beginHandler, endHandler, state, 
                                   RequestNotification.AuthorizeRequest, false, this); 
        }
 
        public void AddOnPostAuthorizeRequestAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnPostAuthorizeRequestAsync(bh, eh, null);
        }
 
        public void AddOnPostAuthorizeRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostAuthorizeRequest, beginHandler, endHandler, state, 
                                   RequestNotification.AuthorizeRequest, true, this); 
        }
 
        public void AddOnResolveRequestCacheAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnResolveRequestCacheAsync(bh, eh, null);
        }
 
        public void AddOnResolveRequestCacheAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventResolveRequestCache, beginHandler, endHandler, state, 
                                   RequestNotification.ResolveRequestCache, false, this); 
        }
 
        public void AddOnPostResolveRequestCacheAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnPostResolveRequestCacheAsync(bh, eh, null);
        }
 
        public void AddOnPostResolveRequestCacheAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostResolveRequestCache, beginHandler, endHandler, state, 
                                   RequestNotification.ResolveRequestCache, true, this); 
        }
 
        public void AddOnMapRequestHandlerAsync(BeginEventHandler bh, EndEventHandler eh) {
            if (!HttpRuntime.UseIntegratedPipeline) {
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode));
            } 
            AddOnMapRequestHandlerAsync(bh, eh, null);
        } 
 
        public void AddOnMapRequestHandlerAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            if (!HttpRuntime.UseIntegratedPipeline) { 
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode));
            }
            AsyncEvents.AddHandler(EventMapRequestHandler, beginHandler, endHandler, state,
                                   RequestNotification.MapRequestHandler, false, this); 
        }
 
        public void AddOnPostMapRequestHandlerAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnPostMapRequestHandlerAsync(bh, eh, null);
        } 

        public void AddOnPostMapRequestHandlerAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostMapRequestHandler, beginHandler, endHandler, state,
                                   RequestNotification.MapRequestHandler, true, this); 
        }
 
        public void AddOnAcquireRequestStateAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnAcquireRequestStateAsync(bh, eh, null);
        } 

        public void AddOnAcquireRequestStateAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventAcquireRequestState, beginHandler, endHandler, state,
                                   RequestNotification.AcquireRequestState, false, this); 
        }
 
        public void AddOnPostAcquireRequestStateAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnPostAcquireRequestStateAsync(bh, eh, null);
        } 

        public void AddOnPostAcquireRequestStateAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostAcquireRequestState, beginHandler, endHandler, state,
                                   RequestNotification.AcquireRequestState, true, this); 
        }
 
        public void AddOnPreRequestHandlerExecuteAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnPreRequestHandlerExecuteAsync(bh, eh, null);
        } 

        public void AddOnPreRequestHandlerExecuteAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPreRequestHandlerExecute, beginHandler, endHandler, state,
                                   RequestNotification.PreExecuteRequestHandler, false, this); 
        }
 
        public void AddOnPostRequestHandlerExecuteAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnPostRequestHandlerExecuteAsync(bh, eh, null);
        } 

        public void AddOnPostRequestHandlerExecuteAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostRequestHandlerExecute, beginHandler, endHandler, state,
                                   RequestNotification.ExecuteRequestHandler, true, this); 
        }
 
        public void AddOnReleaseRequestStateAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnReleaseRequestStateAsync(bh, eh, null);
        } 

        public void AddOnReleaseRequestStateAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventReleaseRequestState, beginHandler, endHandler, state,
                                   RequestNotification.ReleaseRequestState, false, this); 
        }
 
        public void AddOnPostReleaseRequestStateAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnPostReleaseRequestStateAsync(bh, eh, null);
        } 

        public void AddOnPostReleaseRequestStateAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostReleaseRequestState, beginHandler, endHandler, state,
                                   RequestNotification.ReleaseRequestState, true, this); 
        }
 
        public void AddOnUpdateRequestCacheAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnUpdateRequestCacheAsync(bh, eh, null);
        } 

        public void AddOnUpdateRequestCacheAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventUpdateRequestCache, beginHandler, endHandler, state,
                                   RequestNotification.UpdateRequestCache , false, this); 
        }
 
        public void AddOnPostUpdateRequestCacheAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnPostUpdateRequestCacheAsync(bh, eh, null);
        } 

        public void AddOnPostUpdateRequestCacheAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostUpdateRequestCache, beginHandler, endHandler, state,
                                   RequestNotification.UpdateRequestCache , true, this); 
        }
 
        public void AddOnLogRequestAsync(BeginEventHandler bh, EndEventHandler eh) { 
            if (!HttpRuntime.UseIntegratedPipeline) {
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
            }
            AddOnLogRequestAsync(bh, eh, null);
        }
 
        public void AddOnLogRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            if (!HttpRuntime.UseIntegratedPipeline) { 
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
            }
            AsyncEvents.AddHandler(EventLogRequest, beginHandler, endHandler, state, 
                                   RequestNotification.LogRequest, false, this);
        }

        public void AddOnPostLogRequestAsync(BeginEventHandler bh, EndEventHandler eh) { 
            if (!HttpRuntime.UseIntegratedPipeline) {
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
            } 
            AddOnPostLogRequestAsync(bh, eh, null);
        } 

        public void AddOnPostLogRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            if (!HttpRuntime.UseIntegratedPipeline) {
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
            }
            AsyncEvents.AddHandler(EventPostLogRequest, beginHandler, endHandler, state, 
                                   RequestNotification.LogRequest, true, this); 
        }
 
        public void AddOnEndRequestAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnEndRequestAsync(bh, eh, null);
        }
 
        public void AddOnEndRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventEndRequest, beginHandler, endHandler, state, 
                                   RequestNotification.EndRequest, false, this); 
        }
 
        //
        // Public Application virtual methods
        //
 

        ///  
        ///     
        ///       Used
        ///          to initialize a HttpModule?s instance variables, and to wireup event handlers to 
        ///          the hosting HttpApplication.
        ///       
        ///    
        public virtual void Init() { 
            // derived class implements this
        } 
 

        ///  
        ///    
        ///       Used
        ///          to clean up an HttpModule?s instance variables
        ///        
        ///    
        public virtual void Dispose() { 
            // also part of IComponent 
            // derived class implements this
            _site = null; 
            if (_events != null) {
                try {
                    EventHandler handler = (EventHandler)_events[EventDisposed];
                    if (handler != null) 
                        handler(this, EventArgs.Empty);
                } 
                finally { 
                    _events.Dispose();
                } 
            }
        }

        [SecurityPermission(SecurityAction.Assert, ControlPrincipal = true)] 
        internal static void SetCurrentPrincipalWithAssert(IPrincipal user) {
            Thread.CurrentPrincipal = user; 
        } 

        [SecurityPermission(SecurityAction.Assert, ControlPrincipal = true)] 
        internal static WindowsIdentity GetCurrentWindowsIdentityWithAssert() {
            return WindowsIdentity.GetCurrent();
        }
 
        private HttpHandlerAction GetHandlerMapping(HttpContext context, String requestType, VirtualPath path, bool useAppConfig) {
            CachedPathData pathData = null; 
            HandlerMappingMemo memo = null; 
            HttpHandlerAction mapping = null;
 
            // Check if cached handler could be used
            if (!useAppConfig) {
                // Grab mapping from cache - verify that the verb matches exactly
                pathData = context.GetPathData(path); 
                memo = pathData.CachedHandler;
 
                // Invalidate cache on missmatch 
                if (memo != null && !memo.IsMatch(requestType, path)) {
                    memo = null; 
                }
            }

            // Get new mapping 
            if (memo == null) {
                // Load from config 
                HttpHandlersSection map = useAppConfig ? RuntimeConfig.GetAppConfig().HttpHandlers 
                                                       : RuntimeConfig.GetConfig(context).HttpHandlers;
                mapping = map.FindMapping(requestType, path); 

                // Add cache entry
                if (!useAppConfig) {
                    memo = new HandlerMappingMemo(mapping, requestType, path); 
                    pathData.CachedHandler = memo;
                } 
            } 
            else {
                // Get mapping from the cache 
                mapping = memo.Mapping;
            }

            return mapping; 
        }
 
        internal IHttpHandler MapIntegratedHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, bool useAppConfig, bool convertNativeStaticFileModule) { 
            IHttpHandler handler = null;
 
            using (new ApplicationImpersonationContext()) {
                string type;

                // vpath is a non-relative virtual path 
                string vpath = path.VirtualPathString;
 
                // If we're using app config, modify vpath by appending the path after the last slash 
                // to the app's virtual path.  This will force IIS IHttpContext::MapHandler to use app configuration.
                if (useAppConfig) { 
                    int index = vpath.LastIndexOf('/');
                    index++;
                    if (index != 0 && index < vpath.Length) {
                        vpath = UrlPath.SimpleCombine(HttpRuntime.AppDomainAppVirtualPathString, vpath.Substring(index)); 
                    }
                    else { 
                        vpath = HttpRuntime.AppDomainAppVirtualPathString; 
                    }
                } 


                IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest;
                type = wr.MapHandlerAndGetHandlerTypeString(requestType /*method*/, vpath, convertNativeStaticFileModule); 

                // If a page developer has removed the default mappings with  
                // without replacing them then we need to give a more descriptive error than 
                // a null parameter exception.
                if (type == null) { 
                    PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_FOUND);
                    PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_FAILED);
                    throw new HttpException(SR.GetString(SR.Http_handler_not_found_for_request_type, requestType));
                } 

                // if it's a native type, don't go any further 
                if(String.IsNullOrEmpty(type)) { 
                    return handler;
                } 

                // Get factory from the mapping
                IHttpHandlerFactory factory = GetFactory(type);
 
                try {
                    handler = factory.GetHandler(context, requestType, path.VirtualPathString, pathTranslated); 
                } 
                catch (FileNotFoundException e) {
                    if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) 
                        throw new HttpException(404, null, e);
                    else
                        throw new HttpException(404, null);
                } 
                catch (DirectoryNotFoundException e) {
                    if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) 
                        throw new HttpException(404, null, e); 
                    else
                        throw new HttpException(404, null); 
                }
                catch (PathTooLongException e) {
                    if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                        throw new HttpException(414, null, e); 
                    else
                        throw new HttpException(414, null); 
                } 

                // Remember for recycling 
                if (_handlerRecycleList == null)
                    _handlerRecycleList = new ArrayList();
                _handlerRecycleList.Add(new HandlerWithFactory(handler, factory));
            } 

            return handler; 
        } 

        internal IHttpHandler MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, bool useAppConfig) { 
            // Don't use remap handler when HttpServerUtility.Execute called
            IHttpHandler handler = (context.ServerExecuteDepth == 0) ? context.RemapHandlerInstance : null;

            using (new ApplicationImpersonationContext()) { 
                // Use remap handler if possible
                if (handler != null){ 
                    return handler; 
                }
 
                // Map new handler
                HttpHandlerAction mapping = GetHandlerMapping(context, requestType, path, useAppConfig);

                // If a page developer has removed the default mappings with  
                // without replacing them then we need to give a more descriptive error than
                // a null parameter exception. 
                if (mapping == null) { 
                    PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_FOUND);
                    PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_FAILED); 
                    throw new HttpException(SR.GetString(SR.Http_handler_not_found_for_request_type, requestType));
                }

                // Get factory from the mapping 
                IHttpHandlerFactory factory = GetFactory(mapping);
 
 
                // Get factory from the mapping
                try { 
                    // Check if it supports the more efficient GetHandler call that can avoid
                    // a VirtualPath object creation.
                    IHttpHandlerFactory2 factory2 = factory as IHttpHandlerFactory2;
 
                    if (factory2 != null) {
                        handler = factory2.GetHandler(context, requestType, path, pathTranslated); 
                    } 
                    else {
                        handler = factory.GetHandler(context, requestType, path.VirtualPathString, pathTranslated); 
                    }
                }
                catch (FileNotFoundException e) {
                    if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) 
                        throw new HttpException(404, null, e);
                    else 
                        throw new HttpException(404, null); 
                }
                catch (DirectoryNotFoundException e) { 
                    if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                        throw new HttpException(404, null, e);
                    else
                        throw new HttpException(404, null); 
                }
                catch (PathTooLongException e) { 
                    if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) 
                        throw new HttpException(414, null, e);
                    else 
                        throw new HttpException(414, null);
                }

                // Remember for recycling 
                if (_handlerRecycleList == null)
                    _handlerRecycleList = new ArrayList(); 
                _handlerRecycleList.Add(new HandlerWithFactory(handler, factory)); 
            }
 
            return handler;
        }

 
        /// 
        ///    [To be supplied.] 
        ///  
        public virtual string GetVaryByCustomString(HttpContext context, string custom) {
 
            if (StringUtil.EqualsIgnoreCase(custom, "browser")) {
                return context.Request.Browser.Type;
            }
 
            return null;
        } 
 
        public virtual string GetOutputCacheProviderName(HttpContext context) {
            // default implementation 
            return System.Web.Caching.OutputCache.DefaultProviderName;
        }

        // 
        // IComponent implementation
        // 
 

        ///  
        ///    [To be supplied.]
        /// 
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public ISite Site { 
            get { return _site;}
            set { _site = value;} 
        }

        //
        // IHttpAsyncHandler implementation 
        //
 
 
        /// 
        IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) { 
            HttpAsyncResult result;

            // Setup the asynchronous stuff and application variables
            _context = context; 
            _context.ApplicationInstance = this;
 
            _stepManager.InitRequest(); 

            // Make sure the context stays rooted (including all async operations) 
            _context.Root();

            // Create the async result
            result = new HttpAsyncResult(cb, extraData); 

            // Remember the async result for use in async completions 
            AsyncResult = result; 

            if (_context.TraceIsEnabled) 
                HttpRuntime.Profile.StartRequest(_context);

            // Start the application
            ResumeSteps(null); 

            // Return the async result 
            return result; 
        }
 

        /// 
        void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) {
            // throw error caught during execution 
            HttpAsyncResult ar = (HttpAsyncResult)result;
            if (ar.Error != null) 
                throw ar.Error; 
        }
 
        //
        // IHttpHandler implementation
        //
 

        ///  
        void IHttpHandler.ProcessRequest(HttpContext context) { 
            throw new HttpException(SR.GetString(SR.[....]_not_supported));
        } 


        /// 
        bool IHttpHandler.IsReusable { 
            get { return true; }
        } 
 
        //
        // Support for external calls into the application like app_onStart 
        //

        [ReflectionPermission(SecurityAction.Assert, Flags=ReflectionPermissionFlag.RestrictedMemberAccess)]
        private void InvokeMethodWithAssert(MethodInfo method, int paramCount, object eventSource, EventArgs eventArgs) { 
            if (paramCount == 0) {
                method.Invoke(this, new Object[0]); 
            } 
            else {
                Debug.Assert(paramCount == 2); 

                method.Invoke(this, new Object[2] { eventSource, eventArgs });
            }
        } 

        internal void ProcessSpecialRequest(HttpContext context, 
                                            MethodInfo method, 
                                            int paramCount,
                                            Object eventSource, 
                                            EventArgs eventArgs,
                                            HttpSessionState session) {
            _context = context;
            if (HttpRuntime.UseIntegratedPipeline && _context != null) { 
                _context.HideRequestResponse = true;
            } 
            _hideRequestResponse = true; 
            _session = session;
            _lastError = null; 

            using (new DisposableHttpContextWrapper(context)) {
                using (new ApplicationImpersonationContext()) {
                    try { 
                        // set culture on the current thread
                        SetAppLevelCulture(); 
                        InvokeMethodWithAssert(method, paramCount, eventSource, eventArgs); 
                    }
                    catch (Exception e) { 
                        // dereference reflection invocation exceptions
                        Exception eActual;
                        if (e is TargetInvocationException)
                            eActual = e.InnerException; 
                        else
                            eActual = e; 
 
                        RecordError(eActual);
 
                        if (context == null) {
                            try {
                                WebBaseEvent.RaiseRuntimeError(eActual, this);
                            } 
                            catch {
                            } 
                        } 

                    } 
                    finally {

                        // this thread should not be locking app state
                        if (_state != null) 
                            _state.EnsureUnLock();
 
                        // restore culture 
                        RestoreAppLevelCulture();
 
                        if (HttpRuntime.UseIntegratedPipeline && _context != null) {
                            _context.HideRequestResponse = false;
                        }
                        _hideRequestResponse = false; 
                        _context = null;
                        _session = null; 
                        _lastError = null; 
                        _appEvent = null;
                    } 
                }
            }
        }
 
        //
        // Report context-less error 
        // 

        internal void RaiseErrorWithoutContext(Exception error) { 
            try {
                try {
                    SetAppLevelCulture();
                    _lastError = error; 

                    RaiseOnError(); 
                } 
                finally {
                    // this thread should not be locking app state 
                    if (_state != null)
                        _state.EnsureUnLock();

                    RestoreAppLevelCulture(); 
                    _lastError = null;
                    _appEvent = null; 
                } 
            }
            catch { // Protect against exception filters 
                throw;
            }
        }
 
        //
        // 
        // 

        internal void InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers) { 
            Debug.Assert(context != null, "context != null");

            // Remember state
            _state = state; 

            PerfCounters.IncrementCounter(AppPerfCounter.PIPELINES); 
 
            try {
                try { 
                    // Remember context for config lookups
                    _initContext = context;
                    _initContext.ApplicationInstance = this;
 
                    // Set config path to be application path for the application initialization
                    context.ConfigurationPath = context.Request.ApplicationPathObject; 
 
                    // keep HttpContext.Current working while running user code
                    using (new DisposableHttpContextWrapper(context)) { 

                        // Build module list from config
                        if (HttpRuntime.UseIntegratedPipeline) {
 
                            Debug.Assert(_moduleConfigInfo != null, "_moduleConfigInfo != null");
                            Debug.Assert(_moduleConfigInfo.Count >= 0, "_moduleConfigInfo.Count >= 0"); 
 
                            try {
                                context.HideRequestResponse = true; 
                                _hideRequestResponse = true;
                                InitIntegratedModules();
                            }
                            finally { 
                                context.HideRequestResponse = false;
                                _hideRequestResponse = false; 
                            } 
                        }
                        else { 
                            InitModules();

                            // this is used exclusively for integrated mode
                            Debug.Assert(null == _moduleContainers, "null == _moduleContainers"); 
                        }
 
                        // Hookup event handlers via reflection 
                        if (handlers != null)
                            HookupEventHandlersForApplicationAndModules(handlers); 

                        // Initialization of the derived class
                        _context = context;
                        if (HttpRuntime.UseIntegratedPipeline && _context != null) { 
                            _context.HideRequestResponse = true;
                        } 
                        _hideRequestResponse = true; 

                        try { 
                            Init();
                        }
                        catch (Exception e) {
                            RecordError(e); 
                        }
                    } 
 
                    if (HttpRuntime.UseIntegratedPipeline && _context != null) {
                        _context.HideRequestResponse = false; 
                    }
                    _hideRequestResponse = false;
                    _context = null;
                    _resumeStepsWaitCallback= new WaitCallback(this.ResumeStepsWaitCallback); 

                    // Construct the execution steps array 
                    if (HttpRuntime.UseIntegratedPipeline) { 
                        _stepManager = new PipelineStepManager(this);
                    } 
                    else {
                        _stepManager = new ApplicationStepManager(this);
                    }
 
                    _stepManager.BuildSteps(_resumeStepsWaitCallback);
                } 
                finally { 
                    _initInternalCompleted = true;
 
                    // Reset config path
                    context.ConfigurationPath = null;

                    // don't hold on to the context 
                    _initContext.ApplicationInstance = null;
                    _initContext = null; 
                } 
            }
            catch { // Protect against exception filters 
                throw;
            }
        }
 
        // helper to expand an event handler into application steps
        private void CreateEventExecutionSteps(Object eventIndex, ArrayList steps) { 
            // async 
            AsyncAppEventHandler asyncHandler = AsyncEvents[eventIndex];
 
            if (asyncHandler != null) {
                asyncHandler.CreateExecutionSteps(this, steps);
            }
 
            // [....]
            EventHandler handler = (EventHandler)Events[eventIndex]; 
 
            if (handler != null) {
                Delegate[] handlers = handler.GetInvocationList(); 

                for (int i = 0; i < handlers.Length; i++)  {
                    steps.Add(new SyncEventExecutionStep(this, (EventHandler)handlers[i]));
                } 
            }
        } 
 
        internal void InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) {
            // Remember state 
            _state = state;

            try {
                //  Remember the context for the initialization 
                if (context != null) {
                    _initContext = context; 
                    _initContext.ApplicationInstance = this; 
                }
 
                // if we're doing integrated pipeline wireup, then appContext is non-null and we need to init modules and register event subscriptions with IIS
                if (appContext != IntPtr.Zero) {
                    // 1694356: app_offline.htm and  require that we make this check here for integrated mode
                    using (new ApplicationImpersonationContext()) { 
                        HttpRuntime.CheckApplicationEnabled();
                    } 
 
                    // retrieve app level culture
                    InitAppLevelCulture(); 

                    Debug.Trace("PipelineRuntime", "InitSpecial for " + appContext.ToString() + "\n");
                    RegisterEventSubscriptionsWithIIS(appContext, context, handlers);
                } 
                else {
                    // retrieve app level culture 
                    InitAppLevelCulture(); 

                    // Hookup event handlers via reflection 
                    if (handlers != null) {
                        HookupEventHandlersForApplicationAndModules(handlers);
                    }
                } 

                // if we're doing integrated pipeline wireup, then appContext is non-null and we need to register the application (global.asax) event handlers 
                if (appContext != IntPtr.Zero) { 
                    if (_appPostNotifications != 0 || _appRequestNotifications != 0) {
                        RegisterIntegratedEvent(appContext, 
                                                HttpApplicationFactory.applicationFileName,
                                                _appRequestNotifications,
                                                _appPostNotifications,
                                                this.GetType().FullName, 
                                                MANAGED_PRECONDITION,
                                                false); 
                    } 
                }
            } 
            finally  {
                _initSpecialCompleted = true;

                //  Do not hold on to the context 
                if (_initContext != null) {
                    _initContext.ApplicationInstance = null; 
                    _initContext = null; 
                }
            } 
        }

        internal void DisposeInternal() {
            PerfCounters.DecrementCounter(AppPerfCounter.PIPELINES); 

            // call derived class 
 
            try {
                Dispose(); 
            }
            catch (Exception e) {
                RecordError(e);
            } 

            // dispose modules 
 
            if (_moduleCollection != null) {
                int numModules = _moduleCollection.Count; 

                for (int i = 0; i < numModules; i++) {
                    try {
                        // set the init key during Dispose for modules 
                        // that try to unregister events
                        if (HttpRuntime.UseIntegratedPipeline) { 
                            _currentModuleCollectionKey = _moduleCollection.GetKey(i); 
                        }
                        _moduleCollection[i].Dispose(); 
                    }
                    catch {
                    }
                } 

                _moduleCollection = null; 
            } 
        }
 
        private void BuildEventMaskDictionary(Dictionary eventMask) {
            eventMask["BeginRequest"]              = RequestNotification.BeginRequest;
            eventMask["AuthenticateRequest"]       = RequestNotification.AuthenticateRequest;
            eventMask["PostAuthenticateRequest"]   = RequestNotification.AuthenticateRequest; 
            eventMask["AuthorizeRequest"]          = RequestNotification.AuthorizeRequest;
            eventMask["PostAuthorizeRequest"]      = RequestNotification.AuthorizeRequest; 
            eventMask["ResolveRequestCache"]       = RequestNotification.ResolveRequestCache; 
            eventMask["PostResolveRequestCache"]   = RequestNotification.ResolveRequestCache;
            eventMask["MapRequestHandler"]         = RequestNotification.MapRequestHandler; 
            eventMask["PostMapRequestHandler"]     = RequestNotification.MapRequestHandler;
            eventMask["AcquireRequestState"]       = RequestNotification.AcquireRequestState;
            eventMask["PostAcquireRequestState"]   = RequestNotification.AcquireRequestState;
            eventMask["PreRequestHandlerExecute"]  = RequestNotification.PreExecuteRequestHandler; 
            eventMask["PostRequestHandlerExecute"] = RequestNotification.ExecuteRequestHandler;
            eventMask["ReleaseRequestState"]       = RequestNotification.ReleaseRequestState; 
            eventMask["PostReleaseRequestState"]   = RequestNotification.ReleaseRequestState; 
            eventMask["UpdateRequestCache"]        = RequestNotification.UpdateRequestCache;
            eventMask["PostUpdateRequestCache"]    = RequestNotification.UpdateRequestCache; 
            eventMask["LogRequest"]                = RequestNotification.LogRequest;
            eventMask["PostLogRequest"]            = RequestNotification.LogRequest;
            eventMask["EndRequest"]                = RequestNotification.EndRequest;
            eventMask["PreSendRequestHeaders"]     = RequestNotification.SendResponse; 
            eventMask["PreSendRequestContent"]     = RequestNotification.SendResponse;
        } 
 
        private void HookupEventHandlersForApplicationAndModules(MethodInfo[] handlers) {
            _currentModuleCollectionKey = HttpApplicationFactory.applicationFileName; 

            if(null == _pipelineEventMasks) {
                Dictionary dict = new Dictionary();
                BuildEventMaskDictionary(dict); 
                if(null == _pipelineEventMasks) {
                    _pipelineEventMasks = dict; 
                } 
            }
 

            for (int i = 0; i < handlers.Length; i++) {
                MethodInfo appMethod = handlers[i];
                String appMethodName = appMethod.Name; 
                int namePosIndex = appMethodName.IndexOf('_');
                String targetName = appMethodName.Substring(0, namePosIndex); 
 
                // Find target for method
                Object target = null; 

                if (StringUtil.EqualsIgnoreCase(targetName, "Application"))
                    target = this;
                else if (_moduleCollection != null) 
                    target = _moduleCollection[targetName];
 
                if (target == null) 
                    continue;
 
                // Find event on the module type
                Type targetType = target.GetType();
                EventDescriptorCollection events = TypeDescriptor.GetEvents(targetType);
                string eventName = appMethodName.Substring(namePosIndex+1); 

                EventDescriptor foundEvent = events.Find(eventName, true); 
                if (foundEvent == null 
                    && StringUtil.EqualsIgnoreCase(eventName.Substring(0, 2), "on")) {
 
                    eventName = eventName.Substring(2);
                    foundEvent = events.Find(eventName, true);
                }
 
                MethodInfo addMethod = null;
                if (foundEvent != null) { 
                    EventInfo reflectionEvent = targetType.GetEvent(foundEvent.Name); 
                    Debug.Assert(reflectionEvent != null);
                    if (reflectionEvent != null) { 
                        addMethod = reflectionEvent.GetAddMethod();
                    }
                }
 
                if (addMethod == null)
                    continue; 
 
                ParameterInfo[] addMethodParams = addMethod.GetParameters();
 
                if (addMethodParams.Length != 1)
                    continue;

                // Create the delegate from app method to pass to AddXXX(handler) method 

                Delegate handlerDelegate = null; 
 
                ParameterInfo[] appMethodParams = appMethod.GetParameters();
 
                if (appMethodParams.Length == 0) {
                    // If the app method doesn't have arguments --
                    // -- hookup via intermidiate handler
 
                    // only can do it for EventHandler, not strongly typed
                    if (addMethodParams[0].ParameterType != typeof(System.EventHandler)) 
                        continue; 

                    ArglessEventHandlerProxy proxy = new ArglessEventHandlerProxy(this, appMethod); 
                    handlerDelegate = proxy.Handler;
                }
                else {
                    // Hookup directly to the app methods hoping all types match 

                    try { 
                        handlerDelegate = Delegate.CreateDelegate(addMethodParams[0].ParameterType, this, appMethodName); 
                    }
                    catch { 
                        // some type mismatch
                        continue;
                    }
                } 

                // Call the AddXXX() to hook up the delegate 
 
                try {
                    addMethod.Invoke(target, new Object[1]{handlerDelegate}); 
                }
                catch {
                    if (HttpRuntime.UseIntegratedPipeline) {
                        throw; 
                    }
                } 
 
                if (eventName != null) {
                    if (_pipelineEventMasks.ContainsKey(eventName)) { 
                        if (!StringUtil.StringStartsWith(eventName, "Post")) {
                            _appRequestNotifications |= _pipelineEventMasks[eventName];
                        }
                        else { 
                            _appPostNotifications |= _pipelineEventMasks[eventName];
                        } 
                    } 
                }
            } 
        }

        private void RegisterIntegratedEvent(IntPtr appContext,
                                             string moduleName, 
                                             RequestNotification requestNotifications,
                                             RequestNotification postRequestNotifications, 
                                             string moduleType, 
                                             string modulePrecondition,
                                             bool useHighPriority) { 

            // lookup the modules event index, if it already exists
            // use it, otherwise, bump the global count
            // the module is used for event dispatch 

            int moduleIndex; 
            if (_moduleIndexMap.ContainsKey(moduleName)) { 
                moduleIndex = (int) _moduleIndexMap[moduleName];
            } 
            else {
                moduleIndex = _moduleIndexMap.Count;
                _moduleIndexMap[moduleName] = moduleIndex;
            } 

#if DBG 
            Debug.Assert(moduleIndex >= 0, "moduleIndex >= 0"); 
            Debug.Trace("PipelineRuntime", "RegisterIntegratedEvent:"
                        + " module=" + moduleName 
                        + ", index=" + moduleIndex.ToString(CultureInfo.InvariantCulture)
                        + ", rq_notify=" + requestNotifications
                        + ", post_rq_notify=" + postRequestNotifications
                        + ", preconditon=" + modulePrecondition + "\r\n"); 
#endif
 
            int result = UnsafeIISMethods.MgdRegisterEventSubscription(appContext, 
                                                                       moduleName,
                                                                       requestNotifications, 
                                                                       postRequestNotifications,
                                                                       moduleType,
                                                                       modulePrecondition,
                                                                       new IntPtr(moduleIndex), 
                                                                       useHighPriority);
 
            if(result < 0) { 
                throw new HttpException(SR.GetString(
                    SR.Failed_Pipeline_Subscription, moduleName)); 
            }
        }

 
        private void SetAppLevelCulture() {
            CultureInfo culture = null; 
            CultureInfo uiculture = null; 
            CultureInfo browserCulture = null;
            string userLanguage = null; 
            //get the language from the browser
            //DevDivBugs 2001091: Request object is not available in integrated mode during Application_Start,
            //so don't try to access it if it is hidden
            if((_appLevelAutoCulture || _appLevelAutoUICulture) && _context != null && _context.HideRequestResponse == false) { 
                userLanguage = _context.UserLanguageFromContext();
                if(userLanguage != null) { 
                    try { browserCulture = HttpServerUtility.CreateReadOnlySpecificCultureInfo(userLanguage); } 
                    catch { }
                } 
            }

            culture = _appLevelCulture;
            uiculture = _appLevelUICulture; 
            if(browserCulture != null) {
                if(_appLevelAutoCulture) { 
                    culture = browserCulture; 
                }
                if(_appLevelAutoUICulture) { 
                    uiculture = browserCulture;
                }
            }
 
            _savedAppLevelCulture = Thread.CurrentThread.CurrentCulture;
            _savedAppLevelUICulture = Thread.CurrentThread.CurrentUICulture; 
 
            if (culture != null && culture != Thread.CurrentThread.CurrentCulture) {
                HttpRuntime.SetCurrentThreadCultureWithAssert(culture); 
            }

            if (uiculture != null && uiculture != Thread.CurrentThread.CurrentUICulture) {
                Thread.CurrentThread.CurrentUICulture = uiculture; 
            }
        } 
 
        private void RestoreAppLevelCulture() {
            CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; 
            CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;

            if (_savedAppLevelCulture != null) {
                // Avoid the cost of the Demand when setting the culture by comparing the cultures first 
                if (currentCulture != _savedAppLevelCulture) {
                    HttpRuntime.SetCurrentThreadCultureWithAssert(_savedAppLevelCulture); 
                } 

                _savedAppLevelCulture = null; 
            }

            if (_savedAppLevelUICulture != null) {
                // Avoid the cost of the Demand when setting the culture by comparing the cultures first 
                if (currentUICulture  != _savedAppLevelUICulture) {
                    Thread.CurrentThread.CurrentUICulture = _savedAppLevelUICulture; 
                } 

                _savedAppLevelUICulture = null; 
            }
        }

        // OnThreadEnterPrivate returns ThreadContext. 
        // ThreadContext.Enter sets variables that are stored on the thread,
        // and saves anything currently on the thread so it can be restored 
        // during the call to ThreadContext.Leave.  All variables that are 
        // modified on the thread should be stored in ThreadContext so they
        // can be restored later.  ThreadContext.Enter should only be called 
        // when holding a lock on the HttpApplication instance.
        // ThreadContext.Leave is also normally called under the lock, but
        // the Integrated Pipeline may delay this call until after the call to
        // IndicateCompletion returns.  When IndicateCompletion is called, 
        // IIS7 will execute the remaining notifications for the request on
        // the current thread.  As a performance improvement, we do not call 
        // Leave before calling IndicateCompletion, and we do not call Enter/Leave 
        // for the notifications executed while we are in the call to
        // IndicateCompletion.  But when IndicateCompletion returns, we do not 
        // have a lock on the HttpApplication instance and therefore cannot
        // modify request state, such as the HttpContext or HttpApplication.
        // The only thing we can do is restore the state of the thread.
        // There's one problem, the Culture/UICulture may be changed by 
        // user code that directly updates the values on the current thread, so
        // before leaving the pipeline we call ThreadContext.Synchronize to 
        // synchronize the values that are stored on the HttpContext with what 
        // is on the thread.  Because of this, the next notification will end up using
        // the Culture/UICulture set by user-code, just as it did on IIS6. 
        internal class ThreadContext {
            private HttpContext _context;
            private IPrincipal _savedPrincipal;
            private HttpContext _savedContext; 
            private ImpersonationContext _impersonationContext;
            private SynchronizationContext _savedSynchronizationContext; 
            private CultureInfo _savedCulture, _setThreadCulture; 
            private CultureInfo _savedUICulture, _setThreadUICulture;
            private bool _hasLeaveBeenCalled; 
            private bool _setThread;

            internal ThreadContext(HttpContext context) {
                _context = context; 
            }
 
            internal void Enter(bool setImpersonationContext) { 
                Debug.Assert(_context != null); // only to be used when context is available
#if DBG 
                Debug.Trace("OnThread", GetTraceMessage("Enter1"));
#endif
                // attach http context to the call context
                _savedContext = DisposableHttpContextWrapper.SwitchContext(_context); 

                // set impersonation on the current thread 
                if (setImpersonationContext) { 
                    SetImpersonationContext();
                } 

                // set synchronization context for the current thread to support the async pattern
                _savedSynchronizationContext = AsyncOperationManager.SynchronizationContext;
                AsyncOperationManager.SynchronizationContext = _context.SyncContext; 

                // set ETW trace ID 
                Guid g = _context.WorkerRequest.RequestTraceIdentifier; 
                if (!(g == Guid.Empty)) {
                    CallContext.LogicalSetData("E2ETrace.ActivityID", g); 
                }

                // set SqlDependecyCookie
                _context.ResetSqlDependencyCookie(); 

                // set principal on the current thread 
                _savedPrincipal = Thread.CurrentPrincipal; 
                SetCurrentPrincipalWithAssert(_context.User);
 
                // only set culture on the current thread if it is not initialized
                SetRequestLevelCulture(_context);

                // DevDivBugs 75042 
                // set current thread in context if there is not there
                // the timeout manager  uses this to abort the correct thread 
                if (_context.CurrentThread == null) { 
                    _setThread = true;
                    _context.CurrentThread = Thread.CurrentThread; 
                }
#if DBG
                Debug.Trace("OnThread", GetTraceMessage("Enter2"));
#endif 
            }
 
            internal bool HasLeaveBeenCalled { get { return _hasLeaveBeenCalled; } } 

            internal void Leave() { 
#if DBG
                Debug.Trace("OnThread", GetTraceMessage("Leave1"));
#endif
                _hasLeaveBeenCalled = true; 

                // remove thread if set 
                if (_setThread) { 
                    _context.CurrentThread = null;
                } 

                // this thread should not be locking app state
                HttpApplicationFactory.ApplicationState.EnsureUnLock();
 
                // stop impersonation
                UndoImpersonationContext(); 
 
                // restore culture
                RestoreRequestLevelCulture(); 

                // restrore synchronization context
                AsyncOperationManager.SynchronizationContext = _savedSynchronizationContext;
 
                // restore thread principal
                SetCurrentPrincipalWithAssert(_savedPrincipal); 
 
                // Remove SqlCacheDependency cookie from call context if necessary
                _context.RemoveSqlDependencyCookie(); 

                // remove http context from the call context
                DisposableHttpContextWrapper.SwitchContext(_savedContext);
                _savedContext = null; 
#if DBG
                Debug.Trace("OnThread", GetTraceMessage("Leave2")); 
#endif 
            }
 
            // Use of IndicateCompletion requires that we synchronize the cultures
            // with what may have been set by user code during execution of the
            // notification.
            internal void Synchronize(HttpContext context) { 
                context.DynamicCulture = Thread.CurrentThread.CurrentCulture;
                context.DynamicUICulture = Thread.CurrentThread.CurrentUICulture; 
            } 

            internal void SetImpersonationContext() { 
                // set impersonation on the current thread
                if (_impersonationContext == null) {
                    _impersonationContext = new ClientImpersonationContext(_context);
                } 
            }
 
            internal void UndoImpersonationContext() { 
                // remove impersonation on the current thread
                if (_impersonationContext != null) { 
                    _impersonationContext.Undo();
                    _impersonationContext = null;
                }
            } 

            // 
            // Application execution logic 
            //
            private void SetRequestLevelCulture(HttpContext context) { 
                CultureInfo culture = null;
                CultureInfo uiculture = null;

                GlobalizationSection globConfig = RuntimeConfig.GetConfig(context).Globalization; 
                if (!String.IsNullOrEmpty(globConfig.Culture))
                    culture = context.CultureFromConfig(globConfig.Culture, true); 
 
                if (!String.IsNullOrEmpty(globConfig.UICulture))
                    uiculture = context.CultureFromConfig(globConfig.UICulture, false); 

                if (context.DynamicCulture != null)
                    culture = context.DynamicCulture;
 
                if (context.DynamicUICulture != null)
                    uiculture = context.DynamicUICulture; 
 
                // Page also could have its own culture settings
                Page page = context.CurrentHandler as Page; 

                if (page != null) {
                    if (page.DynamicCulture != null)
                        culture = page.DynamicCulture; 

                    if (page.DynamicUICulture != null) 
                        uiculture = page.DynamicUICulture; 
                }
 
                _savedCulture = Thread.CurrentThread.CurrentCulture;
                _savedUICulture = Thread.CurrentThread.CurrentUICulture;

                if (culture != null && culture != Thread.CurrentThread.CurrentCulture) { 
                    HttpRuntime.SetCurrentThreadCultureWithAssert(culture);
                    _setThreadCulture = culture; 
                } 

                if (uiculture != null && uiculture != Thread.CurrentThread.CurrentUICulture) { 
                    Thread.CurrentThread.CurrentUICulture = uiculture;
                    _setThreadUICulture = uiculture;
                }
            } 

            private void RestoreRequestLevelCulture() { 
                CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; 
                CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;
 
                if (_savedCulture != null) {
                    // Avoid the cost of the Demand when setting the culture by comparing the cultures first
                    if (currentCulture != _savedCulture) {
                        HttpRuntime.SetCurrentThreadCultureWithAssert(_savedCulture); 
                        if (_context != null) {
                            // remember changed culture for the rest of the request 
                            _context.DynamicCulture = currentCulture; 
                        }
                    } 

                    _savedCulture = null;
                }
 
                if (_savedUICulture != null) {
                    // Avoid the cost of the Demand when setting the culture by comparing the cultures first 
                    if (currentUICulture  != _savedUICulture) { 
                        Thread.CurrentThread.CurrentUICulture = _savedUICulture;
                        if (_context != null) { 
                            // remember changed culture for the rest of the request
                            _context.DynamicUICulture = currentUICulture;
                        }
                    } 

                    _savedUICulture = null; 
                } 
            }
 
#if DBG
            static string GetTraceMessage(string tag) {
                System.Text.StringBuilder sb = new System.Text.StringBuilder(256);
                sb.Append(tag); 
                sb.AppendFormat(" Thread={0}", SafeNativeMethods.GetCurrentThreadId().ToString(CultureInfo.InvariantCulture));
                sb.AppendFormat(" Context={0}", (HttpContext.Current != null) ? HttpContext.Current.GetHashCode().ToString(CultureInfo.InvariantCulture) : "NULL_CTX"); 
                sb.AppendFormat(" Principal={0}", (Thread.CurrentPrincipal != null) ? Thread.CurrentPrincipal.GetHashCode().ToString(CultureInfo.InvariantCulture) : "NULL_PRIN"); 
                sb.AppendFormat(" Culture={0}", Thread.CurrentThread.CurrentCulture.LCID.ToString(CultureInfo.InvariantCulture));
                sb.AppendFormat(" UICulture={0}", Thread.CurrentThread.CurrentUICulture.LCID.ToString(CultureInfo.InvariantCulture)); 
                sb.AppendFormat(" ActivityID={0}", CallContext.LogicalGetData("E2ETrace.ActivityID"));
                return sb.ToString();
            }
#endif 
        }
 
        // Initializes the thread on entry to the managed pipeline. A ThreadContext is returned, on 
        // which the caller must call Leave.  The IIS7 integrated pipeline uses setImpersonationContext
        // to prevent it from being set until after the authentication notification. 
        private ThreadContext OnThreadEnterPrivate(bool setImpersonationContext) {
            ThreadContext threadContext = new ThreadContext(_context);
            threadContext.Enter(setImpersonationContext);
 
            // An entry is added to the request timeout manager once per request
            // and removed in ReleaseAppInstance. 
            if (!_timeoutManagerInitialized) { 
                // ensure Timeout is set (see ASURT 148698)
                // to avoid ---- getting config later (ASURT 127388) 
                _context.EnsureTimeout();

                HttpRuntime.RequestTimeoutManager.Add(_context);
                _timeoutManagerInitialized = true; 
            }
 
            return threadContext; 
        }
 
        internal ThreadContext OnThreadEnter() {
            return OnThreadEnterPrivate(true /* setImpersonationContext */);
        }
 
        internal ThreadContext OnThreadEnter(bool setImpersonationContext) {
            return OnThreadEnterPrivate(setImpersonationContext); 
        } 

        /* 
         * Execute single step catching exceptions in a fancy way (see below)
         */
        internal Exception ExecuteStep(IExecutionStep step, ref bool completedSynchronously) {
            Exception error = null; 

            try { 
                try { 
                    if (step.IsCancellable) {
                        _context.BeginCancellablePeriod();  // request can be cancelled from this point 

                        try {
                            step.Execute();
                        } 
                        finally {
                            _context.EndCancellablePeriod();  // request can be cancelled until this point 
                        } 

                        _context.WaitForExceptionIfCancelled();  // wait outside of finally 
                    }
                    else {
                        step.Execute();
                    } 

                    if (!step.CompletedSynchronously) { 
                        completedSynchronously = false; 
                        return null;
                    } 
                }
                catch (Exception e) {
                    error = e;
 
                    // Since we will leave the context later, we need to remember if we are impersonating
                    // before we lose that info - VSWhidbey 494476 
                    if (ImpersonationContext.CurrentThreadTokenExists) { 
                        e.Data[System.Web.Management.WebThreadInformation.IsImpersonatingKey] = String.Empty;
                    } 
                    // This might force ThreadAbortException to be thrown
                    // automatically, because we consumed an exception that was
                    // hiding ThreadAbortException behind it
 
                    if (e is ThreadAbortException &&
                        ((Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) == 0))  { 
                        // Response.End from a COM+ component that re-throws ThreadAbortException 
                        // It is not a real ThreadAbort
                        // VSWhidbey 178556 
                        error = null;
                        _stepManager.CompleteRequest();
                    }
                } 
#pragma warning disable 1058
                catch { 
                    // ignore non-Exception objects that could be thrown 
                }
#pragma warning restore 1058 
            }
            catch (ThreadAbortException e) {
                // ThreadAbortException could be masked as another one
                // the try-catch above consumes all exceptions, only 
                // ThreadAbortException can filter up here because it gets
                // auto rethrown if no other exception is thrown on catch 
 
                if (e.ExceptionState != null && e.ExceptionState is CancelModuleException) {
                    // one of ours (Response.End or timeout) -- cancel abort 

                    CancelModuleException cancelException = (CancelModuleException)e.ExceptionState;

                    if (cancelException.Timeout) { 
                        // Timed out
                        error = new HttpException(SR.GetString(SR.Request_timed_out), 
                                            null, WebEventCodes.RuntimeErrorRequestAbort); 
                        PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_TIMED_OUT);
                    } 
                    else {
                        // Response.End
                        error = null;
                        _stepManager.CompleteRequest(); 
                    }
 
                    Thread.ResetAbort(); 
                }
            } 

            completedSynchronously = true;
            return error;
        } 

        /* 
         * Resume execution of the app steps 
         */
 
        private void ResumeStepsFromThreadPoolThread(Exception error) {
            if (Thread.CurrentThread.IsThreadPoolThread) {
                // if on thread pool thread, use the current thread
                ResumeSteps(error); 
            }
            else { 
                // if on a non-threadpool thread, requeue 
                ThreadPool.QueueUserWorkItem(_resumeStepsWaitCallback, error);
            } 
        }

        private void ResumeStepsWaitCallback(Object error) {
            ResumeSteps(error as Exception); 
        }
 
        private void ResumeSteps(Exception error) { 
            _stepManager.ResumeSteps(error);
        } 


        /*
         * Add error to the context fire OnError on first error 
         */
        private void RecordError(Exception error) { 
            bool firstError = true; 

            if (_context != null) { 
                if (_context.Error != null)
                    firstError = false;

                _context.AddError(error); 
            }
            else { 
                if (_lastError != null) 
                    firstError = false;
 
                _lastError = error;
            }

            if (firstError) 
                RaiseOnError();
        } 
 

        // 
        // Init module list
        //

        private void InitModulesCommon() { 
            int n = _moduleCollection.Count;
 
            for (int i = 0; i < n; i++) { 
                // remember the module being inited for event subscriptions
                // we'll later use this for routing 
                _currentModuleCollectionKey = _moduleCollection.GetKey(i);
                _moduleCollection[i].Init(this);
            }
 
            _currentModuleCollectionKey = null;
            InitAppLevelCulture(); 
        } 

        private void InitIntegratedModules() { 
            Debug.Assert(null != _moduleConfigInfo, "null != _moduleConfigInfo");
            _moduleCollection = BuildIntegratedModuleCollection(_moduleConfigInfo);
            InitModulesCommon();
        } 

        private void InitModules() { 
            HttpModulesSection pconfig = RuntimeConfig.GetAppConfig().HttpModules; 
            _moduleCollection = pconfig.CreateModules();
 
            InitModulesCommon();
        }

        internal string CurrentModuleCollectionKey { 
            get {
                return (null == _currentModuleCollectionKey) ? "UnknownModule" : _currentModuleCollectionKey; 
            } 
        }
 
        private void RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) {
            RequestNotification requestNotifications;
            RequestNotification postRequestNotifications;
 
            // register an implicit filter module
            RegisterIntegratedEvent(appContext, 
                                    IMPLICIT_FILTER_MODULE, 
                                    RequestNotification.UpdateRequestCache| RequestNotification.LogRequest  /*requestNotifications*/,
                                    0 /*postRequestNotifications*/, 
                                    String.Empty /*type*/,
                                    String.Empty /*precondition*/,
                                    true /*useHighPriority*/);
 
            // integrated pipeline will always use serverModules instead of 
            _moduleCollection = GetModuleCollection(appContext); 
 
            if (handlers != null) {
                HookupEventHandlersForApplicationAndModules(handlers); 
            }

            // 1643363: Breaking Change: ASP.Net v2.0: Application_OnStart is called after Module.Init (Integarted mode)
            HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(context, this); 

            // Call Init on HttpApplication derived class ("global.asax") 
            // and process event subscriptions before processing other modules. 
            // Doing this now prevents clearing any events that may
            // have been added to event handlers during instantiation of this instance. 
            // NOTE:  If "global.asax" has a constructor which hooks up event handlers,
            // then they were added to the event handler lists but have not been registered with IIS yet,
            // so we MUST call ProcessEventSubscriptions on it first, before the other modules.
            _currentModuleCollectionKey = HttpApplicationFactory.applicationFileName; 

            try { 
                _hideRequestResponse = true; 
                context.HideRequestResponse = true;
                _context = context; 
                Init();
            }
            catch (Exception e) {
                RecordError(e); 
                Exception error = context.Error;
                if (error != null) { 
                    throw error; 
                }
            } 
            finally {
                _context = null;
                context.HideRequestResponse = false;
                _hideRequestResponse = false; 
            }
 
            ProcessEventSubscriptions(out requestNotifications, out postRequestNotifications); 

            // Save the notification subscriptions so we can register them with IIS later, after 
            // we call HookupEventHandlersForApplicationAndModules and process global.asax event handlers.
            _appRequestNotifications |= requestNotifications;
            _appPostNotifications    |= postRequestNotifications;
 
            for (int i = 0; i < _moduleCollection.Count; i++) {
                _currentModuleCollectionKey = _moduleCollection.GetKey(i); 
                IHttpModule httpModule = _moduleCollection.Get(i); 
                ModuleConfigurationInfo moduleInfo = _moduleConfigInfo[i];
 
#if DBG
                Debug.Trace("PipelineRuntime", "RegisterEventSubscriptionsWithIIS: name=" + CurrentModuleCollectionKey
                            + ", type=" + httpModule.GetType().FullName + "\n");
 
                // make sure collections are in [....]
                Debug.Assert(moduleInfo.Name == _currentModuleCollectionKey, "moduleInfo.Name == _currentModuleCollectionKey"); 
#endif 

                httpModule.Init(this); 

                ProcessEventSubscriptions(out requestNotifications, out postRequestNotifications);

                // are any events wired up? 
                if (requestNotifications != 0 || postRequestNotifications != 0) {
 
                    RegisterIntegratedEvent(appContext, 
                                            moduleInfo.Name,
                                            requestNotifications, 
                                            postRequestNotifications,
                                            moduleInfo.Type,
                                            moduleInfo.Precondition,
                                            false /*useHighPriority*/); 
                }
            } 
 
            // WOS 1728067: RewritePath does not remap the handler when rewriting from a non-ASP.NET request
            // register a default implicit handler 
            RegisterIntegratedEvent(appContext,
                                    IMPLICIT_HANDLER,
                                    RequestNotification.ExecuteRequestHandler | RequestNotification.MapRequestHandler /*requestNotifications*/,
                                    0 /*postRequestNotifications*/, 
                                    String.Empty /*type*/,
                                    String.Empty /*precondition*/, 
                                    false /*useHighPriority*/); 
        }
 
        private void ProcessEventSubscriptions(out RequestNotification requestNotifications,
                                               out RequestNotification postRequestNotifications) {
            requestNotifications = 0;
            postRequestNotifications = 0; 

            // Begin 
            if(HasEventSubscription(EventBeginRequest)) { 
                requestNotifications |= RequestNotification.BeginRequest;
            } 

            // Authenticate
            if(HasEventSubscription(EventAuthenticateRequest)) {
                requestNotifications |= RequestNotification.AuthenticateRequest; 
            }
 
            if(HasEventSubscription(EventPostAuthenticateRequest)) { 
                postRequestNotifications |= RequestNotification.AuthenticateRequest;
            } 

            // Authorize
            if(HasEventSubscription(EventAuthorizeRequest)) {
                requestNotifications |= RequestNotification.AuthorizeRequest; 
            }
            if(HasEventSubscription(EventPostAuthorizeRequest)) { 
                postRequestNotifications |= RequestNotification.AuthorizeRequest; 
            }
 
            // ResolveRequestCache
            if(HasEventSubscription(EventResolveRequestCache)) {
                requestNotifications |= RequestNotification.ResolveRequestCache;
            } 
            if(HasEventSubscription(EventPostResolveRequestCache)) {
                postRequestNotifications |= RequestNotification.ResolveRequestCache; 
            } 

            // MapRequestHandler 
            if(HasEventSubscription(EventMapRequestHandler)) {
                requestNotifications |= RequestNotification.MapRequestHandler;
            }
            if(HasEventSubscription(EventPostMapRequestHandler)) { 
                postRequestNotifications |= RequestNotification.MapRequestHandler;
            } 
 
            // AcquireRequestState
            if(HasEventSubscription(EventAcquireRequestState)) { 
                requestNotifications |= RequestNotification.AcquireRequestState;
            }
            if(HasEventSubscription(EventPostAcquireRequestState)) {
                postRequestNotifications |= RequestNotification.AcquireRequestState; 
            }
 
            // PreExecuteRequestHandler 
            if(HasEventSubscription(EventPreRequestHandlerExecute)) {
                requestNotifications |= RequestNotification.PreExecuteRequestHandler; 
            }

            // PostRequestHandlerExecute
            if (HasEventSubscription(EventPostRequestHandlerExecute)) { 
                postRequestNotifications |= RequestNotification.ExecuteRequestHandler;
            } 
 
            // ReleaseRequestState
            if(HasEventSubscription(EventReleaseRequestState)) { 
                requestNotifications |= RequestNotification.ReleaseRequestState;
            }
            if(HasEventSubscription(EventPostReleaseRequestState)) {
                postRequestNotifications |= RequestNotification.ReleaseRequestState; 
            }
 
            // UpdateRequestCache 
            if(HasEventSubscription(EventUpdateRequestCache)) {
                requestNotifications |= RequestNotification.UpdateRequestCache; 
            }
            if(HasEventSubscription(EventPostUpdateRequestCache)) {
                postRequestNotifications |= RequestNotification.UpdateRequestCache;
            } 

            // LogRequest 
            if(HasEventSubscription(EventLogRequest)) { 
                requestNotifications |= RequestNotification.LogRequest;
            } 
            if(HasEventSubscription(EventPostLogRequest)) {
                postRequestNotifications |= RequestNotification.LogRequest;
            }
 
            // EndRequest
            if(HasEventSubscription(EventEndRequest)) { 
                requestNotifications |= RequestNotification.EndRequest; 
            }
 
            // PreSendRequestHeaders
            if(HasEventSubscription(EventPreSendRequestHeaders)) {
                requestNotifications |= RequestNotification.SendResponse;
            } 

            // PreSendRequestContent 
            if(HasEventSubscription(EventPreSendRequestContent)) { 
                requestNotifications |= RequestNotification.SendResponse;
            } 
        }

        // check if an event has subscribers
        // and *reset* them if so 
        // this is used only for special app instances
        // and not for processing requests 
        private bool HasEventSubscription(Object eventIndex) { 
            bool hasEvents = false;
 
            // async
            AsyncAppEventHandler asyncHandler = AsyncEvents[eventIndex];

            if (asyncHandler != null && asyncHandler.Count > 0) { 
                asyncHandler.Reset();
                hasEvents = true; 
            } 

            // [....] 
            EventHandler handler = (EventHandler)Events[eventIndex];

            if (handler != null) {
                Delegate[] handlers = handler.GetInvocationList(); 
                if( handlers.Length > 0 ) {
                    hasEvents = true; 
                } 

                foreach(Delegate d in handlers) { 
                    Events.RemoveHandler(eventIndex, d);
                }
            }
 
            return hasEvents;
        } 
 

        // 
        // Get app-level culture info (needed to context-less 'global' methods)
        //

        private void InitAppLevelCulture() { 
            GlobalizationSection globConfig = RuntimeConfig.GetAppConfig().Globalization;
            string culture = globConfig.Culture; 
            string uiCulture = globConfig.UICulture; 
            if (!String.IsNullOrEmpty(culture)) {
                if (StringUtil.StringStartsWithIgnoreCase(culture, AutoCulture)) { 
                    _appLevelAutoCulture = true;
                    string appLevelCulture = GetFallbackCulture(culture);
                    if(appLevelCulture != null) {
                        _appLevelCulture = HttpServerUtility.CreateReadOnlyCultureInfo(culture.Substring(5)); 
                    }
                } 
                else { 
                    _appLevelAutoCulture = false;
                    _appLevelCulture = HttpServerUtility.CreateReadOnlyCultureInfo(globConfig.Culture); 
                }
            }
            if (!String.IsNullOrEmpty(uiCulture)) {
                if (StringUtil.StringStartsWithIgnoreCase(uiCulture, AutoCulture)) 
                {
                    _appLevelAutoUICulture = true; 
                    string appLevelUICulture = GetFallbackCulture(uiCulture); 
                    if(appLevelUICulture != null) {
                        _appLevelUICulture = HttpServerUtility.CreateReadOnlyCultureInfo(uiCulture.Substring(5)); 
                    }
                }
                else {
                    _appLevelAutoUICulture = false; 
                    _appLevelUICulture = HttpServerUtility.CreateReadOnlyCultureInfo(globConfig.UICulture);
                } 
            } 
        }
 
        internal static string GetFallbackCulture(string culture) {
            if((culture.Length > 5) && (culture.IndexOf(':') == 4)) {
                return culture.Substring(5);
            } 
            return null;
        } 
 
        //
        // Request mappings management functions 
        //

        private IHttpHandlerFactory GetFactory(HttpHandlerAction mapping) {
            HandlerFactoryCache entry = (HandlerFactoryCache)_handlerFactories[mapping.Type]; 
            if (entry == null) {
                entry = new HandlerFactoryCache(mapping); 
                _handlerFactories[mapping.Type] = entry; 
            }
 
            return entry.Factory;
        }

        private IHttpHandlerFactory GetFactory(string type) { 
            HandlerFactoryCache entry = (HandlerFactoryCache)_handlerFactories[type];
            if (entry == null) { 
                entry = new HandlerFactoryCache(type); 
                _handlerFactories[type] = entry;
            } 

            return entry.Factory;
        }
 

        /* 
         * Recycle all handlers mapped during the request processing 
         */
        private void RecycleHandlers() { 
            if (_handlerRecycleList != null) {
                int numHandlers = _handlerRecycleList.Count;

                for (int i = 0; i < numHandlers; i++) 
                    ((HandlerWithFactory)_handlerRecycleList[i]).Recycle();
 
                _handlerRecycleList = null; 
            }
        } 

        /*
         * Special exception to cancel module execution (not really an exception)
         * used in Response.End and when cancelling requests 
         */
        internal class CancelModuleException { 
            private bool _timeout; 

            internal CancelModuleException(bool timeout) { 
                _timeout = timeout;
            }

            internal bool Timeout { get { return _timeout;}} 
        }
 
        // Setup the asynchronous stuff and application variables 
        // context for the entire deal is already rooted for native handler
        internal void AssignContext(HttpContext context) { 
            Debug.Assert(HttpRuntime.UseIntegratedPipeline, "HttpRuntime.UseIntegratedPipeline");

            if (null == _context) {
                _stepManager.InitRequest(); 

                _context = context; 
                _context.ApplicationInstance = this; 

                if (_context.TraceIsEnabled) 
                    HttpRuntime.Profile.StartRequest(_context);

                // this will throw if config is invalid, so we do it after HttpContext.ApplicationInstance is set
                _context.SetImpersonationEnabled(); 
            }
        } 
 
        internal IAsyncResult BeginProcessRequestNotification(HttpContext context, AsyncCallback cb) {
            Debug.Trace("PipelineRuntime", "BeginProcessRequestNotification"); 

            HttpAsyncResult result;

            if (_context == null) { 
                //
                AssignContext(context); 
            } 

            // 
            // everytime initialization
            //

            context.CurrentModuleEventIndex = -1; 

            // Create the async result 
            result = new HttpAsyncResult(cb, context); 
            context.NotificationContext.AsyncResult = result;
 
            // enter notification execution loop

            ResumeSteps(null);
 
            return result;
        } 
 
        internal RequestNotificationStatus EndProcessRequestNotification(IAsyncResult result) {
            HttpAsyncResult ar = (HttpAsyncResult)result; 
            if (ar.Error != null)
                throw ar.Error;

            return ar.Status; 
        }
 
        internal void ReleaseAppInstance() { 
            if (_context != null)
            { 
                if (_context.TraceIsEnabled) {
                    HttpRuntime.Profile.EndRequest(_context);
                }
                _context.ClearReferences(); 
                if (_timeoutManagerInitialized) {
                    HttpRuntime.RequestTimeoutManager.Remove(_context); 
                    _timeoutManagerInitialized = false; 
                }
            } 
            RecycleHandlers();
            if (AsyncResult != null) {
                AsyncResult = null;
            } 
            _context = null;
            AppEvent = null; 
            HttpApplicationFactory.RecycleApplicationInstance(this); 
        }
 
        private void AddEventMapping(string moduleName,
                                      RequestNotification requestNotification,
                                      bool isPostNotification,
                                      IExecutionStep step) { 

            ThrowIfEventBindingDisallowed(); 
 
            // Add events to the IExecutionStep containers only if
            // InitSpecial has completed and InitInternal has not completed. 
            if (!IsContainerInitalizationAllowed) {
                return;
            }
 
            Debug.Assert(!String.IsNullOrEmpty(moduleName), "!String.IsNullOrEmpty(moduleName)");
            Debug.Trace("PipelineRuntime", "AddEventMapping: for " + moduleName + 
                        " for " + requestNotification + "\r\n" ); 

 
            PipelineModuleStepContainer container = GetModuleContainer(moduleName);
            //WOS 1985878: HttpModule unsubscribing an event handler causes AV in Integrated Mode
            if (container != null) {
#if DBG 
                container.DebugModuleName = moduleName;
#endif 
                container.AddEvent(requestNotification, isPostNotification, step); 
            }
        } 

        static internal List IntegratedModuleList {
            get {
                return _moduleConfigInfo; 
            }
        } 
 
        private HttpModuleCollection GetModuleCollection(IntPtr appContext) {
            if (_moduleConfigInfo != null) { 
                return BuildIntegratedModuleCollection(_moduleConfigInfo);
            }

            List moduleList = null; 

            IntPtr pModuleCollection = IntPtr.Zero; 
            IntPtr pBstrModuleName = IntPtr.Zero; 
            int cBstrModuleName = 0;
            IntPtr pBstrModuleType = IntPtr.Zero; 
            int cBstrModuleType = 0;
            IntPtr pBstrModulePrecondition = IntPtr.Zero;
            int cBstrModulePrecondition = 0;
            try { 
                int count = 0;
                int result = UnsafeIISMethods.MgdGetModuleCollection(appContext, out pModuleCollection, out count); 
                if (result < 0) { 
                    throw new HttpException(SR.GetString(SR.Cant_Read_Native_Modules, result.ToString("X8", CultureInfo.InvariantCulture)));
                } 
                moduleList = new List(count);

                for (uint index = 0; index < count; index++) {
                    result = UnsafeIISMethods.MgdGetNextModule(pModuleCollection, ref index, 
                                                               out pBstrModuleName, out cBstrModuleName,
                                                               out pBstrModuleType, out cBstrModuleType, 
                                                               out pBstrModulePrecondition, out cBstrModulePrecondition); 
                    if (result < 0) {
                        throw new HttpException(SR.GetString(SR.Cant_Read_Native_Modules, result.ToString("X8", CultureInfo.InvariantCulture))); 
                    }
                    string moduleName = (cBstrModuleName > 0) ? StringUtil.StringFromWCharPtr(pBstrModuleName, cBstrModuleName) : null;
                    string moduleType = (cBstrModuleType > 0) ? StringUtil.StringFromWCharPtr(pBstrModuleType, cBstrModuleType) : null;
                    string modulePrecondition = (cBstrModulePrecondition > 0) ? StringUtil.StringFromWCharPtr(pBstrModulePrecondition, cBstrModulePrecondition) : String.Empty; 
                    Marshal.FreeBSTR(pBstrModuleName);
                    pBstrModuleName = IntPtr.Zero; 
                    cBstrModuleName = 0; 
                    Marshal.FreeBSTR(pBstrModuleType);
                    pBstrModuleType = IntPtr.Zero; 
                    cBstrModuleType = 0;
                    Marshal.FreeBSTR(pBstrModulePrecondition);
                    pBstrModulePrecondition = IntPtr.Zero;
                    cBstrModulePrecondition = 0; 

                    if (!String.IsNullOrEmpty(moduleName) && !String.IsNullOrEmpty(moduleType)) { 
                        moduleList.Add(new ModuleConfigurationInfo(moduleName, moduleType, modulePrecondition)); 
                    }
                } 
            }
            finally {
                if (pModuleCollection != IntPtr.Zero) {
                    Marshal.Release(pModuleCollection); 
                    pModuleCollection = IntPtr.Zero;
                } 
                if (pBstrModuleName != IntPtr.Zero) { 
                    Marshal.FreeBSTR(pBstrModuleName);
                    pBstrModuleName = IntPtr.Zero; 
                }
                if (pBstrModuleType != IntPtr.Zero) {
                    Marshal.FreeBSTR(pBstrModuleType);
                    pBstrModuleType = IntPtr.Zero; 
                }
                if (pBstrModulePrecondition != IntPtr.Zero) { 
                    Marshal.FreeBSTR(pBstrModulePrecondition); 
                    pBstrModulePrecondition = IntPtr.Zero;
                } 
            }

            _moduleConfigInfo = moduleList;
 
            return BuildIntegratedModuleCollection(_moduleConfigInfo);
        } 
 
        HttpModuleCollection BuildIntegratedModuleCollection(List moduleList) {
            HttpModuleCollection modules = new HttpModuleCollection(); 

            foreach(ModuleConfigurationInfo mod in moduleList) {
#if DBG
                Debug.Trace("NativeConfig", "Runtime module: " + mod.Name + " of type " + mod.Type + "\n"); 
#endif
                ModulesEntry currentModule = new ModulesEntry(mod.Name, mod.Type, "type", null); 
 
                modules.AddModule(currentModule.ModuleName, currentModule.Create());
            } 

            return modules;
        }
 
        //
        // Internal classes to support [asynchronous] app execution logic 
        // 

        internal class AsyncAppEventHandler { 
            int _count;
            ArrayList _beginHandlers;
            ArrayList _endHandlers;
            ArrayList _stateObjects; 

            internal AsyncAppEventHandler() { 
                _count = 0; 
                _beginHandlers = new ArrayList();
                _endHandlers   = new ArrayList(); 
                _stateObjects  = new ArrayList();
            }

            internal void Reset() { 
                _count = 0;
                _beginHandlers.Clear(); 
                _endHandlers.Clear(); 
                _stateObjects.Clear();
            } 

            internal int Count {
                get {
                    return _count; 
                }
            } 
 
            internal void Add(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
                _beginHandlers.Add(beginHandler); 
                _endHandlers.Add(endHandler);
                _stateObjects.Add(state);
                _count++;
            } 

            internal void CreateExecutionSteps(HttpApplication app, ArrayList steps) { 
                for (int i = 0; i < _count; i++) { 
                    steps.Add(new AsyncEventExecutionStep(
                        app, 
                        (BeginEventHandler)_beginHandlers[i],
                        (EndEventHandler)_endHandlers[i],
                        _stateObjects[i]));
                } 
            }
        } 
 
        internal class AsyncAppEventHandlersTable {
            private Hashtable _table; 

            internal void AddHandler(Object eventId, BeginEventHandler beginHandler,
                                     EndEventHandler endHandler, Object state,
                                     RequestNotification requestNotification, 
                                     bool isPost, HttpApplication app) {
                if (_table == null) 
                    _table = new Hashtable(); 

                AsyncAppEventHandler asyncHandler = (AsyncAppEventHandler)_table[eventId]; 

                if (asyncHandler == null) {
                    asyncHandler = new AsyncAppEventHandler();
                    _table[eventId] = asyncHandler; 
                }
 
                asyncHandler.Add(beginHandler, endHandler, state); 

                if (HttpRuntime.UseIntegratedPipeline) { 
                    AsyncEventExecutionStep step =
                        new AsyncEventExecutionStep(app,
                                                    beginHandler,
                                                    endHandler, 
                                                    state);
 
                    app.AddEventMapping(app.CurrentModuleCollectionKey, requestNotification, isPost, step); 
                }
            } 

            internal AsyncAppEventHandler this[Object eventId] {
                get {
                    if (_table == null) 
                        return null;
                    return (AsyncAppEventHandler)_table[eventId]; 
                } 
            }
        } 

        // interface to represent one execution step
        internal interface IExecutionStep {
            void Execute(); 
            bool CompletedSynchronously { get;}
            bool IsCancellable { get; } 
        } 

        // execution step -- stub 
        internal class NoopExecutionStep : IExecutionStep {
            internal NoopExecutionStep() {
            }
 
            void IExecutionStep.Execute() {
            } 
 
            bool IExecutionStep.CompletedSynchronously {
                get { return true;} 
            }

            bool IExecutionStep.IsCancellable {
                get { return false; } 
            }
        } 
 
        // execution step -- call synchronous event
        internal class SyncEventExecutionStep : IExecutionStep { 
            private HttpApplication _application;
            private EventHandler    _handler;

            internal SyncEventExecutionStep(HttpApplication app, EventHandler handler) { 
                _application = app;
                _handler = handler; 
            } 

            internal EventHandler Handler { 
                get {
                    return _handler;
                }
            } 

            void IExecutionStep.Execute() { 
                string targetTypeStr = null; 

                if (_handler != null) { 
                    if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) {
                        targetTypeStr = _handler.Method.ReflectedType.ToString();

                        EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_ENTER, _application.Context.WorkerRequest, targetTypeStr); 
                    }
                    _handler(_application, _application.AppEvent); 
                    if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_LEAVE, _application.Context.WorkerRequest, targetTypeStr); 
                }
            } 

            bool IExecutionStep.CompletedSynchronously {
                [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
                get { return true;} 
            }
 
            bool IExecutionStep.IsCancellable { 
                [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
                get { return true; } 
            }
        }

        // execution step -- call asynchronous event 
        internal class AsyncEventExecutionStep : IExecutionStep {
            private HttpApplication     _application; 
            private BeginEventHandler   _beginHandler; 
            private EndEventHandler     _endHandler;
            private Object              _state; 
            private AsyncCallback       _completionCallback;
            private bool                _[....];          // per call
            private string              _targetTypeStr;
 
            internal AsyncEventExecutionStep(HttpApplication app, BeginEventHandler beginHandler, EndEventHandler endHandler, Object state)
                :this(app, beginHandler, endHandler, state, HttpRuntime.UseIntegratedPipeline) 
                { 
                }
 
            internal AsyncEventExecutionStep(HttpApplication app, BeginEventHandler beginHandler, EndEventHandler endHandler, Object state, bool useIntegratedPipeline) {

                _application = app;
                _beginHandler = beginHandler; 
                _endHandler = endHandler;
                _state = state; 
                _completionCallback = new AsyncCallback(this.OnAsyncEventCompletion); 
            }
 
            private void OnAsyncEventCompletion(IAsyncResult ar) {
                if (ar.CompletedSynchronously)  // handled in Execute()
                    return;
 
                Debug.Trace("PipelineRuntime", "AsyncStep.OnAsyncEventCompletion");
                HttpContext context = _application.Context; 
                Exception error = null; 

                try { 
                    _endHandler(ar);
                }
                catch (Exception e) {
                    error = e; 
                }
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_LEAVE, context.WorkerRequest, _targetTypeStr); 

                // re-set start time after an async completion (see VSWhidbey 231010) 
                context.SetStartTime();

                // Assert to disregard the user code up the stack
                ResumeStepsWithAssert(error); 
            }
 
            [PermissionSet(SecurityAction.Assert, Unrestricted=true)] 
            void ResumeStepsWithAssert(Exception error) {
                _application.ResumeStepsFromThreadPoolThread(error); 
            }

            void IExecutionStep.Execute() {
                _[....] = false; 

                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) { 
                    _targetTypeStr = _beginHandler.Method.ReflectedType.ToString(); 
                    EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_ENTER, _application.Context.WorkerRequest, _targetTypeStr);
                } 

                IAsyncResult ar = _beginHandler(_application, _application.AppEvent, _completionCallback, _state);

                if (ar.CompletedSynchronously) { 
                    _[....] = true;
                    _endHandler(ar); 
 
                    if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_LEAVE, _application.Context.WorkerRequest, _targetTypeStr);
                } 
            }

            bool IExecutionStep.CompletedSynchronously {
                get { return _[....];} 
            }
 
            bool IExecutionStep.IsCancellable { 
                get { return false; }
            } 
        }

        // execution step -- validate the path for canonicalization issues
        internal class ValidatePathExecutionStep : IExecutionStep { 
            private HttpApplication _application;
 
            internal ValidatePathExecutionStep(HttpApplication app) { 
                _application = app;
            } 

            void IExecutionStep.Execute() {
                _application.Context.ValidatePath();
            } 

            bool IExecutionStep.CompletedSynchronously { 
                get { return true; } 
            }
 
            bool IExecutionStep.IsCancellable {
                get { return false; }
            }
        } 

        // execution step -- validate request (virtual path, query string, entity body, etc) 
        internal class ValidateRequestExecutionStep : IExecutionStep { 
            private HttpApplication _application;
 
            internal ValidateRequestExecutionStep(HttpApplication app) {
                _application = app;
            }
 
            void IExecutionStep.Execute() {
                _application.Context.Request.ValidateInputIfRequiredByConfig(); 
            } 

            bool IExecutionStep.CompletedSynchronously { 
                get { return true; }
            }

            bool IExecutionStep.IsCancellable { 
                get { return false; }
            } 
        } 

        // materialize handler for integrated pipeline 
        // this does not map handler, rather that's done by the core
        // this does instantiate the managed type so that things that need to
        // look at it can
        internal class MaterializeHandlerExecutionStep : IExecutionStep { 
            private HttpApplication _application;
 
            internal MaterializeHandlerExecutionStep(HttpApplication app) { 
                _application = app;
            } 

            void IExecutionStep.Execute() {
                HttpContext context = _application.Context;
                HttpRequest request = context.Request; 
                IHttpHandler handler = null;
                string configType = null; 
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_ENTER, context.WorkerRequest);
 
                IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest;

                // Get handler
                if (context.RemapHandlerInstance != null){ 
                    //RemapHandler overrides all
                    context.Handler = context.RemapHandlerInstance; 
                } 
                else if (request.RewrittenUrl != null) {
                    // RewritePath, we need to re-map the handler 
                    bool handlerExists;
                    configType = wr.ReMapHandlerAndGetHandlerTypeString(context, request.Path, out handlerExists);
                    if (!handlerExists) {
                        // WOS 1973590: When RewritePath is used with missing handler in Integrated Mode,an empty response 200 is returned instead of 404 
                        throw new HttpException(404, SR.GetString(SR.Http_handler_not_found_for_request_type, request.RequestType));
                    } 
                } 
                else {
                    configType = wr.GetManagedHandlerType(); 
                }

                if (!String.IsNullOrEmpty(configType)) {
                    IHttpHandlerFactory factory = _application.GetFactory(configType); 
                    string pathTranslated = request.PhysicalPathInternal;
 
                    try { 
                        handler = factory.GetHandler(context, request.RequestType, request.FilePath, pathTranslated);
                    } 
                    catch (FileNotFoundException e) {
                        if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                            throw new HttpException(404, null, e);
                        else 
                            throw new HttpException(404, null);
                    } 
                    catch (DirectoryNotFoundException e) { 
                        if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                            throw new HttpException(404, null, e); 
                        else
                            throw new HttpException(404, null);
                    }
                    catch (PathTooLongException e) { 
                        if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                            throw new HttpException(414, null, e); 
                        else 
                            throw new HttpException(414, null);
                    } 

                    context.Handler = handler;

                    // Remember for recycling 
                    if (_application._handlerRecycleList == null)
                        _application._handlerRecycleList = new ArrayList(); 
                    _application._handlerRecycleList.Add(new HandlerWithFactory(handler, factory)); 
                }
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_LEAVE, context.WorkerRequest);
            }

            bool IExecutionStep.CompletedSynchronously { 
                get { return true;}
            } 
 
            bool IExecutionStep.IsCancellable {
                get { return false; } 
            }
        }

 
        // execution step -- map HTTP handler (used to be a separate module)
        internal class MapHandlerExecutionStep : IExecutionStep { 
            private HttpApplication _application; 

            internal MapHandlerExecutionStep(HttpApplication app) { 
                _application = app;
            }

            void IExecutionStep.Execute() { 
                HttpContext context = _application.Context;
                HttpRequest request = context.Request; 
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_ENTER, context.WorkerRequest);
 
                context.Handler = _application.MapHttpHandler(
                    context,
                    request.RequestType,
                    request.FilePathObject, 
                    request.PhysicalPathInternal,
                    false /*useAppConfig*/); 
                Debug.Assert(context.ConfigurationPath == context.Request.FilePathObject, "context.ConfigurationPath (" + 
                             context.ConfigurationPath + ") != context.Request.FilePath (" + context.Request.FilePath + ")");
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_LEAVE, context.WorkerRequest);
            }

            bool IExecutionStep.CompletedSynchronously { 
                get { return true;}
            } 
 
            bool IExecutionStep.IsCancellable {
                get { return false; } 
            }
        }

        // execution step -- call HTTP handler (used to be a separate module) 
        internal class CallHandlerExecutionStep : IExecutionStep {
            private HttpApplication   _application; 
            private AsyncCallback     _completionCallback; 
            private IHttpAsyncHandler _handler;       // per call
            private bool              _[....];          // per call 

            internal CallHandlerExecutionStep(HttpApplication app) {
                _application = app;
                _completionCallback = new AsyncCallback(this.OnAsyncHandlerCompletion); 
            }
 
            private void OnAsyncHandlerCompletion(IAsyncResult ar) { 
                if (ar.CompletedSynchronously)  // handled in Execute()
                    return; 

                HttpContext context = _application.Context;
                Exception error = null;
 
                try {
                    try { 
                        _handler.EndProcessRequest(ar); 
                    }
                    finally { 
                        // In Integrated mode, generate the necessary response headers
                        // after the ASP.NET handler runs.  If EndProcessRequest throws,
                        // the headers will be generated by ReportRuntimeError
                        context.Response.GenerateResponseHeadersForHandler(); 
                    }
                } 
                catch (Exception e) { 
                    if (e is ThreadAbortException || e.InnerException != null && e.InnerException is ThreadAbortException) {
                        // Response.End happened during async operation 
                        _application.CompleteRequest();
                    }
                    else {
                        error = e; 
                    }
                } 
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Information, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest);
 
                _handler = null; // not to remember

                // re-set start time after an async completion (see VSWhidbey 231010)
                context.SetStartTime(); 

                // Assert to disregard the user code up the stack 
                ResumeStepsWithAssert(error); 
            }
 
            [PermissionSet(SecurityAction.Assert, Unrestricted=true)]
            void ResumeStepsWithAssert(Exception error) {
                _application.ResumeStepsFromThreadPoolThread(error);
            } 

            void IExecutionStep.Execute() { 
                HttpContext context = _application.Context; 
                IHttpHandler handler = context.Handler;
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Information, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_ENTER, context.WorkerRequest);

                if (handler != null && HttpRuntime.UseIntegratedPipeline) {
                    IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest; 
                    if (wr != null && wr.IsHandlerExecutionDenied()) {
                        _[....] = true; 
                        HttpException error = new HttpException(403, SR.GetString(SR.Handler_access_denied)); 
                        error.SetFormatter(new PageForbiddenErrorFormatter(context.Request.Path, SR.GetString(SR.Handler_access_denied)));
                        throw error; 
                    }
                }

                if (handler == null) { 
                    _[....] = true;
                } 
                else if (handler is IHttpAsyncHandler) { 
                    // asynchronous handler
                    IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler)handler; 

                    _[....] = false;
                    _handler = asyncHandler;
                    IAsyncResult ar = asyncHandler.BeginProcessRequest(context, _completionCallback, null); 

                    if (ar.CompletedSynchronously) { 
                        _[....] = true; 
                        _handler = null; // not to remember
 
                        try {
                            asyncHandler.EndProcessRequest(ar);
                        }
                        finally { 
                            //  In Integrated mode, generate the necessary response headers
                            //  after the ASP.NET handler runs 
                            context.Response.GenerateResponseHeadersForHandler(); 
                        }
 
                        if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Information, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest);
                    }
                }
                else { 
                    // synchronous handler
                    _[....] = true; 
 
                    // disable async operations
                    //_application.SyncContext.Disable(); 

                    // make sure completions of async operations don't block
                    // to enable [....] handlers that poll for async completions
                    context.SyncContext.SetSyncCaller(); 

                    try { 
                        handler.ProcessRequest(context); 
                    }
                    finally { 
                        context.SyncContext.ResetSyncCaller();
                        if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Information, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest);

                        // In Integrated mode, generate the necessary response headers 
                        // after the ASP.NET handler runs
                        context.Response.GenerateResponseHeadersForHandler(); 
                    } 
                }
            } 

            bool IExecutionStep.CompletedSynchronously {
                get { return _[....];}
            } 

            bool IExecutionStep.IsCancellable { 
                // launching of async handler should not be cancellable 
                get { return (_application.Context.Handler is IHttpAsyncHandler) ? false : true; }
            } 
        }

        // execution step -- call response filter
        internal class CallFilterExecutionStep : IExecutionStep { 
            private HttpApplication _application;
 
            internal CallFilterExecutionStep(HttpApplication app) { 
                _application = app;
            } 

            void IExecutionStep.Execute() {
                try {
                    _application.Context.Response.FilterOutput(); 
                }
                finally { 
                    // if this is the UpdateCache notification, then disable the LogRequest notification (which handles the error case) 
                    if (HttpRuntime.UseIntegratedPipeline && (_application.Context.CurrentNotification == RequestNotification.UpdateRequestCache)) {
                        _application.Context.DisableNotifications(RequestNotification.LogRequest, 0 /*postNotifications*/); 
                    }
                }
            }
 
            bool IExecutionStep.CompletedSynchronously {
                get { return true;} 
            } 

            bool IExecutionStep.IsCancellable { 
                get { return true; }
            }
        }
 
        // integrated pipeline execution step for RaiseOnPreSendRequestHeaders and RaiseOnPreSendRequestContent
        internal class SendResponseExecutionStep : IExecutionStep { 
            private HttpApplication _application; 
            private EventHandler _handler;
            private bool _isHeaders; 

            internal SendResponseExecutionStep(HttpApplication app, EventHandler handler, bool isHeaders) {
                _application = app;
                _handler = handler; 
                _isHeaders = isHeaders;
            } 
 
            void IExecutionStep.Execute() {
 
                // IIS only has a SendResponse notification, so we check the flags
                // to determine whether this notification is for headers or content.
                // The step uses _isHeaders to keep track of whether this is for headers or content.
                if (_application.Context.IsSendResponseHeaders && _isHeaders 
                    || !_isHeaders) {
 
                    string targetTypeStr = null; 

                    if (_handler != null) { 
                        if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) {
                            targetTypeStr = _handler.Method.ReflectedType.ToString();

                            EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_ENTER, _application.Context.WorkerRequest, targetTypeStr); 
                        }
                        _handler(_application, _application.AppEvent); 
                        if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_LEAVE, _application.Context.WorkerRequest, targetTypeStr); 
                    }
                } 
            }

            bool IExecutionStep.CompletedSynchronously {
                get { return true;} 
            }
 
            bool IExecutionStep.IsCancellable { 
                get { return true; }
            } 
        }

        internal class UrlMappingsExecutionStep : IExecutionStep {
            private HttpApplication _application; 

 
            internal UrlMappingsExecutionStep(HttpApplication app) { 
                _application = app;
            } 

            void IExecutionStep.Execute() {
                HttpContext context = _application.Context;
                UrlMappingsModule.UrlMappingRewritePath(context); 
            }
 
            bool IExecutionStep.CompletedSynchronously { 
                get { return true;}
            } 

            bool IExecutionStep.IsCancellable {
                get { return false; }
            } 
        }
 
        internal abstract class StepManager { 
            protected HttpApplication _application;
            protected bool _requestCompleted; 

            internal StepManager(HttpApplication application) {
                _application = application;
            } 

            internal bool IsCompleted { get { return _requestCompleted; } } 
 
            internal abstract void BuildSteps(WaitCallback stepCallback);
 
            internal void CompleteRequest() {
                _requestCompleted = true;
                if (HttpRuntime.UseIntegratedPipeline) {
                    HttpContext context = _application.Context; 
                    if (context != null && context.NotificationContext != null) {
                        context.NotificationContext.RequestCompleted = true; 
                    } 
                }
            } 

            internal abstract void InitRequest();

            internal abstract void ResumeSteps(Exception error); 
        }
 
        internal class ApplicationStepManager : StepManager { 
            private IExecutionStep[] _execSteps;
            private WaitCallback _resumeStepsWaitCallback; 
            private int _currentStepIndex;
            private int _numStepCalls;
            private int _numSyncStepCalls;
            private int _endRequestStepIndex; 

            internal ApplicationStepManager(HttpApplication app): base(app) { 
            } 

            internal override void BuildSteps(WaitCallback stepCallback ) { 
                ArrayList steps = new ArrayList();
                HttpApplication app = _application;

                bool urlMappingsEnabled = false; 
                UrlMappingsSection urlMappings = RuntimeConfig.GetConfig().UrlMappings;
                urlMappingsEnabled = urlMappings.IsEnabled && ( urlMappings.UrlMappings.Count > 0 ); 
 
                steps.Add(new ValidateRequestExecutionStep(app));
                steps.Add(new ValidatePathExecutionStep(app)); 

                if (urlMappingsEnabled)
                    steps.Add(new UrlMappingsExecutionStep(app)); // url mappings
 
                app.CreateEventExecutionSteps(HttpApplication.EventBeginRequest, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventAuthenticateRequest, steps); 
                app.CreateEventExecutionSteps(HttpApplication.EventDefaultAuthentication, steps); 
                app.CreateEventExecutionSteps(HttpApplication.EventPostAuthenticateRequest, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventAuthorizeRequest, steps); 
                app.CreateEventExecutionSteps(HttpApplication.EventPostAuthorizeRequest, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventResolveRequestCache, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPostResolveRequestCache, steps);
                steps.Add(new MapHandlerExecutionStep(app));     // map handler 
                app.CreateEventExecutionSteps(HttpApplication.EventPostMapRequestHandler, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventAcquireRequestState, steps); 
                app.CreateEventExecutionSteps(HttpApplication.EventPostAcquireRequestState, steps); 
                app.CreateEventExecutionSteps(HttpApplication.EventPreRequestHandlerExecute, steps);
                steps.Add(new CallHandlerExecutionStep(app));  // execute handler 
                app.CreateEventExecutionSteps(HttpApplication.EventPostRequestHandlerExecute, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventReleaseRequestState, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPostReleaseRequestState, steps);
                steps.Add(new CallFilterExecutionStep(app));  // filtering 
                app.CreateEventExecutionSteps(HttpApplication.EventUpdateRequestCache, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPostUpdateRequestCache, steps); 
                _endRequestStepIndex = steps.Count; 
                app.CreateEventExecutionSteps(HttpApplication.EventEndRequest, steps);
                steps.Add(new NoopExecutionStep()); // the last is always there 

                _execSteps = new IExecutionStep[steps.Count];
                steps.CopyTo(_execSteps);
 
                // callback for async completion when reposting to threadpool thread
                _resumeStepsWaitCallback = stepCallback; 
            } 

            internal override void InitRequest() { 
                _currentStepIndex   = -1;
                _numStepCalls       = 0;
                _numSyncStepCalls   = 0;
                _requestCompleted   = false; 
            }
 
            // This attribute prevents undesirable 'just-my-code' debugging behavior (VSWhidbey 404406/VSWhidbey 609188) 
            [System.Diagnostics.DebuggerStepperBoundaryAttribute]
            internal override void ResumeSteps(Exception error) { 
                bool appCompleted  = false;
                bool stepCompletedSynchronously = true;
                HttpApplication app = _application;
                HttpContext context = app.Context; 
                ThreadContext threadContext = null;
                AspNetSynchronizationContext syncContext = context.SyncContext; 
 
                Debug.Trace("Async", "HttpApplication.ResumeSteps");
 
                lock (_application) {
                    // avoid ---- between the app code and fast async completion from a module

                    try { 
                        threadContext = app.OnThreadEnter();
                    } 
                    catch (Exception e) { 
                        if (error == null)
                            error = e; 
                    }

                    try {
                        try { 
                            for (;;) {
                                // record error 
 
                                if (syncContext.Error != null) {
                                    error = syncContext.Error; 
                                    syncContext.ClearError();
                                }

                                if (error != null) { 
                                    app.RecordError(error);
                                    error = null; 
                                } 

                                // check for any outstanding async operations 

                                if (syncContext.PendingOperationsCount > 0) {
#if DBG
                                    Debug.Trace("Async", "Application has " + syncContext.PendingOperationsCount + " pending async operations"); 
#endif
                                    // wait until all pending async operations complete 
                                    syncContext.SetLastCompletionWorkItem(_resumeStepsWaitCallback); 
                                    break;
                                } 

                                // advance to next step

                                if (_currentStepIndex < _endRequestStepIndex && (context.Error != null || _requestCompleted)) { 
                                    // end request
                                    context.Response.FilterOutput(); 
                                    _currentStepIndex = _endRequestStepIndex; 
                                }
                                else { 
                                    _currentStepIndex++;
                                }

                                if (_currentStepIndex >= _execSteps.Length) { 
                                    appCompleted = true;
                                    break; 
                                } 

                                // execute the current step 

                                _numStepCalls++;          // count all calls

                                // enable launching async operations before each new step 
                                context.SyncContext.Enable();
 
                                // call to execute current step catching thread abort exception 
                                error = app.ExecuteStep(_execSteps[_currentStepIndex], ref stepCompletedSynchronously);
 
                                // unwind the stack in the async case
                                if (!stepCompletedSynchronously)
                                    break;
 
                                _numSyncStepCalls++;      // count synchronous calls
                            } 
                        } 
                        finally {
                            if (threadContext != null) { 
                                try {
                                    threadContext.Leave();
                                }
                                catch { 
                                }
                            } 
                        } 
                    }
                    catch { // Protect against exception filters 
                        throw;
                    }

                }   // lock 

                if (appCompleted) { 
                    // unroot context (async app operations ended) 
                    context.Unroot();
 
                    // async completion
                    app.AsyncResult.Complete((_numStepCalls == _numSyncStepCalls), null, null);
                    app.ReleaseAppInstance();
                } 
            }
        } 
 
        internal class PipelineStepManager : StepManager {
 
            WaitCallback _resumeStepsWaitCallback;
            bool _validatePathCalled;
            bool _validateInputCalled;
 
            internal PipelineStepManager(HttpApplication app): base(app) {
            } 
 
            internal override void BuildSteps(WaitCallback stepCallback) {
                Debug.Trace("PipelineRuntime", "BuildSteps"); 
                //ArrayList steps = new ArrayList();
                HttpApplication app = _application;

                // add special steps that don't currently 
                // correspond to a configured handler
 
                IExecutionStep materializeStep = new MaterializeHandlerExecutionStep(app); 

                // implicit map step 
                app.AddEventMapping(
                    HttpApplication.IMPLICIT_HANDLER,
                    RequestNotification.MapRequestHandler,
                    false, materializeStep); 

                // implicit handler routing step 
                IExecutionStep handlerStep = new CallHandlerExecutionStep(app); 

                app.AddEventMapping( 
                    HttpApplication.IMPLICIT_HANDLER,
                    RequestNotification.ExecuteRequestHandler,
                    false, handlerStep);
 
                // add implicit request filtering step
                IExecutionStep filterStep = new CallFilterExecutionStep(app); 
 
                // normally, this executes during UpdateRequestCache as a high priority module
                app.AddEventMapping( 
                    HttpApplication.IMPLICIT_FILTER_MODULE,
                    RequestNotification.UpdateRequestCache,
                    false, filterStep);
 
                // for error conditions, this executes during LogRequest as a high priority module
                app.AddEventMapping( 
                    HttpApplication.IMPLICIT_FILTER_MODULE, 
                    RequestNotification.LogRequest,
                    false, filterStep); 

                _resumeStepsWaitCallback = stepCallback;
            }
 
            internal override void InitRequest() {
                _requestCompleted = false; 
                _validatePathCalled = false; 
                _validateInputCalled = false;
            } 

            // PipelineStepManager::ResumeSteps
            // called from IIS7 (on IIS thread) via BeginProcessRequestNotification
            // or from an async completion (on CLR thread) via HttpApplication::ResumeStepsFromThreadPoolThread 
            // This attribute prevents undesirable 'just-my-code' debugging behavior (VSWhidbey 404406/VSWhidbey 609188)
            [System.Diagnostics.DebuggerStepperBoundaryAttribute] 
            internal override void ResumeSteps(Exception error) { 
                HttpContext context = _application.Context;
                IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest; 
                AspNetSynchronizationContext syncContext = context.SyncContext;

                RequestNotificationStatus status = RequestNotificationStatus.Continue;
                HttpApplication.ThreadContext threadContext = null; 
                bool isSynchronousCompletion = false;
                bool needToComplete = false; 
                bool stepCompletedSynchronously = false; 
                int currentModuleLastEventIndex = _application.CurrentModuleContainer.GetEventCount(context.CurrentNotification, context.IsPostNotification) - 1;
 
                // DevDiv Bugs 187441: IIS7 Integrated Mode: Problem flushing Response from background threads in IIS7 integrated mode
                bool isReEntry = context.NotificationContext.IsReEntry;
                if (!isReEntry) // currently we only re-enter for SendResponse
                { 
#pragma warning disable 0618
                    //@ 
                    Monitor.Enter(_application); 
#pragma warning restore 0618
                } 
                try {
                    bool locked = false;
                    try {
                        // As a performance optimization, ASP.NET uses the IIS IHttpContext::IndicateCompletion function to continue executing notifications 
                        // on a thread that is associated with the AppDomain.  This is done by calling IndicateCompletion from within the AppDomain, instead
                        // of returning to native code.  This technique can only be used for notifications that complete synchronously. 
 
                        // There are two cases where notifications happen on a thread that has an initialized ThreadContext, and therefore does not need
                        // to call ThreadContext.OnThreadEnter.  These include SendResponse notifications and notifications that occur within a call to 
                        // IndicateCompletion.  Note that SendResponse notifications occur on-demand, i.e., they happen when another notification triggers
                        // a SendResponse, at which point it blocks until the SendResponse notification completes.

                        if (!isReEntry) { // currently we only re-enter for SendResponse 
                            if (context.InIndicateCompletion) {
                                // we already have a ThreadContext 
                                threadContext = context.IndicateCompletionContext; 
                                if (context.UsesImpersonation) {
                                    // UsesImpersonation is set to true after RQ_AUTHENTICATE_REQUEST 
                                    threadContext.SetImpersonationContext();
                                }
                            }
                            else { 
                                // we need to create a new ThreadContext
                                threadContext = _application.OnThreadEnter(context.UsesImpersonation); 
                            } 
                        }
 
                        for(;;) {
#if DBG
                            Debug.Trace("PipelineRuntime", "ResumeSteps: CurrentModuleEventIndex=" + context.CurrentModuleEventIndex);
#endif 

                            // check and record errors into the HttpContext 
                            if (syncContext.Error != null) { 
                                error = syncContext.Error;
                                syncContext.ClearError(); 
                            }
                            if (error != null) {
                                // the error can be cleared by the user
                                _application.RecordError(error); 
                                error = null;
                            } 
 
                            if (!_validateInputCalled || !_validatePathCalled) {
                                error = ValidateHelper(context); 
                                if (error != null) {
                                    continue;
                                }
                            } 

                            // check for any outstanding async operations 
                            if (syncContext.PendingOperationsCount > 0) { 
#if DBG
                                Debug.Trace("Async", "Application has " + syncContext.PendingOperationsCount + " pending async operations"); 
#endif
                                // Since the step completed asynchronously, this thread must return RequestNotificationStatus.Pending to IIS,
                                // and the async completion of this step must call IIS7WorkerRequest::PostCompletion.  The async completion of
                                // this step will call ResumeSteps again. 
                                 context.NotificationContext.PendingAsyncCompletion = true;
 
                                // wait until all pending async operations complete 
                                syncContext.SetLastCompletionWorkItem(_resumeStepsWaitCallback);
 
                                break;
                            }

                            // LogRequest and EndRequest never report errors, and never return a status of FinishRequest. 
                            bool needToFinishRequest = ( context.NotificationContext.Error != null || context.NotificationContext.RequestCompleted )
                                && context.CurrentNotification != RequestNotification.LogRequest 
                                && context.CurrentNotification != RequestNotification.EndRequest; 

                            if (needToFinishRequest || context.CurrentModuleEventIndex == currentModuleLastEventIndex) { 

                                // if an error occured or someone completed the request, set the status to FinishRequest
                                status = needToFinishRequest ? RequestNotificationStatus.FinishRequest : RequestNotificationStatus.Continue;
 
                                // async case
                                if (context.NotificationContext.PendingAsyncCompletion) { 
                                    context.Response.SyncStatusIntegrated(); 
                                    context.NotificationContext.PendingAsyncCompletion = false;
                                    isSynchronousCompletion = false; 
                                    needToComplete = true;
                                    break;
                                }
 
                                // [....] case (we might be able to stay in managed code and execute another notification)
                                if (needToFinishRequest || UnsafeIISMethods.MgdGetNextNotification(wr.RequestContext, RequestNotificationStatus.Continue) != 1) { 
                                    isSynchronousCompletion = true; 
                                    needToComplete = true;
                                    break; 
                                }

                                int currentModuleIndex = 0;
                                bool isPostNotification = false; 
                                int currentNotification = 0;
 
                                UnsafeIISMethods.MgdGetCurrentNotificationInfo(wr.RequestContext, out currentModuleIndex, out isPostNotification, out currentNotification); 

                                // setup the HttpContext for this event/module combo 
                                context.CurrentModuleIndex = currentModuleIndex;
                                context.IsPostNotification = isPostNotification;
                                context.CurrentNotification = (RequestNotification) currentNotification;
                                context.CurrentModuleEventIndex = -1; 
                                currentModuleLastEventIndex = _application.CurrentModuleContainer.GetEventCount(context.CurrentNotification, context.IsPostNotification) - 1;
                            } 
 
                            context.CurrentModuleEventIndex++;
 
                            IExecutionStep step = _application.CurrentModuleContainer.GetNextEvent(context.CurrentNotification, context.IsPostNotification,
                                                                                                   context.CurrentModuleEventIndex);

                            // enable launching async operations before each new step 
                            context.SyncContext.Enable();
 
                            stepCompletedSynchronously = false; 
                            error = _application.ExecuteStep(step, ref stepCompletedSynchronously);
 
#if DBG
                            Debug.Trace("PipelineRuntime", "ResumeSteps: notification=" + context.CurrentNotification.ToString()
                                        + ", isPost=" + context.IsPostNotification
                                        + ", step=" + step.GetType().FullName 
                                        + ", completedSync="  + stepCompletedSynchronously
                                        + ", moduleName=" + _application.CurrentModuleContainer.DebugModuleName 
                                        + ", moduleIndex=" + context.CurrentModuleIndex 
                                        + ", eventIndex=" + context.CurrentModuleEventIndex);
#endif 


                            if (!stepCompletedSynchronously) {
                                // Since the step completed asynchronously, this thread must return RequestNotificationStatus.Pending to IIS, 
                                // and the async completion of this step must call IIS7WorkerRequest::PostCompletion.  The async completion of
                                // this step will call ResumeSteps again. 
                                //context.AcquireNotifcationContextLockBeforeUnwind(); 
                                _application.AcquireNotifcationContextLock(ref locked);
                                context.NotificationContext.PendingAsyncCompletion = true; 
                                break;
                            }
                            else {
                                context.Response.SyncStatusIntegrated(); 
                            }
                        } 
                    } 
                    finally {
                        if (locked) { 
                            _application.ReleaseNotifcationContextLock();
                        }
                        if (threadContext != null) {
                            if (context.InIndicateCompletion) { 
                                if (isSynchronousCompletion) {
                                    // this is a [....] completion on an IIS thread 
                                    threadContext.Synchronize(context); 
                                    //always undo impersonation so that the token is removed before returning to IIS (DDB 156421)
                                    threadContext.UndoImpersonationContext(); 
                                }
                                else {
                                    // We're returning pending on an IIS thread in a call to IndicateCompletion.
                                    // Leave the thread context now while we're still under the lock so that the 
                                    // async completion does not corrupt the state of HttpContext or IndicateCompletionContext.
                                    if (!threadContext.HasLeaveBeenCalled) { 
                                        lock (threadContext) { 
                                            if (!threadContext.HasLeaveBeenCalled) {
                                                threadContext.Leave(); 
                                                context.IndicateCompletionContext = null;
                                                context.InIndicateCompletion = false;
                                            }
                                        } 
                                    }
                                } 
                            } 
                            else if (isSynchronousCompletion){
                                // this is a [....] completion on an IIS thread 
                                threadContext.Synchronize(context);
                                // get ready to call IndicateCompletion
                                context.IndicateCompletionContext = threadContext;
                                //always undo impersonation so that the token is removed before returning to IIS (DDB 156421) 
                                threadContext.UndoImpersonationContext();
                            } 
                            else { 
                                // We're not in a call to IndicateCompletion.  We're either returning pending or
                                // we're in an async completion, and therefore we must clean-up the thread state. Impersonation is reverted 
                                threadContext.Leave();
                            }
                        }
                    } 

                    // WOS #1703315: we cannot complete until after OnThreadLeave is called. 
                    if (needToComplete) { 
                        // call HttpRuntime::OnRequestNotificationCompletion
                        _application.AsyncResult.Complete(isSynchronousCompletion, null /*result*/, null /*error*/, status); 
                    }
                } // end of try statement that begins after Monitor.Enter(_application)
                finally {
                    if (!isReEntry) 
                    {
                        Monitor.Exit(_application); 
                    } 
                }
            } 

            private Exception ValidateHelper(HttpContext context) {
                if (!_validateInputCalled) {
                    _validateInputCalled = true; 
                    try {
                        context.Request.ValidateInputIfRequiredByConfig(); 
                    } 
                    catch(Exception e) {
                        return e; 
                    }
                }
                if (!_validatePathCalled) {
                    _validatePathCalled = true; 
                    try {
                        context.ValidatePath(); 
                    } 
                    catch(Exception e) {
                        return e; 
                    }
                }
                return null;
            } 
        }
    } 
} 

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

namespace System.Web { 
    using System.Runtime.Serialization.Formatters; 
    using System.IO;
    using System.Threading; 
    using System.Runtime.InteropServices;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Collections; 
    using System.Reflection;
    using System.Globalization; 
    using System.Security.Principal; 
    using System.Web;
    using System.Web.SessionState; 
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.Util;
    using System.Web.Configuration; 
    using System.Web.Configuration.Common;
    using System.Web.Hosting; 
    using System.Web.Management; 
    using System.Runtime.Remoting.Messaging;
    using System.Security; 
    using System.Security.Permissions;
    using System.Collections.Generic;
    using System.Web.Compilation;
 
    using IIS = System.Web.Hosting.UnsafeIISMethods;
 
 
    //
    // Async EventHandler support 
    //


    ///  
    ///    [To be supplied.]
    ///  
    public delegate IAsyncResult BeginEventHandler(object sender, EventArgs e, AsyncCallback cb, object extraData); 

    ///  
    ///    [To be supplied.]
    /// 
    public delegate void EndEventHandler(IAsyncResult ar);
 

    ///  
    ///     
    ///       The  HttpApplication class defines the methods, properties and events common to all
    ///       HttpApplication objects within the ASP.NET Framework. 
    ///    
    /// 
    [
    ToolboxItem(false) 
    ]
    public class HttpApplication : IHttpAsyncHandler, IComponent { 
        // application state dictionary 
        private HttpApplicationState _state;
 
        // context during init for config lookups
        private HttpContext _initContext;

        // async support 
        private HttpAsyncResult _ar; // currently pending async result for call into application
 
        // list of modules 
        private HttpModuleCollection  _moduleCollection;
 
        // event handlers
        private static readonly object EventDisposed = new object();
        private static readonly object EventErrorRecorded = new object();
        private static readonly object EventPreSendRequestHeaders = new object(); 
        private static readonly object EventPreSendRequestContent = new object();
 
        private static readonly object EventBeginRequest = new object(); 
        private static readonly object EventAuthenticateRequest = new object();
        private static readonly object EventDefaultAuthentication = new object(); 
        private static readonly object EventPostAuthenticateRequest = new object();
        private static readonly object EventAuthorizeRequest = new object();
        private static readonly object EventPostAuthorizeRequest = new object();
        private static readonly object EventResolveRequestCache = new object(); 
        private static readonly object EventPostResolveRequestCache = new object();
        private static readonly object EventMapRequestHandler = new object(); 
        private static readonly object EventPostMapRequestHandler = new object(); 
        private static readonly object EventAcquireRequestState = new object();
        private static readonly object EventPostAcquireRequestState = new object(); 
        private static readonly object EventPreRequestHandlerExecute = new object();
        private static readonly object EventPostRequestHandlerExecute = new object();
        private static readonly object EventReleaseRequestState = new object();
        private static readonly object EventPostReleaseRequestState = new object(); 
        private static readonly object EventUpdateRequestCache = new object();
        private static readonly object EventPostUpdateRequestCache = new object(); 
        private static readonly object EventLogRequest = new object(); 
        private static readonly object EventPostLogRequest = new object();
        private static readonly object EventEndRequest = new object(); 
        internal static readonly string AutoCulture = "auto";

        private EventHandlerList _events;
        private AsyncAppEventHandlersTable _asyncEvents; 

        // execution steps 
        private StepManager _stepManager; 

        // callback for Application ResumeSteps 
        #pragma warning disable 0649
        private WaitCallback _resumeStepsWaitCallback;
        #pragma warning restore 0649
 
        // event passed to modules
        private EventArgs _appEvent; 
 
        // list of handler mappings
        private Hashtable _handlerFactories = new Hashtable(); 

        // list of handler/factory pairs to be recycled
        private ArrayList _handlerRecycleList;
 
        // flag to hide request and response intrinsics
        private bool _hideRequestResponse; 
 
        // application execution variables
        private HttpContext _context; 
        private Exception _lastError;  // placeholder for the error when context not avail
        private bool _timeoutManagerInitialized;

        // session (supplied by session-on-end outside of context) 
        private HttpSessionState _session;
 
        // culture (needs to be set per thread) 
        private CultureInfo _appLevelCulture;
        private CultureInfo _appLevelUICulture; 
        private CultureInfo _savedAppLevelCulture;
        private CultureInfo _savedAppLevelUICulture;
        private bool _appLevelAutoCulture;
        private bool _appLevelAutoUICulture; 

        // pipeline event mappings 
        private Dictionary _pipelineEventMasks; 

 
        // IComponent support
        private ISite _site;

        // IIS7 specific fields 
        internal const string MANAGED_PRECONDITION = "managedHandler";
        internal const string IMPLICIT_FILTER_MODULE = "AspNetFilterModule"; 
        internal const string IMPLICIT_HANDLER = "ManagedPipelineHandler"; 

        // map modules to their index 
        private static Hashtable _moduleIndexMap = new Hashtable();
        private static bool _initSpecialCompleted;

        private bool _initInternalCompleted; 
        private RequestNotification _appRequestNotifications;
        private RequestNotification _appPostNotifications; 
 
        // Set the current module init key to the global.asax module to enable
        // the custom global.asax derivation constructor to register event handlers 
        private string _currentModuleCollectionKey = HttpApplicationFactory.applicationFileName;

        // module config is read once per app domain and used to initialize the per-instance _moduleContainers array
        private static List _moduleConfigInfo; 

        // this is the per instance list that contains the events for each module 
        private PipelineModuleStepContainer[] _moduleContainers; 

        // Byte array to be used by HttpRequest.GetEntireRawContent. Windows OS Bug 1632921 
        private byte[] _entityBuffer;

        //
        // Public Application properties 
        //
 
 
        /// 
        ///     
        ///          HTTPRuntime provided context object that provides access to additional
        ///          pipeline-module exposed objects.
        ///       
        ///     
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public HttpContext Context { 
            get {
                return(_context != null) ? _context : _initContext;
            }
        } 

        private bool IsContainerInitalizationAllowed { 
            get { 
                if (HttpRuntime.UseIntegratedPipeline && _initSpecialCompleted && !_initInternalCompleted) {
                    // return true if 
                    //      i) this is integrated pipeline mode,
                    //     ii) InitSpecial has been called at least once in this AppDomain to register events with IIS,
                    //    iii) InitInternal has not been invoked yet or is currently executing
                    return true; 
                }
                return false; 
            } 
        }
 
        private void ThrowIfEventBindingDisallowed() {
            if (HttpRuntime.UseIntegratedPipeline && _initSpecialCompleted && _initInternalCompleted) {
                // throw if we're using the integrated pipeline and both InitSpecial and InitInternal have completed.
                throw new InvalidOperationException(SR.GetString(SR.Event_Binding_Disallowed)); 
            }
        } 
 
        private PipelineModuleStepContainer[] ModuleContainers {
            get { 
                if (_moduleContainers == null) {

                    Debug.Assert(_moduleIndexMap != null && _moduleIndexMap.Count > 0, "_moduleIndexMap != null && _moduleIndexMap.Count > 0");
 
                    // At this point, all modules have been registered with IIS via RegisterIntegratedEvent.
                    // Now we need to create a container for each module and add execution steps. 
                    // The number of containers is the same as the number of modules that have been 
                    // registered (_moduleIndexMap.Count).
 
                    _moduleContainers = new PipelineModuleStepContainer[_moduleIndexMap.Count];

                    for (int i = 0; i < _moduleContainers.Length; i++) {
                        _moduleContainers[i] = new PipelineModuleStepContainer(); 
                    }
 
                } 

                return _moduleContainers; 
            }
        }

        ///  
        ///    [To be supplied.]
        ///  
        public event EventHandler Disposed { 
            add {
                Events.AddHandler(EventDisposed, value); 
            }

            remove {
                Events.RemoveHandler(EventDisposed, value); 
            }
        } 
 

        ///  
        ///    [To be supplied.]
        /// 
        protected EventHandlerList Events {
            get { 
                if (_events == null) {
                    _events = new EventHandlerList(); 
                } 
                return _events;
            } 
        }

        private AsyncAppEventHandlersTable AsyncEvents {
            get { 
                if (_asyncEvents == null)
                    _asyncEvents = new AsyncAppEventHandlersTable(); 
                return _asyncEvents; 
            }
        } 

        // Last error during the processing of the current request.
        internal Exception LastError {
            get { 
                // only temporaraly public (will be internal and not related context)
                return (_context != null) ? _context.Error : _lastError; 
            } 

        } 

        // Used by HttpRequest.GetEntireRawContent. Windows OS Bug 1632921
        internal byte[] EntityBuffer
        { 
            get
            { 
                if (_entityBuffer == null) 
                {
                    _entityBuffer = new byte[8 * 1024]; 
                }
                return _entityBuffer;
            }
        } 

        internal void ClearError() { 
            _lastError = null; 
        }
 
        /// 
        ///    HTTPRuntime provided request intrinsic object that provides access to incoming HTTP
        ///       request data.
        ///  
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public HttpRequest Request { 
            get {
                HttpRequest request = null;

                if (_context != null && !_hideRequestResponse) 
                    request = _context.Request;
 
                if (request == null) 
                    throw new HttpException(SR.GetString(SR.Request_not_available));
 
                return request;
            }
        }
 

        ///  
        ///    HTTPRuntime provided 
        ///       response intrinsic object that allows transmission of HTTP response data to a
        ///       client. 
        /// 
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public HttpResponse Response { 
            get { 
                HttpResponse response = null;
 
                if (_context != null && !_hideRequestResponse)
                    response = _context.Response;

                if (response == null) 
                    throw new HttpException(SR.GetString(SR.Response_not_available));
 
                return response; 
            }
        } 


        /// 
        ///     
        ///    HTTPRuntime provided session intrinsic.
        ///     
        ///  
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public HttpSessionState Session {
            get { 
                HttpSessionState session = null;
 
                if (_session != null) 
                    session = _session;
                else if (_context != null) 
                    session = _context.Session;

                if (session == null)
                    throw new HttpException(SR.GetString(SR.Session_not_available)); 

                return session; 
            } 
        }
 

        /// 
        ///    
        ///       Returns 
        ///          a reference to an HTTPApplication state bag instance.
        ///        
        ///     
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public HttpApplicationState Application {
            get { 
                Debug.Assert(_state != null);  // app state always available
                return _state; 
            } 
        }
 

        /// 
        ///    Provides the web server Intrinsic object.
        ///  
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public HttpServerUtility Server { 
            get {
                if (_context != null)
                    return _context.Server;
                else 
                    return new HttpServerUtility(this); // special Server for application only
            } 
        } 

 
        /// 
        ///    Provides the User Intrinsic object.
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ] 
        public IPrincipal User {
            get { 
                if (_context == null)
                    throw new HttpException(SR.GetString(SR.User_not_available));

                return _context.User; 
            }
        } 
 

        ///  
        ///    
        ///       Collection
        ///          of all IHTTPModules configured for the current application.
        ///        
        ///    
        [ 
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public HttpModuleCollection Modules {
            [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.High)]
            get {
                if (_moduleCollection == null) 
                    _moduleCollection = new HttpModuleCollection();
                return _moduleCollection; 
            } 
        }
 
        // event passed to all modules
        internal EventArgs AppEvent {
            get {
                if (_appEvent == null) 
                    _appEvent = EventArgs.Empty;
 
                return _appEvent; 
            }
 
            set {
                _appEvent = null;
            }
        } 

        // DevDiv Bugs 151914: Release session state before executing child request 
        internal void EnsureReleaseState() { 
            if (_moduleCollection != null) {
                for (int i = 0; i < _moduleCollection.Count; i++) { 
                    IHttpModule module = _moduleCollection.Get(i);
                    if (module is SessionStateModule) {
                        ((SessionStateModule) module).EnsureReleaseState(this);
                        break; 
                    }
                } 
            } 
        }
 
        /// 
        ///    [To be supplied.]
        /// 
        public void CompleteRequest() { 
            //
            // Request completion (force skipping all steps until RequestEnd 
            // 
            _stepManager.CompleteRequest();
        } 

        internal bool IsRequestCompleted {
            get {
                if (null == _stepManager) { 
                    return false;
                } 
 
                return _stepManager.IsCompleted;
            } 
        }

        // Dev10 745301: Asynchronous pipeline steps can start a new thread that triggers
        // a SendResponse notification.  E.g., it might call Flush when a module is registered 
        // for PreSendRequestHeaders/Content.  If the async pipeline step returns from ExecuteStep
        // while the SendResponse notification is executing, the NotificationContext can 
        // be corrupted.  To fix this, a lock is now taken to prevent multi-threaded access when 
        // the async pipeline step sets the NotificationContext.PendingAsyncCompletion field.
        // The SendResponse notification also acquires the lock when it enters managed code and 
        // releases the lock when it leaves.
        internal void AcquireNotifcationContextLock(ref bool locked) {
            Debug.Assert(HttpRuntime.UseIntegratedPipeline, "HttpRuntime.UseIntegratedPipeline");
            Monitor.Enter(_stepManager, ref locked); 
        }
 
        internal void ReleaseNotifcationContextLock() { 
            Debug.Assert(HttpRuntime.UseIntegratedPipeline, "HttpRuntime.UseIntegratedPipeline");
            Monitor.Exit(_stepManager); 
        }

        private void RaiseOnError() {
            EventHandler handler = (EventHandler)Events[EventErrorRecorded]; 
            if (handler != null) {
                try { 
                    handler(this, AppEvent); 
                }
                catch (Exception e) { 
                    if (_context != null) {
                        _context.AddError(e);
                    }
                } 
            }
        } 
 
        internal void RaiseOnPreSendRequestHeaders() {
            EventHandler handler = (EventHandler)Events[EventPreSendRequestHeaders]; 
            if (handler != null) {
                try {
                    handler(this, AppEvent);
                } 
                catch (Exception e) {
                    RecordError(e); 
                } 
            }
        } 

        internal void RaiseOnPreSendRequestContent() {
            EventHandler handler = (EventHandler)Events[EventPreSendRequestContent];
            if (handler != null) { 
                try {
                    handler(this, AppEvent); 
                } 
                catch (Exception e) {
                    RecordError(e); 
                }
            }
        }
 
        internal HttpAsyncResult AsyncResult {
            get { 
                if (HttpRuntime.UseIntegratedPipeline) { 
                    return (_context.NotificationContext != null) ? _context.NotificationContext.AsyncResult : null;
                } 
                else {
                    return _ar;
                }
            } 
            set {
                if (HttpRuntime.UseIntegratedPipeline) { 
                    _context.NotificationContext.AsyncResult = value; 
                }
                else { 
                    _ar = value;
                }
            }
        } 

        internal void AddSyncEventHookup(object key, Delegate handler, RequestNotification notification) { 
            AddSyncEventHookup(key, handler, notification, false); 
        }
 
        private PipelineModuleStepContainer CurrentModuleContainer { get { return ModuleContainers[_context.CurrentModuleIndex]; } }

        private PipelineModuleStepContainer GetModuleContainer(string moduleName) {
            object value = _moduleIndexMap[moduleName]; 

            if (value == null) { 
                return null; 
            }
 
            int moduleIndex = (int)value;

#if DBG
            Debug.Trace("PipelineRuntime", "GetModuleContainer: moduleName=" + moduleName + ", index=" + moduleIndex.ToString(CultureInfo.InvariantCulture) + "\r\n"); 
            Debug.Assert(moduleIndex >= 0 && moduleIndex < ModuleContainers.Length, "moduleIndex >= 0 && moduleIndex < ModuleContainers.Length");
#endif 
 
            PipelineModuleStepContainer container = ModuleContainers[moduleIndex];
 
            Debug.Assert(container != null, "container != null");

            return container;
        } 

        private void AddSyncEventHookup(object key, Delegate handler, RequestNotification notification, bool isPostNotification) { 
            ThrowIfEventBindingDisallowed(); 

            // add the event to the delegate invocation list 
            // this keeps non-pipeline ASP.NET hosts working
            Events.AddHandler(key, handler);

            // For integrated pipeline mode, add events to the IExecutionStep containers only if 
            // InitSpecial has completed and InitInternal has not completed.
            if (IsContainerInitalizationAllowed) { 
                // lookup the module index and add this notification 
                PipelineModuleStepContainer container = GetModuleContainer(CurrentModuleCollectionKey);
                //WOS 1985878: HttpModule unsubscribing an event handler causes AV in Integrated Mode 
                if (container != null) {
#if DBG
                    container.DebugModuleName = CurrentModuleCollectionKey;
#endif 
                    SyncEventExecutionStep step = new SyncEventExecutionStep(this, (EventHandler)handler);
                    container.AddEvent(notification, isPostNotification, step); 
                } 
            }
        } 

        internal void RemoveSyncEventHookup(object key, Delegate handler, RequestNotification notification) {
            RemoveSyncEventHookup(key, handler, notification, false);
        } 

        internal void RemoveSyncEventHookup(object key, Delegate handler, RequestNotification notification, bool isPostNotification) { 
            ThrowIfEventBindingDisallowed(); 

            Events.RemoveHandler(key, handler); 

            if (IsContainerInitalizationAllowed) {
                PipelineModuleStepContainer container = GetModuleContainer(CurrentModuleCollectionKey);
                //WOS 1985878: HttpModule unsubscribing an event handler causes AV in Integrated Mode 
                if (container != null) {
                    container.RemoveEvent(notification, isPostNotification, handler); 
                } 
            }
        } 

        private void AddSendResponseEventHookup(object key, Delegate handler) {
            ThrowIfEventBindingDisallowed();
 
            // add the event to the delegate invocation list
            // this keeps non-pipeline ASP.NET hosts working 
            Events.AddHandler(key, handler); 

            // For integrated pipeline mode, add events to the IExecutionStep containers only if 
            // InitSpecial has completed and InitInternal has not completed.
            if (IsContainerInitalizationAllowed) {
                // lookup the module index and add this notification
                PipelineModuleStepContainer container = GetModuleContainer(CurrentModuleCollectionKey); 
                //WOS 1985878: HttpModule unsubscribing an event handler causes AV in Integrated Mode
                if (container != null) { 
#if DBG 
                    container.DebugModuleName = CurrentModuleCollectionKey;
#endif 
                    bool isHeaders = (key == EventPreSendRequestHeaders);
                    SendResponseExecutionStep step = new SendResponseExecutionStep(this, (EventHandler)handler, isHeaders);
                    container.AddEvent(RequestNotification.SendResponse, false /*isPostNotification*/, step);
                } 
            }
        } 
 
        private void RemoveSendResponseEventHookup(object key, Delegate handler) {
            ThrowIfEventBindingDisallowed(); 

            Events.RemoveHandler(key, handler);

            if (IsContainerInitalizationAllowed) { 
                PipelineModuleStepContainer container = GetModuleContainer(CurrentModuleCollectionKey);
                //WOS 1985878: HttpModule unsubscribing an event handler causes AV in Integrated Mode 
                if (container != null) { 
                    container.RemoveEvent(RequestNotification.SendResponse, false /*isPostNotification*/, handler);
                } 
            }
        }

        // 
        // [....] event hookup
        // 
 

        /// [To be supplied.] 
        public event EventHandler BeginRequest {
            add { AddSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); }
            remove { RemoveSyncEventHookup(EventBeginRequest, value, RequestNotification.BeginRequest); }
        } 

 
        /// [To be supplied.] 
        public event EventHandler AuthenticateRequest {
            add { AddSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); } 
            remove { RemoveSyncEventHookup(EventAuthenticateRequest, value, RequestNotification.AuthenticateRequest); }
        }

        // internal - for back-stop module only 
        internal event EventHandler DefaultAuthentication {
            add { AddSyncEventHookup(EventDefaultAuthentication, value, RequestNotification.AuthenticateRequest); } 
            remove { RemoveSyncEventHookup(EventDefaultAuthentication, value, RequestNotification.AuthenticateRequest); } 
        }
 

        /// [To be supplied.]
        public event EventHandler PostAuthenticateRequest {
            add { AddSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); } 
            remove { RemoveSyncEventHookup(EventPostAuthenticateRequest, value, RequestNotification.AuthenticateRequest, true); }
        } 
 

        /// [To be supplied.] 
        public event EventHandler AuthorizeRequest {
            add { AddSyncEventHookup(EventAuthorizeRequest, value, RequestNotification.AuthorizeRequest); }
            remove { RemoveSyncEventHookup(EventAuthorizeRequest, value, RequestNotification.AuthorizeRequest); }
        } 

 
        /// [To be supplied.] 
        public event EventHandler PostAuthorizeRequest {
            add { AddSyncEventHookup(EventPostAuthorizeRequest, value, RequestNotification.AuthorizeRequest, true); } 
            remove { RemoveSyncEventHookup(EventPostAuthorizeRequest, value, RequestNotification.AuthorizeRequest, true); }
        }

 
        /// [To be supplied.]
        public event EventHandler ResolveRequestCache { 
            add { AddSyncEventHookup(EventResolveRequestCache, value, RequestNotification.ResolveRequestCache); } 
            remove { RemoveSyncEventHookup(EventResolveRequestCache, value, RequestNotification.ResolveRequestCache); }
        } 


        /// [To be supplied.]
        public event EventHandler PostResolveRequestCache { 
            add { AddSyncEventHookup(EventPostResolveRequestCache, value, RequestNotification.ResolveRequestCache, true); }
            remove { RemoveSyncEventHookup(EventPostResolveRequestCache, value, RequestNotification.ResolveRequestCache, true); } 
        } 

        public event EventHandler MapRequestHandler { 
            add {
                if (!HttpRuntime.UseIntegratedPipeline) {
                    throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode));
                } 
                AddSyncEventHookup(EventMapRequestHandler, value, RequestNotification.MapRequestHandler);
            } 
            remove { 
                if (!HttpRuntime.UseIntegratedPipeline) {
                    throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
                }
                RemoveSyncEventHookup(EventMapRequestHandler, value, RequestNotification.MapRequestHandler);
            }
        } 

        /// [To be supplied.] 
        public event EventHandler PostMapRequestHandler { 
            add { AddSyncEventHookup(EventPostMapRequestHandler, value, RequestNotification.MapRequestHandler, true); }
            remove { RemoveSyncEventHookup(EventPostMapRequestHandler, value, RequestNotification.MapRequestHandler); } 
        }


        /// [To be supplied.] 
        public event EventHandler AcquireRequestState {
            add { AddSyncEventHookup(EventAcquireRequestState, value, RequestNotification.AcquireRequestState); } 
            remove { RemoveSyncEventHookup(EventAcquireRequestState, value, RequestNotification.AcquireRequestState); } 
        }
 

        /// [To be supplied.]
        public event EventHandler PostAcquireRequestState {
            add { AddSyncEventHookup(EventPostAcquireRequestState, value, RequestNotification.AcquireRequestState, true); } 
            remove { RemoveSyncEventHookup(EventPostAcquireRequestState, value, RequestNotification.AcquireRequestState, true); }
        } 
 

        /// [To be supplied.] 
        public event EventHandler PreRequestHandlerExecute {
            add { AddSyncEventHookup(EventPreRequestHandlerExecute, value, RequestNotification.PreExecuteRequestHandler); }
            remove { RemoveSyncEventHookup(EventPreRequestHandlerExecute, value, RequestNotification.PreExecuteRequestHandler); }
        } 

        /// [To be supplied.] 
        public event EventHandler PostRequestHandlerExecute { 
            add { AddSyncEventHookup(EventPostRequestHandlerExecute, value, RequestNotification.ExecuteRequestHandler, true); }
            remove { RemoveSyncEventHookup(EventPostRequestHandlerExecute, value, RequestNotification.ExecuteRequestHandler, true); } 
        }


        /// [To be supplied.] 
        public event EventHandler ReleaseRequestState {
            add { AddSyncEventHookup(EventReleaseRequestState, value, RequestNotification.ReleaseRequestState ); } 
            remove { RemoveSyncEventHookup(EventReleaseRequestState, value, RequestNotification.ReleaseRequestState); } 
        }
 

        /// [To be supplied.]
        public event EventHandler PostReleaseRequestState {
            add { AddSyncEventHookup(EventPostReleaseRequestState, value, RequestNotification.ReleaseRequestState, true); } 
            remove { RemoveSyncEventHookup(EventPostReleaseRequestState, value, RequestNotification.ReleaseRequestState, true); }
        } 
 

        /// [To be supplied.] 
        public event EventHandler UpdateRequestCache {
            add { AddSyncEventHookup(EventUpdateRequestCache, value, RequestNotification.UpdateRequestCache); }
            remove { RemoveSyncEventHookup(EventUpdateRequestCache, value, RequestNotification.UpdateRequestCache); }
        } 

 
        /// [To be supplied.] 
        public event EventHandler PostUpdateRequestCache {
            add { AddSyncEventHookup(EventPostUpdateRequestCache, value, RequestNotification.UpdateRequestCache, true); } 
            remove { RemoveSyncEventHookup(EventPostUpdateRequestCache, value, RequestNotification.UpdateRequestCache, true); }
        }

        public event EventHandler LogRequest { 
            add {
                if (!HttpRuntime.UseIntegratedPipeline) { 
                    throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
                }
                AddSyncEventHookup(EventLogRequest, value, RequestNotification.LogRequest); 
            }
            remove {
                if (!HttpRuntime.UseIntegratedPipeline) {
                    throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
                }
                RemoveSyncEventHookup(EventLogRequest, value, RequestNotification.LogRequest); 
            } 
        }
 
        public event EventHandler PostLogRequest {
            add {
                if (!HttpRuntime.UseIntegratedPipeline) {
                    throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
                }
                AddSyncEventHookup(EventPostLogRequest, value, RequestNotification.LogRequest, true); 
            } 
            remove {
                if (!HttpRuntime.UseIntegratedPipeline) { 
                    throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode));
                }
                RemoveSyncEventHookup(EventPostLogRequest, value, RequestNotification.LogRequest, true);
            } 
        }
 
        /// [To be supplied.] 
        public event EventHandler EndRequest {
            add { AddSyncEventHookup(EventEndRequest, value, RequestNotification.EndRequest); } 
            remove { RemoveSyncEventHookup(EventEndRequest, value, RequestNotification.EndRequest); }
        }

 
        /// [To be supplied.]
        public event EventHandler Error { 
            add { Events.AddHandler(EventErrorRecorded, value); } 
            remove { Events.RemoveHandler(EventErrorRecorded, value); }
        } 


        /// [To be supplied.]
        public event EventHandler PreSendRequestHeaders { 
            add { AddSendResponseEventHookup(EventPreSendRequestHeaders, value); }
            remove { RemoveSendResponseEventHookup(EventPreSendRequestHeaders, value); } 
        } 

 
        /// [To be supplied.]
        public event EventHandler PreSendRequestContent {
            add { AddSendResponseEventHookup(EventPreSendRequestContent, value); }
            remove { RemoveSendResponseEventHookup(EventPreSendRequestContent, value); } 
        }
 
        // 
        // Async event hookup
        // 

        public void AddOnBeginRequestAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnBeginRequestAsync(bh, eh, null);
        } 

        public void AddOnBeginRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) { 
            AsyncEvents.AddHandler(EventBeginRequest, beginHandler, endHandler, state, RequestNotification.BeginRequest, false, this); 
        }
 
        public void AddOnAuthenticateRequestAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnAuthenticateRequestAsync(bh, eh, null);
        }
 
        public void AddOnAuthenticateRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventAuthenticateRequest, beginHandler, endHandler, state, 
                                   RequestNotification.AuthenticateRequest, false, this); 
        }
 
        public void AddOnPostAuthenticateRequestAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnPostAuthenticateRequestAsync(bh, eh, null);
        }
 
        public void AddOnPostAuthenticateRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostAuthenticateRequest, beginHandler, endHandler, state, 
                                   RequestNotification.AuthenticateRequest, true, this); 
        }
 
        public void AddOnAuthorizeRequestAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnAuthorizeRequestAsync(bh, eh, null);
        }
 
        public void AddOnAuthorizeRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventAuthorizeRequest, beginHandler, endHandler, state, 
                                   RequestNotification.AuthorizeRequest, false, this); 
        }
 
        public void AddOnPostAuthorizeRequestAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnPostAuthorizeRequestAsync(bh, eh, null);
        }
 
        public void AddOnPostAuthorizeRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostAuthorizeRequest, beginHandler, endHandler, state, 
                                   RequestNotification.AuthorizeRequest, true, this); 
        }
 
        public void AddOnResolveRequestCacheAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnResolveRequestCacheAsync(bh, eh, null);
        }
 
        public void AddOnResolveRequestCacheAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventResolveRequestCache, beginHandler, endHandler, state, 
                                   RequestNotification.ResolveRequestCache, false, this); 
        }
 
        public void AddOnPostResolveRequestCacheAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnPostResolveRequestCacheAsync(bh, eh, null);
        }
 
        public void AddOnPostResolveRequestCacheAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostResolveRequestCache, beginHandler, endHandler, state, 
                                   RequestNotification.ResolveRequestCache, true, this); 
        }
 
        public void AddOnMapRequestHandlerAsync(BeginEventHandler bh, EndEventHandler eh) {
            if (!HttpRuntime.UseIntegratedPipeline) {
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode));
            } 
            AddOnMapRequestHandlerAsync(bh, eh, null);
        } 
 
        public void AddOnMapRequestHandlerAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            if (!HttpRuntime.UseIntegratedPipeline) { 
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode));
            }
            AsyncEvents.AddHandler(EventMapRequestHandler, beginHandler, endHandler, state,
                                   RequestNotification.MapRequestHandler, false, this); 
        }
 
        public void AddOnPostMapRequestHandlerAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnPostMapRequestHandlerAsync(bh, eh, null);
        } 

        public void AddOnPostMapRequestHandlerAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostMapRequestHandler, beginHandler, endHandler, state,
                                   RequestNotification.MapRequestHandler, true, this); 
        }
 
        public void AddOnAcquireRequestStateAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnAcquireRequestStateAsync(bh, eh, null);
        } 

        public void AddOnAcquireRequestStateAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventAcquireRequestState, beginHandler, endHandler, state,
                                   RequestNotification.AcquireRequestState, false, this); 
        }
 
        public void AddOnPostAcquireRequestStateAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnPostAcquireRequestStateAsync(bh, eh, null);
        } 

        public void AddOnPostAcquireRequestStateAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostAcquireRequestState, beginHandler, endHandler, state,
                                   RequestNotification.AcquireRequestState, true, this); 
        }
 
        public void AddOnPreRequestHandlerExecuteAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnPreRequestHandlerExecuteAsync(bh, eh, null);
        } 

        public void AddOnPreRequestHandlerExecuteAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPreRequestHandlerExecute, beginHandler, endHandler, state,
                                   RequestNotification.PreExecuteRequestHandler, false, this); 
        }
 
        public void AddOnPostRequestHandlerExecuteAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnPostRequestHandlerExecuteAsync(bh, eh, null);
        } 

        public void AddOnPostRequestHandlerExecuteAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostRequestHandlerExecute, beginHandler, endHandler, state,
                                   RequestNotification.ExecuteRequestHandler, true, this); 
        }
 
        public void AddOnReleaseRequestStateAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnReleaseRequestStateAsync(bh, eh, null);
        } 

        public void AddOnReleaseRequestStateAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventReleaseRequestState, beginHandler, endHandler, state,
                                   RequestNotification.ReleaseRequestState, false, this); 
        }
 
        public void AddOnPostReleaseRequestStateAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnPostReleaseRequestStateAsync(bh, eh, null);
        } 

        public void AddOnPostReleaseRequestStateAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostReleaseRequestState, beginHandler, endHandler, state,
                                   RequestNotification.ReleaseRequestState, true, this); 
        }
 
        public void AddOnUpdateRequestCacheAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnUpdateRequestCacheAsync(bh, eh, null);
        } 

        public void AddOnUpdateRequestCacheAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventUpdateRequestCache, beginHandler, endHandler, state,
                                   RequestNotification.UpdateRequestCache , false, this); 
        }
 
        public void AddOnPostUpdateRequestCacheAsync(BeginEventHandler bh, EndEventHandler eh) { 
            AddOnPostUpdateRequestCacheAsync(bh, eh, null);
        } 

        public void AddOnPostUpdateRequestCacheAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventPostUpdateRequestCache, beginHandler, endHandler, state,
                                   RequestNotification.UpdateRequestCache , true, this); 
        }
 
        public void AddOnLogRequestAsync(BeginEventHandler bh, EndEventHandler eh) { 
            if (!HttpRuntime.UseIntegratedPipeline) {
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
            }
            AddOnLogRequestAsync(bh, eh, null);
        }
 
        public void AddOnLogRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            if (!HttpRuntime.UseIntegratedPipeline) { 
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
            }
            AsyncEvents.AddHandler(EventLogRequest, beginHandler, endHandler, state, 
                                   RequestNotification.LogRequest, false, this);
        }

        public void AddOnPostLogRequestAsync(BeginEventHandler bh, EndEventHandler eh) { 
            if (!HttpRuntime.UseIntegratedPipeline) {
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
            } 
            AddOnPostLogRequestAsync(bh, eh, null);
        } 

        public void AddOnPostLogRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            if (!HttpRuntime.UseIntegratedPipeline) {
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode)); 
            }
            AsyncEvents.AddHandler(EventPostLogRequest, beginHandler, endHandler, state, 
                                   RequestNotification.LogRequest, true, this); 
        }
 
        public void AddOnEndRequestAsync(BeginEventHandler bh, EndEventHandler eh) {
            AddOnEndRequestAsync(bh, eh, null);
        }
 
        public void AddOnEndRequestAsync(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
            AsyncEvents.AddHandler(EventEndRequest, beginHandler, endHandler, state, 
                                   RequestNotification.EndRequest, false, this); 
        }
 
        //
        // Public Application virtual methods
        //
 

        ///  
        ///     
        ///       Used
        ///          to initialize a HttpModule?s instance variables, and to wireup event handlers to 
        ///          the hosting HttpApplication.
        ///       
        ///    
        public virtual void Init() { 
            // derived class implements this
        } 
 

        ///  
        ///    
        ///       Used
        ///          to clean up an HttpModule?s instance variables
        ///        
        ///    
        public virtual void Dispose() { 
            // also part of IComponent 
            // derived class implements this
            _site = null; 
            if (_events != null) {
                try {
                    EventHandler handler = (EventHandler)_events[EventDisposed];
                    if (handler != null) 
                        handler(this, EventArgs.Empty);
                } 
                finally { 
                    _events.Dispose();
                } 
            }
        }

        [SecurityPermission(SecurityAction.Assert, ControlPrincipal = true)] 
        internal static void SetCurrentPrincipalWithAssert(IPrincipal user) {
            Thread.CurrentPrincipal = user; 
        } 

        [SecurityPermission(SecurityAction.Assert, ControlPrincipal = true)] 
        internal static WindowsIdentity GetCurrentWindowsIdentityWithAssert() {
            return WindowsIdentity.GetCurrent();
        }
 
        private HttpHandlerAction GetHandlerMapping(HttpContext context, String requestType, VirtualPath path, bool useAppConfig) {
            CachedPathData pathData = null; 
            HandlerMappingMemo memo = null; 
            HttpHandlerAction mapping = null;
 
            // Check if cached handler could be used
            if (!useAppConfig) {
                // Grab mapping from cache - verify that the verb matches exactly
                pathData = context.GetPathData(path); 
                memo = pathData.CachedHandler;
 
                // Invalidate cache on missmatch 
                if (memo != null && !memo.IsMatch(requestType, path)) {
                    memo = null; 
                }
            }

            // Get new mapping 
            if (memo == null) {
                // Load from config 
                HttpHandlersSection map = useAppConfig ? RuntimeConfig.GetAppConfig().HttpHandlers 
                                                       : RuntimeConfig.GetConfig(context).HttpHandlers;
                mapping = map.FindMapping(requestType, path); 

                // Add cache entry
                if (!useAppConfig) {
                    memo = new HandlerMappingMemo(mapping, requestType, path); 
                    pathData.CachedHandler = memo;
                } 
            } 
            else {
                // Get mapping from the cache 
                mapping = memo.Mapping;
            }

            return mapping; 
        }
 
        internal IHttpHandler MapIntegratedHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, bool useAppConfig, bool convertNativeStaticFileModule) { 
            IHttpHandler handler = null;
 
            using (new ApplicationImpersonationContext()) {
                string type;

                // vpath is a non-relative virtual path 
                string vpath = path.VirtualPathString;
 
                // If we're using app config, modify vpath by appending the path after the last slash 
                // to the app's virtual path.  This will force IIS IHttpContext::MapHandler to use app configuration.
                if (useAppConfig) { 
                    int index = vpath.LastIndexOf('/');
                    index++;
                    if (index != 0 && index < vpath.Length) {
                        vpath = UrlPath.SimpleCombine(HttpRuntime.AppDomainAppVirtualPathString, vpath.Substring(index)); 
                    }
                    else { 
                        vpath = HttpRuntime.AppDomainAppVirtualPathString; 
                    }
                } 


                IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest;
                type = wr.MapHandlerAndGetHandlerTypeString(requestType /*method*/, vpath, convertNativeStaticFileModule); 

                // If a page developer has removed the default mappings with  
                // without replacing them then we need to give a more descriptive error than 
                // a null parameter exception.
                if (type == null) { 
                    PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_FOUND);
                    PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_FAILED);
                    throw new HttpException(SR.GetString(SR.Http_handler_not_found_for_request_type, requestType));
                } 

                // if it's a native type, don't go any further 
                if(String.IsNullOrEmpty(type)) { 
                    return handler;
                } 

                // Get factory from the mapping
                IHttpHandlerFactory factory = GetFactory(type);
 
                try {
                    handler = factory.GetHandler(context, requestType, path.VirtualPathString, pathTranslated); 
                } 
                catch (FileNotFoundException e) {
                    if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) 
                        throw new HttpException(404, null, e);
                    else
                        throw new HttpException(404, null);
                } 
                catch (DirectoryNotFoundException e) {
                    if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) 
                        throw new HttpException(404, null, e); 
                    else
                        throw new HttpException(404, null); 
                }
                catch (PathTooLongException e) {
                    if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                        throw new HttpException(414, null, e); 
                    else
                        throw new HttpException(414, null); 
                } 

                // Remember for recycling 
                if (_handlerRecycleList == null)
                    _handlerRecycleList = new ArrayList();
                _handlerRecycleList.Add(new HandlerWithFactory(handler, factory));
            } 

            return handler; 
        } 

        internal IHttpHandler MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, bool useAppConfig) { 
            // Don't use remap handler when HttpServerUtility.Execute called
            IHttpHandler handler = (context.ServerExecuteDepth == 0) ? context.RemapHandlerInstance : null;

            using (new ApplicationImpersonationContext()) { 
                // Use remap handler if possible
                if (handler != null){ 
                    return handler; 
                }
 
                // Map new handler
                HttpHandlerAction mapping = GetHandlerMapping(context, requestType, path, useAppConfig);

                // If a page developer has removed the default mappings with  
                // without replacing them then we need to give a more descriptive error than
                // a null parameter exception. 
                if (mapping == null) { 
                    PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_FOUND);
                    PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_FAILED); 
                    throw new HttpException(SR.GetString(SR.Http_handler_not_found_for_request_type, requestType));
                }

                // Get factory from the mapping 
                IHttpHandlerFactory factory = GetFactory(mapping);
 
 
                // Get factory from the mapping
                try { 
                    // Check if it supports the more efficient GetHandler call that can avoid
                    // a VirtualPath object creation.
                    IHttpHandlerFactory2 factory2 = factory as IHttpHandlerFactory2;
 
                    if (factory2 != null) {
                        handler = factory2.GetHandler(context, requestType, path, pathTranslated); 
                    } 
                    else {
                        handler = factory.GetHandler(context, requestType, path.VirtualPathString, pathTranslated); 
                    }
                }
                catch (FileNotFoundException e) {
                    if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) 
                        throw new HttpException(404, null, e);
                    else 
                        throw new HttpException(404, null); 
                }
                catch (DirectoryNotFoundException e) { 
                    if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                        throw new HttpException(404, null, e);
                    else
                        throw new HttpException(404, null); 
                }
                catch (PathTooLongException e) { 
                    if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) 
                        throw new HttpException(414, null, e);
                    else 
                        throw new HttpException(414, null);
                }

                // Remember for recycling 
                if (_handlerRecycleList == null)
                    _handlerRecycleList = new ArrayList(); 
                _handlerRecycleList.Add(new HandlerWithFactory(handler, factory)); 
            }
 
            return handler;
        }

 
        /// 
        ///    [To be supplied.] 
        ///  
        public virtual string GetVaryByCustomString(HttpContext context, string custom) {
 
            if (StringUtil.EqualsIgnoreCase(custom, "browser")) {
                return context.Request.Browser.Type;
            }
 
            return null;
        } 
 
        public virtual string GetOutputCacheProviderName(HttpContext context) {
            // default implementation 
            return System.Web.Caching.OutputCache.DefaultProviderName;
        }

        // 
        // IComponent implementation
        // 
 

        ///  
        ///    [To be supplied.]
        /// 
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public ISite Site { 
            get { return _site;}
            set { _site = value;} 
        }

        //
        // IHttpAsyncHandler implementation 
        //
 
 
        /// 
        IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) { 
            HttpAsyncResult result;

            // Setup the asynchronous stuff and application variables
            _context = context; 
            _context.ApplicationInstance = this;
 
            _stepManager.InitRequest(); 

            // Make sure the context stays rooted (including all async operations) 
            _context.Root();

            // Create the async result
            result = new HttpAsyncResult(cb, extraData); 

            // Remember the async result for use in async completions 
            AsyncResult = result; 

            if (_context.TraceIsEnabled) 
                HttpRuntime.Profile.StartRequest(_context);

            // Start the application
            ResumeSteps(null); 

            // Return the async result 
            return result; 
        }
 

        /// 
        void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) {
            // throw error caught during execution 
            HttpAsyncResult ar = (HttpAsyncResult)result;
            if (ar.Error != null) 
                throw ar.Error; 
        }
 
        //
        // IHttpHandler implementation
        //
 

        ///  
        void IHttpHandler.ProcessRequest(HttpContext context) { 
            throw new HttpException(SR.GetString(SR.[....]_not_supported));
        } 


        /// 
        bool IHttpHandler.IsReusable { 
            get { return true; }
        } 
 
        //
        // Support for external calls into the application like app_onStart 
        //

        [ReflectionPermission(SecurityAction.Assert, Flags=ReflectionPermissionFlag.RestrictedMemberAccess)]
        private void InvokeMethodWithAssert(MethodInfo method, int paramCount, object eventSource, EventArgs eventArgs) { 
            if (paramCount == 0) {
                method.Invoke(this, new Object[0]); 
            } 
            else {
                Debug.Assert(paramCount == 2); 

                method.Invoke(this, new Object[2] { eventSource, eventArgs });
            }
        } 

        internal void ProcessSpecialRequest(HttpContext context, 
                                            MethodInfo method, 
                                            int paramCount,
                                            Object eventSource, 
                                            EventArgs eventArgs,
                                            HttpSessionState session) {
            _context = context;
            if (HttpRuntime.UseIntegratedPipeline && _context != null) { 
                _context.HideRequestResponse = true;
            } 
            _hideRequestResponse = true; 
            _session = session;
            _lastError = null; 

            using (new DisposableHttpContextWrapper(context)) {
                using (new ApplicationImpersonationContext()) {
                    try { 
                        // set culture on the current thread
                        SetAppLevelCulture(); 
                        InvokeMethodWithAssert(method, paramCount, eventSource, eventArgs); 
                    }
                    catch (Exception e) { 
                        // dereference reflection invocation exceptions
                        Exception eActual;
                        if (e is TargetInvocationException)
                            eActual = e.InnerException; 
                        else
                            eActual = e; 
 
                        RecordError(eActual);
 
                        if (context == null) {
                            try {
                                WebBaseEvent.RaiseRuntimeError(eActual, this);
                            } 
                            catch {
                            } 
                        } 

                    } 
                    finally {

                        // this thread should not be locking app state
                        if (_state != null) 
                            _state.EnsureUnLock();
 
                        // restore culture 
                        RestoreAppLevelCulture();
 
                        if (HttpRuntime.UseIntegratedPipeline && _context != null) {
                            _context.HideRequestResponse = false;
                        }
                        _hideRequestResponse = false; 
                        _context = null;
                        _session = null; 
                        _lastError = null; 
                        _appEvent = null;
                    } 
                }
            }
        }
 
        //
        // Report context-less error 
        // 

        internal void RaiseErrorWithoutContext(Exception error) { 
            try {
                try {
                    SetAppLevelCulture();
                    _lastError = error; 

                    RaiseOnError(); 
                } 
                finally {
                    // this thread should not be locking app state 
                    if (_state != null)
                        _state.EnsureUnLock();

                    RestoreAppLevelCulture(); 
                    _lastError = null;
                    _appEvent = null; 
                } 
            }
            catch { // Protect against exception filters 
                throw;
            }
        }
 
        //
        // 
        // 

        internal void InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers) { 
            Debug.Assert(context != null, "context != null");

            // Remember state
            _state = state; 

            PerfCounters.IncrementCounter(AppPerfCounter.PIPELINES); 
 
            try {
                try { 
                    // Remember context for config lookups
                    _initContext = context;
                    _initContext.ApplicationInstance = this;
 
                    // Set config path to be application path for the application initialization
                    context.ConfigurationPath = context.Request.ApplicationPathObject; 
 
                    // keep HttpContext.Current working while running user code
                    using (new DisposableHttpContextWrapper(context)) { 

                        // Build module list from config
                        if (HttpRuntime.UseIntegratedPipeline) {
 
                            Debug.Assert(_moduleConfigInfo != null, "_moduleConfigInfo != null");
                            Debug.Assert(_moduleConfigInfo.Count >= 0, "_moduleConfigInfo.Count >= 0"); 
 
                            try {
                                context.HideRequestResponse = true; 
                                _hideRequestResponse = true;
                                InitIntegratedModules();
                            }
                            finally { 
                                context.HideRequestResponse = false;
                                _hideRequestResponse = false; 
                            } 
                        }
                        else { 
                            InitModules();

                            // this is used exclusively for integrated mode
                            Debug.Assert(null == _moduleContainers, "null == _moduleContainers"); 
                        }
 
                        // Hookup event handlers via reflection 
                        if (handlers != null)
                            HookupEventHandlersForApplicationAndModules(handlers); 

                        // Initialization of the derived class
                        _context = context;
                        if (HttpRuntime.UseIntegratedPipeline && _context != null) { 
                            _context.HideRequestResponse = true;
                        } 
                        _hideRequestResponse = true; 

                        try { 
                            Init();
                        }
                        catch (Exception e) {
                            RecordError(e); 
                        }
                    } 
 
                    if (HttpRuntime.UseIntegratedPipeline && _context != null) {
                        _context.HideRequestResponse = false; 
                    }
                    _hideRequestResponse = false;
                    _context = null;
                    _resumeStepsWaitCallback= new WaitCallback(this.ResumeStepsWaitCallback); 

                    // Construct the execution steps array 
                    if (HttpRuntime.UseIntegratedPipeline) { 
                        _stepManager = new PipelineStepManager(this);
                    } 
                    else {
                        _stepManager = new ApplicationStepManager(this);
                    }
 
                    _stepManager.BuildSteps(_resumeStepsWaitCallback);
                } 
                finally { 
                    _initInternalCompleted = true;
 
                    // Reset config path
                    context.ConfigurationPath = null;

                    // don't hold on to the context 
                    _initContext.ApplicationInstance = null;
                    _initContext = null; 
                } 
            }
            catch { // Protect against exception filters 
                throw;
            }
        }
 
        // helper to expand an event handler into application steps
        private void CreateEventExecutionSteps(Object eventIndex, ArrayList steps) { 
            // async 
            AsyncAppEventHandler asyncHandler = AsyncEvents[eventIndex];
 
            if (asyncHandler != null) {
                asyncHandler.CreateExecutionSteps(this, steps);
            }
 
            // [....]
            EventHandler handler = (EventHandler)Events[eventIndex]; 
 
            if (handler != null) {
                Delegate[] handlers = handler.GetInvocationList(); 

                for (int i = 0; i < handlers.Length; i++)  {
                    steps.Add(new SyncEventExecutionStep(this, (EventHandler)handlers[i]));
                } 
            }
        } 
 
        internal void InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) {
            // Remember state 
            _state = state;

            try {
                //  Remember the context for the initialization 
                if (context != null) {
                    _initContext = context; 
                    _initContext.ApplicationInstance = this; 
                }
 
                // if we're doing integrated pipeline wireup, then appContext is non-null and we need to init modules and register event subscriptions with IIS
                if (appContext != IntPtr.Zero) {
                    // 1694356: app_offline.htm and  require that we make this check here for integrated mode
                    using (new ApplicationImpersonationContext()) { 
                        HttpRuntime.CheckApplicationEnabled();
                    } 
 
                    // retrieve app level culture
                    InitAppLevelCulture(); 

                    Debug.Trace("PipelineRuntime", "InitSpecial for " + appContext.ToString() + "\n");
                    RegisterEventSubscriptionsWithIIS(appContext, context, handlers);
                } 
                else {
                    // retrieve app level culture 
                    InitAppLevelCulture(); 

                    // Hookup event handlers via reflection 
                    if (handlers != null) {
                        HookupEventHandlersForApplicationAndModules(handlers);
                    }
                } 

                // if we're doing integrated pipeline wireup, then appContext is non-null and we need to register the application (global.asax) event handlers 
                if (appContext != IntPtr.Zero) { 
                    if (_appPostNotifications != 0 || _appRequestNotifications != 0) {
                        RegisterIntegratedEvent(appContext, 
                                                HttpApplicationFactory.applicationFileName,
                                                _appRequestNotifications,
                                                _appPostNotifications,
                                                this.GetType().FullName, 
                                                MANAGED_PRECONDITION,
                                                false); 
                    } 
                }
            } 
            finally  {
                _initSpecialCompleted = true;

                //  Do not hold on to the context 
                if (_initContext != null) {
                    _initContext.ApplicationInstance = null; 
                    _initContext = null; 
                }
            } 
        }

        internal void DisposeInternal() {
            PerfCounters.DecrementCounter(AppPerfCounter.PIPELINES); 

            // call derived class 
 
            try {
                Dispose(); 
            }
            catch (Exception e) {
                RecordError(e);
            } 

            // dispose modules 
 
            if (_moduleCollection != null) {
                int numModules = _moduleCollection.Count; 

                for (int i = 0; i < numModules; i++) {
                    try {
                        // set the init key during Dispose for modules 
                        // that try to unregister events
                        if (HttpRuntime.UseIntegratedPipeline) { 
                            _currentModuleCollectionKey = _moduleCollection.GetKey(i); 
                        }
                        _moduleCollection[i].Dispose(); 
                    }
                    catch {
                    }
                } 

                _moduleCollection = null; 
            } 
        }
 
        private void BuildEventMaskDictionary(Dictionary eventMask) {
            eventMask["BeginRequest"]              = RequestNotification.BeginRequest;
            eventMask["AuthenticateRequest"]       = RequestNotification.AuthenticateRequest;
            eventMask["PostAuthenticateRequest"]   = RequestNotification.AuthenticateRequest; 
            eventMask["AuthorizeRequest"]          = RequestNotification.AuthorizeRequest;
            eventMask["PostAuthorizeRequest"]      = RequestNotification.AuthorizeRequest; 
            eventMask["ResolveRequestCache"]       = RequestNotification.ResolveRequestCache; 
            eventMask["PostResolveRequestCache"]   = RequestNotification.ResolveRequestCache;
            eventMask["MapRequestHandler"]         = RequestNotification.MapRequestHandler; 
            eventMask["PostMapRequestHandler"]     = RequestNotification.MapRequestHandler;
            eventMask["AcquireRequestState"]       = RequestNotification.AcquireRequestState;
            eventMask["PostAcquireRequestState"]   = RequestNotification.AcquireRequestState;
            eventMask["PreRequestHandlerExecute"]  = RequestNotification.PreExecuteRequestHandler; 
            eventMask["PostRequestHandlerExecute"] = RequestNotification.ExecuteRequestHandler;
            eventMask["ReleaseRequestState"]       = RequestNotification.ReleaseRequestState; 
            eventMask["PostReleaseRequestState"]   = RequestNotification.ReleaseRequestState; 
            eventMask["UpdateRequestCache"]        = RequestNotification.UpdateRequestCache;
            eventMask["PostUpdateRequestCache"]    = RequestNotification.UpdateRequestCache; 
            eventMask["LogRequest"]                = RequestNotification.LogRequest;
            eventMask["PostLogRequest"]            = RequestNotification.LogRequest;
            eventMask["EndRequest"]                = RequestNotification.EndRequest;
            eventMask["PreSendRequestHeaders"]     = RequestNotification.SendResponse; 
            eventMask["PreSendRequestContent"]     = RequestNotification.SendResponse;
        } 
 
        private void HookupEventHandlersForApplicationAndModules(MethodInfo[] handlers) {
            _currentModuleCollectionKey = HttpApplicationFactory.applicationFileName; 

            if(null == _pipelineEventMasks) {
                Dictionary dict = new Dictionary();
                BuildEventMaskDictionary(dict); 
                if(null == _pipelineEventMasks) {
                    _pipelineEventMasks = dict; 
                } 
            }
 

            for (int i = 0; i < handlers.Length; i++) {
                MethodInfo appMethod = handlers[i];
                String appMethodName = appMethod.Name; 
                int namePosIndex = appMethodName.IndexOf('_');
                String targetName = appMethodName.Substring(0, namePosIndex); 
 
                // Find target for method
                Object target = null; 

                if (StringUtil.EqualsIgnoreCase(targetName, "Application"))
                    target = this;
                else if (_moduleCollection != null) 
                    target = _moduleCollection[targetName];
 
                if (target == null) 
                    continue;
 
                // Find event on the module type
                Type targetType = target.GetType();
                EventDescriptorCollection events = TypeDescriptor.GetEvents(targetType);
                string eventName = appMethodName.Substring(namePosIndex+1); 

                EventDescriptor foundEvent = events.Find(eventName, true); 
                if (foundEvent == null 
                    && StringUtil.EqualsIgnoreCase(eventName.Substring(0, 2), "on")) {
 
                    eventName = eventName.Substring(2);
                    foundEvent = events.Find(eventName, true);
                }
 
                MethodInfo addMethod = null;
                if (foundEvent != null) { 
                    EventInfo reflectionEvent = targetType.GetEvent(foundEvent.Name); 
                    Debug.Assert(reflectionEvent != null);
                    if (reflectionEvent != null) { 
                        addMethod = reflectionEvent.GetAddMethod();
                    }
                }
 
                if (addMethod == null)
                    continue; 
 
                ParameterInfo[] addMethodParams = addMethod.GetParameters();
 
                if (addMethodParams.Length != 1)
                    continue;

                // Create the delegate from app method to pass to AddXXX(handler) method 

                Delegate handlerDelegate = null; 
 
                ParameterInfo[] appMethodParams = appMethod.GetParameters();
 
                if (appMethodParams.Length == 0) {
                    // If the app method doesn't have arguments --
                    // -- hookup via intermidiate handler
 
                    // only can do it for EventHandler, not strongly typed
                    if (addMethodParams[0].ParameterType != typeof(System.EventHandler)) 
                        continue; 

                    ArglessEventHandlerProxy proxy = new ArglessEventHandlerProxy(this, appMethod); 
                    handlerDelegate = proxy.Handler;
                }
                else {
                    // Hookup directly to the app methods hoping all types match 

                    try { 
                        handlerDelegate = Delegate.CreateDelegate(addMethodParams[0].ParameterType, this, appMethodName); 
                    }
                    catch { 
                        // some type mismatch
                        continue;
                    }
                } 

                // Call the AddXXX() to hook up the delegate 
 
                try {
                    addMethod.Invoke(target, new Object[1]{handlerDelegate}); 
                }
                catch {
                    if (HttpRuntime.UseIntegratedPipeline) {
                        throw; 
                    }
                } 
 
                if (eventName != null) {
                    if (_pipelineEventMasks.ContainsKey(eventName)) { 
                        if (!StringUtil.StringStartsWith(eventName, "Post")) {
                            _appRequestNotifications |= _pipelineEventMasks[eventName];
                        }
                        else { 
                            _appPostNotifications |= _pipelineEventMasks[eventName];
                        } 
                    } 
                }
            } 
        }

        private void RegisterIntegratedEvent(IntPtr appContext,
                                             string moduleName, 
                                             RequestNotification requestNotifications,
                                             RequestNotification postRequestNotifications, 
                                             string moduleType, 
                                             string modulePrecondition,
                                             bool useHighPriority) { 

            // lookup the modules event index, if it already exists
            // use it, otherwise, bump the global count
            // the module is used for event dispatch 

            int moduleIndex; 
            if (_moduleIndexMap.ContainsKey(moduleName)) { 
                moduleIndex = (int) _moduleIndexMap[moduleName];
            } 
            else {
                moduleIndex = _moduleIndexMap.Count;
                _moduleIndexMap[moduleName] = moduleIndex;
            } 

#if DBG 
            Debug.Assert(moduleIndex >= 0, "moduleIndex >= 0"); 
            Debug.Trace("PipelineRuntime", "RegisterIntegratedEvent:"
                        + " module=" + moduleName 
                        + ", index=" + moduleIndex.ToString(CultureInfo.InvariantCulture)
                        + ", rq_notify=" + requestNotifications
                        + ", post_rq_notify=" + postRequestNotifications
                        + ", preconditon=" + modulePrecondition + "\r\n"); 
#endif
 
            int result = UnsafeIISMethods.MgdRegisterEventSubscription(appContext, 
                                                                       moduleName,
                                                                       requestNotifications, 
                                                                       postRequestNotifications,
                                                                       moduleType,
                                                                       modulePrecondition,
                                                                       new IntPtr(moduleIndex), 
                                                                       useHighPriority);
 
            if(result < 0) { 
                throw new HttpException(SR.GetString(
                    SR.Failed_Pipeline_Subscription, moduleName)); 
            }
        }

 
        private void SetAppLevelCulture() {
            CultureInfo culture = null; 
            CultureInfo uiculture = null; 
            CultureInfo browserCulture = null;
            string userLanguage = null; 
            //get the language from the browser
            //DevDivBugs 2001091: Request object is not available in integrated mode during Application_Start,
            //so don't try to access it if it is hidden
            if((_appLevelAutoCulture || _appLevelAutoUICulture) && _context != null && _context.HideRequestResponse == false) { 
                userLanguage = _context.UserLanguageFromContext();
                if(userLanguage != null) { 
                    try { browserCulture = HttpServerUtility.CreateReadOnlySpecificCultureInfo(userLanguage); } 
                    catch { }
                } 
            }

            culture = _appLevelCulture;
            uiculture = _appLevelUICulture; 
            if(browserCulture != null) {
                if(_appLevelAutoCulture) { 
                    culture = browserCulture; 
                }
                if(_appLevelAutoUICulture) { 
                    uiculture = browserCulture;
                }
            }
 
            _savedAppLevelCulture = Thread.CurrentThread.CurrentCulture;
            _savedAppLevelUICulture = Thread.CurrentThread.CurrentUICulture; 
 
            if (culture != null && culture != Thread.CurrentThread.CurrentCulture) {
                HttpRuntime.SetCurrentThreadCultureWithAssert(culture); 
            }

            if (uiculture != null && uiculture != Thread.CurrentThread.CurrentUICulture) {
                Thread.CurrentThread.CurrentUICulture = uiculture; 
            }
        } 
 
        private void RestoreAppLevelCulture() {
            CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; 
            CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;

            if (_savedAppLevelCulture != null) {
                // Avoid the cost of the Demand when setting the culture by comparing the cultures first 
                if (currentCulture != _savedAppLevelCulture) {
                    HttpRuntime.SetCurrentThreadCultureWithAssert(_savedAppLevelCulture); 
                } 

                _savedAppLevelCulture = null; 
            }

            if (_savedAppLevelUICulture != null) {
                // Avoid the cost of the Demand when setting the culture by comparing the cultures first 
                if (currentUICulture  != _savedAppLevelUICulture) {
                    Thread.CurrentThread.CurrentUICulture = _savedAppLevelUICulture; 
                } 

                _savedAppLevelUICulture = null; 
            }
        }

        // OnThreadEnterPrivate returns ThreadContext. 
        // ThreadContext.Enter sets variables that are stored on the thread,
        // and saves anything currently on the thread so it can be restored 
        // during the call to ThreadContext.Leave.  All variables that are 
        // modified on the thread should be stored in ThreadContext so they
        // can be restored later.  ThreadContext.Enter should only be called 
        // when holding a lock on the HttpApplication instance.
        // ThreadContext.Leave is also normally called under the lock, but
        // the Integrated Pipeline may delay this call until after the call to
        // IndicateCompletion returns.  When IndicateCompletion is called, 
        // IIS7 will execute the remaining notifications for the request on
        // the current thread.  As a performance improvement, we do not call 
        // Leave before calling IndicateCompletion, and we do not call Enter/Leave 
        // for the notifications executed while we are in the call to
        // IndicateCompletion.  But when IndicateCompletion returns, we do not 
        // have a lock on the HttpApplication instance and therefore cannot
        // modify request state, such as the HttpContext or HttpApplication.
        // The only thing we can do is restore the state of the thread.
        // There's one problem, the Culture/UICulture may be changed by 
        // user code that directly updates the values on the current thread, so
        // before leaving the pipeline we call ThreadContext.Synchronize to 
        // synchronize the values that are stored on the HttpContext with what 
        // is on the thread.  Because of this, the next notification will end up using
        // the Culture/UICulture set by user-code, just as it did on IIS6. 
        internal class ThreadContext {
            private HttpContext _context;
            private IPrincipal _savedPrincipal;
            private HttpContext _savedContext; 
            private ImpersonationContext _impersonationContext;
            private SynchronizationContext _savedSynchronizationContext; 
            private CultureInfo _savedCulture, _setThreadCulture; 
            private CultureInfo _savedUICulture, _setThreadUICulture;
            private bool _hasLeaveBeenCalled; 
            private bool _setThread;

            internal ThreadContext(HttpContext context) {
                _context = context; 
            }
 
            internal void Enter(bool setImpersonationContext) { 
                Debug.Assert(_context != null); // only to be used when context is available
#if DBG 
                Debug.Trace("OnThread", GetTraceMessage("Enter1"));
#endif
                // attach http context to the call context
                _savedContext = DisposableHttpContextWrapper.SwitchContext(_context); 

                // set impersonation on the current thread 
                if (setImpersonationContext) { 
                    SetImpersonationContext();
                } 

                // set synchronization context for the current thread to support the async pattern
                _savedSynchronizationContext = AsyncOperationManager.SynchronizationContext;
                AsyncOperationManager.SynchronizationContext = _context.SyncContext; 

                // set ETW trace ID 
                Guid g = _context.WorkerRequest.RequestTraceIdentifier; 
                if (!(g == Guid.Empty)) {
                    CallContext.LogicalSetData("E2ETrace.ActivityID", g); 
                }

                // set SqlDependecyCookie
                _context.ResetSqlDependencyCookie(); 

                // set principal on the current thread 
                _savedPrincipal = Thread.CurrentPrincipal; 
                SetCurrentPrincipalWithAssert(_context.User);
 
                // only set culture on the current thread if it is not initialized
                SetRequestLevelCulture(_context);

                // DevDivBugs 75042 
                // set current thread in context if there is not there
                // the timeout manager  uses this to abort the correct thread 
                if (_context.CurrentThread == null) { 
                    _setThread = true;
                    _context.CurrentThread = Thread.CurrentThread; 
                }
#if DBG
                Debug.Trace("OnThread", GetTraceMessage("Enter2"));
#endif 
            }
 
            internal bool HasLeaveBeenCalled { get { return _hasLeaveBeenCalled; } } 

            internal void Leave() { 
#if DBG
                Debug.Trace("OnThread", GetTraceMessage("Leave1"));
#endif
                _hasLeaveBeenCalled = true; 

                // remove thread if set 
                if (_setThread) { 
                    _context.CurrentThread = null;
                } 

                // this thread should not be locking app state
                HttpApplicationFactory.ApplicationState.EnsureUnLock();
 
                // stop impersonation
                UndoImpersonationContext(); 
 
                // restore culture
                RestoreRequestLevelCulture(); 

                // restrore synchronization context
                AsyncOperationManager.SynchronizationContext = _savedSynchronizationContext;
 
                // restore thread principal
                SetCurrentPrincipalWithAssert(_savedPrincipal); 
 
                // Remove SqlCacheDependency cookie from call context if necessary
                _context.RemoveSqlDependencyCookie(); 

                // remove http context from the call context
                DisposableHttpContextWrapper.SwitchContext(_savedContext);
                _savedContext = null; 
#if DBG
                Debug.Trace("OnThread", GetTraceMessage("Leave2")); 
#endif 
            }
 
            // Use of IndicateCompletion requires that we synchronize the cultures
            // with what may have been set by user code during execution of the
            // notification.
            internal void Synchronize(HttpContext context) { 
                context.DynamicCulture = Thread.CurrentThread.CurrentCulture;
                context.DynamicUICulture = Thread.CurrentThread.CurrentUICulture; 
            } 

            internal void SetImpersonationContext() { 
                // set impersonation on the current thread
                if (_impersonationContext == null) {
                    _impersonationContext = new ClientImpersonationContext(_context);
                } 
            }
 
            internal void UndoImpersonationContext() { 
                // remove impersonation on the current thread
                if (_impersonationContext != null) { 
                    _impersonationContext.Undo();
                    _impersonationContext = null;
                }
            } 

            // 
            // Application execution logic 
            //
            private void SetRequestLevelCulture(HttpContext context) { 
                CultureInfo culture = null;
                CultureInfo uiculture = null;

                GlobalizationSection globConfig = RuntimeConfig.GetConfig(context).Globalization; 
                if (!String.IsNullOrEmpty(globConfig.Culture))
                    culture = context.CultureFromConfig(globConfig.Culture, true); 
 
                if (!String.IsNullOrEmpty(globConfig.UICulture))
                    uiculture = context.CultureFromConfig(globConfig.UICulture, false); 

                if (context.DynamicCulture != null)
                    culture = context.DynamicCulture;
 
                if (context.DynamicUICulture != null)
                    uiculture = context.DynamicUICulture; 
 
                // Page also could have its own culture settings
                Page page = context.CurrentHandler as Page; 

                if (page != null) {
                    if (page.DynamicCulture != null)
                        culture = page.DynamicCulture; 

                    if (page.DynamicUICulture != null) 
                        uiculture = page.DynamicUICulture; 
                }
 
                _savedCulture = Thread.CurrentThread.CurrentCulture;
                _savedUICulture = Thread.CurrentThread.CurrentUICulture;

                if (culture != null && culture != Thread.CurrentThread.CurrentCulture) { 
                    HttpRuntime.SetCurrentThreadCultureWithAssert(culture);
                    _setThreadCulture = culture; 
                } 

                if (uiculture != null && uiculture != Thread.CurrentThread.CurrentUICulture) { 
                    Thread.CurrentThread.CurrentUICulture = uiculture;
                    _setThreadUICulture = uiculture;
                }
            } 

            private void RestoreRequestLevelCulture() { 
                CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; 
                CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;
 
                if (_savedCulture != null) {
                    // Avoid the cost of the Demand when setting the culture by comparing the cultures first
                    if (currentCulture != _savedCulture) {
                        HttpRuntime.SetCurrentThreadCultureWithAssert(_savedCulture); 
                        if (_context != null) {
                            // remember changed culture for the rest of the request 
                            _context.DynamicCulture = currentCulture; 
                        }
                    } 

                    _savedCulture = null;
                }
 
                if (_savedUICulture != null) {
                    // Avoid the cost of the Demand when setting the culture by comparing the cultures first 
                    if (currentUICulture  != _savedUICulture) { 
                        Thread.CurrentThread.CurrentUICulture = _savedUICulture;
                        if (_context != null) { 
                            // remember changed culture for the rest of the request
                            _context.DynamicUICulture = currentUICulture;
                        }
                    } 

                    _savedUICulture = null; 
                } 
            }
 
#if DBG
            static string GetTraceMessage(string tag) {
                System.Text.StringBuilder sb = new System.Text.StringBuilder(256);
                sb.Append(tag); 
                sb.AppendFormat(" Thread={0}", SafeNativeMethods.GetCurrentThreadId().ToString(CultureInfo.InvariantCulture));
                sb.AppendFormat(" Context={0}", (HttpContext.Current != null) ? HttpContext.Current.GetHashCode().ToString(CultureInfo.InvariantCulture) : "NULL_CTX"); 
                sb.AppendFormat(" Principal={0}", (Thread.CurrentPrincipal != null) ? Thread.CurrentPrincipal.GetHashCode().ToString(CultureInfo.InvariantCulture) : "NULL_PRIN"); 
                sb.AppendFormat(" Culture={0}", Thread.CurrentThread.CurrentCulture.LCID.ToString(CultureInfo.InvariantCulture));
                sb.AppendFormat(" UICulture={0}", Thread.CurrentThread.CurrentUICulture.LCID.ToString(CultureInfo.InvariantCulture)); 
                sb.AppendFormat(" ActivityID={0}", CallContext.LogicalGetData("E2ETrace.ActivityID"));
                return sb.ToString();
            }
#endif 
        }
 
        // Initializes the thread on entry to the managed pipeline. A ThreadContext is returned, on 
        // which the caller must call Leave.  The IIS7 integrated pipeline uses setImpersonationContext
        // to prevent it from being set until after the authentication notification. 
        private ThreadContext OnThreadEnterPrivate(bool setImpersonationContext) {
            ThreadContext threadContext = new ThreadContext(_context);
            threadContext.Enter(setImpersonationContext);
 
            // An entry is added to the request timeout manager once per request
            // and removed in ReleaseAppInstance. 
            if (!_timeoutManagerInitialized) { 
                // ensure Timeout is set (see ASURT 148698)
                // to avoid ---- getting config later (ASURT 127388) 
                _context.EnsureTimeout();

                HttpRuntime.RequestTimeoutManager.Add(_context);
                _timeoutManagerInitialized = true; 
            }
 
            return threadContext; 
        }
 
        internal ThreadContext OnThreadEnter() {
            return OnThreadEnterPrivate(true /* setImpersonationContext */);
        }
 
        internal ThreadContext OnThreadEnter(bool setImpersonationContext) {
            return OnThreadEnterPrivate(setImpersonationContext); 
        } 

        /* 
         * Execute single step catching exceptions in a fancy way (see below)
         */
        internal Exception ExecuteStep(IExecutionStep step, ref bool completedSynchronously) {
            Exception error = null; 

            try { 
                try { 
                    if (step.IsCancellable) {
                        _context.BeginCancellablePeriod();  // request can be cancelled from this point 

                        try {
                            step.Execute();
                        } 
                        finally {
                            _context.EndCancellablePeriod();  // request can be cancelled until this point 
                        } 

                        _context.WaitForExceptionIfCancelled();  // wait outside of finally 
                    }
                    else {
                        step.Execute();
                    } 

                    if (!step.CompletedSynchronously) { 
                        completedSynchronously = false; 
                        return null;
                    } 
                }
                catch (Exception e) {
                    error = e;
 
                    // Since we will leave the context later, we need to remember if we are impersonating
                    // before we lose that info - VSWhidbey 494476 
                    if (ImpersonationContext.CurrentThreadTokenExists) { 
                        e.Data[System.Web.Management.WebThreadInformation.IsImpersonatingKey] = String.Empty;
                    } 
                    // This might force ThreadAbortException to be thrown
                    // automatically, because we consumed an exception that was
                    // hiding ThreadAbortException behind it
 
                    if (e is ThreadAbortException &&
                        ((Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) == 0))  { 
                        // Response.End from a COM+ component that re-throws ThreadAbortException 
                        // It is not a real ThreadAbort
                        // VSWhidbey 178556 
                        error = null;
                        _stepManager.CompleteRequest();
                    }
                } 
#pragma warning disable 1058
                catch { 
                    // ignore non-Exception objects that could be thrown 
                }
#pragma warning restore 1058 
            }
            catch (ThreadAbortException e) {
                // ThreadAbortException could be masked as another one
                // the try-catch above consumes all exceptions, only 
                // ThreadAbortException can filter up here because it gets
                // auto rethrown if no other exception is thrown on catch 
 
                if (e.ExceptionState != null && e.ExceptionState is CancelModuleException) {
                    // one of ours (Response.End or timeout) -- cancel abort 

                    CancelModuleException cancelException = (CancelModuleException)e.ExceptionState;

                    if (cancelException.Timeout) { 
                        // Timed out
                        error = new HttpException(SR.GetString(SR.Request_timed_out), 
                                            null, WebEventCodes.RuntimeErrorRequestAbort); 
                        PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_TIMED_OUT);
                    } 
                    else {
                        // Response.End
                        error = null;
                        _stepManager.CompleteRequest(); 
                    }
 
                    Thread.ResetAbort(); 
                }
            } 

            completedSynchronously = true;
            return error;
        } 

        /* 
         * Resume execution of the app steps 
         */
 
        private void ResumeStepsFromThreadPoolThread(Exception error) {
            if (Thread.CurrentThread.IsThreadPoolThread) {
                // if on thread pool thread, use the current thread
                ResumeSteps(error); 
            }
            else { 
                // if on a non-threadpool thread, requeue 
                ThreadPool.QueueUserWorkItem(_resumeStepsWaitCallback, error);
            } 
        }

        private void ResumeStepsWaitCallback(Object error) {
            ResumeSteps(error as Exception); 
        }
 
        private void ResumeSteps(Exception error) { 
            _stepManager.ResumeSteps(error);
        } 


        /*
         * Add error to the context fire OnError on first error 
         */
        private void RecordError(Exception error) { 
            bool firstError = true; 

            if (_context != null) { 
                if (_context.Error != null)
                    firstError = false;

                _context.AddError(error); 
            }
            else { 
                if (_lastError != null) 
                    firstError = false;
 
                _lastError = error;
            }

            if (firstError) 
                RaiseOnError();
        } 
 

        // 
        // Init module list
        //

        private void InitModulesCommon() { 
            int n = _moduleCollection.Count;
 
            for (int i = 0; i < n; i++) { 
                // remember the module being inited for event subscriptions
                // we'll later use this for routing 
                _currentModuleCollectionKey = _moduleCollection.GetKey(i);
                _moduleCollection[i].Init(this);
            }
 
            _currentModuleCollectionKey = null;
            InitAppLevelCulture(); 
        } 

        private void InitIntegratedModules() { 
            Debug.Assert(null != _moduleConfigInfo, "null != _moduleConfigInfo");
            _moduleCollection = BuildIntegratedModuleCollection(_moduleConfigInfo);
            InitModulesCommon();
        } 

        private void InitModules() { 
            HttpModulesSection pconfig = RuntimeConfig.GetAppConfig().HttpModules; 
            _moduleCollection = pconfig.CreateModules();
 
            InitModulesCommon();
        }

        internal string CurrentModuleCollectionKey { 
            get {
                return (null == _currentModuleCollectionKey) ? "UnknownModule" : _currentModuleCollectionKey; 
            } 
        }
 
        private void RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) {
            RequestNotification requestNotifications;
            RequestNotification postRequestNotifications;
 
            // register an implicit filter module
            RegisterIntegratedEvent(appContext, 
                                    IMPLICIT_FILTER_MODULE, 
                                    RequestNotification.UpdateRequestCache| RequestNotification.LogRequest  /*requestNotifications*/,
                                    0 /*postRequestNotifications*/, 
                                    String.Empty /*type*/,
                                    String.Empty /*precondition*/,
                                    true /*useHighPriority*/);
 
            // integrated pipeline will always use serverModules instead of 
            _moduleCollection = GetModuleCollection(appContext); 
 
            if (handlers != null) {
                HookupEventHandlersForApplicationAndModules(handlers); 
            }

            // 1643363: Breaking Change: ASP.Net v2.0: Application_OnStart is called after Module.Init (Integarted mode)
            HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(context, this); 

            // Call Init on HttpApplication derived class ("global.asax") 
            // and process event subscriptions before processing other modules. 
            // Doing this now prevents clearing any events that may
            // have been added to event handlers during instantiation of this instance. 
            // NOTE:  If "global.asax" has a constructor which hooks up event handlers,
            // then they were added to the event handler lists but have not been registered with IIS yet,
            // so we MUST call ProcessEventSubscriptions on it first, before the other modules.
            _currentModuleCollectionKey = HttpApplicationFactory.applicationFileName; 

            try { 
                _hideRequestResponse = true; 
                context.HideRequestResponse = true;
                _context = context; 
                Init();
            }
            catch (Exception e) {
                RecordError(e); 
                Exception error = context.Error;
                if (error != null) { 
                    throw error; 
                }
            } 
            finally {
                _context = null;
                context.HideRequestResponse = false;
                _hideRequestResponse = false; 
            }
 
            ProcessEventSubscriptions(out requestNotifications, out postRequestNotifications); 

            // Save the notification subscriptions so we can register them with IIS later, after 
            // we call HookupEventHandlersForApplicationAndModules and process global.asax event handlers.
            _appRequestNotifications |= requestNotifications;
            _appPostNotifications    |= postRequestNotifications;
 
            for (int i = 0; i < _moduleCollection.Count; i++) {
                _currentModuleCollectionKey = _moduleCollection.GetKey(i); 
                IHttpModule httpModule = _moduleCollection.Get(i); 
                ModuleConfigurationInfo moduleInfo = _moduleConfigInfo[i];
 
#if DBG
                Debug.Trace("PipelineRuntime", "RegisterEventSubscriptionsWithIIS: name=" + CurrentModuleCollectionKey
                            + ", type=" + httpModule.GetType().FullName + "\n");
 
                // make sure collections are in [....]
                Debug.Assert(moduleInfo.Name == _currentModuleCollectionKey, "moduleInfo.Name == _currentModuleCollectionKey"); 
#endif 

                httpModule.Init(this); 

                ProcessEventSubscriptions(out requestNotifications, out postRequestNotifications);

                // are any events wired up? 
                if (requestNotifications != 0 || postRequestNotifications != 0) {
 
                    RegisterIntegratedEvent(appContext, 
                                            moduleInfo.Name,
                                            requestNotifications, 
                                            postRequestNotifications,
                                            moduleInfo.Type,
                                            moduleInfo.Precondition,
                                            false /*useHighPriority*/); 
                }
            } 
 
            // WOS 1728067: RewritePath does not remap the handler when rewriting from a non-ASP.NET request
            // register a default implicit handler 
            RegisterIntegratedEvent(appContext,
                                    IMPLICIT_HANDLER,
                                    RequestNotification.ExecuteRequestHandler | RequestNotification.MapRequestHandler /*requestNotifications*/,
                                    0 /*postRequestNotifications*/, 
                                    String.Empty /*type*/,
                                    String.Empty /*precondition*/, 
                                    false /*useHighPriority*/); 
        }
 
        private void ProcessEventSubscriptions(out RequestNotification requestNotifications,
                                               out RequestNotification postRequestNotifications) {
            requestNotifications = 0;
            postRequestNotifications = 0; 

            // Begin 
            if(HasEventSubscription(EventBeginRequest)) { 
                requestNotifications |= RequestNotification.BeginRequest;
            } 

            // Authenticate
            if(HasEventSubscription(EventAuthenticateRequest)) {
                requestNotifications |= RequestNotification.AuthenticateRequest; 
            }
 
            if(HasEventSubscription(EventPostAuthenticateRequest)) { 
                postRequestNotifications |= RequestNotification.AuthenticateRequest;
            } 

            // Authorize
            if(HasEventSubscription(EventAuthorizeRequest)) {
                requestNotifications |= RequestNotification.AuthorizeRequest; 
            }
            if(HasEventSubscription(EventPostAuthorizeRequest)) { 
                postRequestNotifications |= RequestNotification.AuthorizeRequest; 
            }
 
            // ResolveRequestCache
            if(HasEventSubscription(EventResolveRequestCache)) {
                requestNotifications |= RequestNotification.ResolveRequestCache;
            } 
            if(HasEventSubscription(EventPostResolveRequestCache)) {
                postRequestNotifications |= RequestNotification.ResolveRequestCache; 
            } 

            // MapRequestHandler 
            if(HasEventSubscription(EventMapRequestHandler)) {
                requestNotifications |= RequestNotification.MapRequestHandler;
            }
            if(HasEventSubscription(EventPostMapRequestHandler)) { 
                postRequestNotifications |= RequestNotification.MapRequestHandler;
            } 
 
            // AcquireRequestState
            if(HasEventSubscription(EventAcquireRequestState)) { 
                requestNotifications |= RequestNotification.AcquireRequestState;
            }
            if(HasEventSubscription(EventPostAcquireRequestState)) {
                postRequestNotifications |= RequestNotification.AcquireRequestState; 
            }
 
            // PreExecuteRequestHandler 
            if(HasEventSubscription(EventPreRequestHandlerExecute)) {
                requestNotifications |= RequestNotification.PreExecuteRequestHandler; 
            }

            // PostRequestHandlerExecute
            if (HasEventSubscription(EventPostRequestHandlerExecute)) { 
                postRequestNotifications |= RequestNotification.ExecuteRequestHandler;
            } 
 
            // ReleaseRequestState
            if(HasEventSubscription(EventReleaseRequestState)) { 
                requestNotifications |= RequestNotification.ReleaseRequestState;
            }
            if(HasEventSubscription(EventPostReleaseRequestState)) {
                postRequestNotifications |= RequestNotification.ReleaseRequestState; 
            }
 
            // UpdateRequestCache 
            if(HasEventSubscription(EventUpdateRequestCache)) {
                requestNotifications |= RequestNotification.UpdateRequestCache; 
            }
            if(HasEventSubscription(EventPostUpdateRequestCache)) {
                postRequestNotifications |= RequestNotification.UpdateRequestCache;
            } 

            // LogRequest 
            if(HasEventSubscription(EventLogRequest)) { 
                requestNotifications |= RequestNotification.LogRequest;
            } 
            if(HasEventSubscription(EventPostLogRequest)) {
                postRequestNotifications |= RequestNotification.LogRequest;
            }
 
            // EndRequest
            if(HasEventSubscription(EventEndRequest)) { 
                requestNotifications |= RequestNotification.EndRequest; 
            }
 
            // PreSendRequestHeaders
            if(HasEventSubscription(EventPreSendRequestHeaders)) {
                requestNotifications |= RequestNotification.SendResponse;
            } 

            // PreSendRequestContent 
            if(HasEventSubscription(EventPreSendRequestContent)) { 
                requestNotifications |= RequestNotification.SendResponse;
            } 
        }

        // check if an event has subscribers
        // and *reset* them if so 
        // this is used only for special app instances
        // and not for processing requests 
        private bool HasEventSubscription(Object eventIndex) { 
            bool hasEvents = false;
 
            // async
            AsyncAppEventHandler asyncHandler = AsyncEvents[eventIndex];

            if (asyncHandler != null && asyncHandler.Count > 0) { 
                asyncHandler.Reset();
                hasEvents = true; 
            } 

            // [....] 
            EventHandler handler = (EventHandler)Events[eventIndex];

            if (handler != null) {
                Delegate[] handlers = handler.GetInvocationList(); 
                if( handlers.Length > 0 ) {
                    hasEvents = true; 
                } 

                foreach(Delegate d in handlers) { 
                    Events.RemoveHandler(eventIndex, d);
                }
            }
 
            return hasEvents;
        } 
 

        // 
        // Get app-level culture info (needed to context-less 'global' methods)
        //

        private void InitAppLevelCulture() { 
            GlobalizationSection globConfig = RuntimeConfig.GetAppConfig().Globalization;
            string culture = globConfig.Culture; 
            string uiCulture = globConfig.UICulture; 
            if (!String.IsNullOrEmpty(culture)) {
                if (StringUtil.StringStartsWithIgnoreCase(culture, AutoCulture)) { 
                    _appLevelAutoCulture = true;
                    string appLevelCulture = GetFallbackCulture(culture);
                    if(appLevelCulture != null) {
                        _appLevelCulture = HttpServerUtility.CreateReadOnlyCultureInfo(culture.Substring(5)); 
                    }
                } 
                else { 
                    _appLevelAutoCulture = false;
                    _appLevelCulture = HttpServerUtility.CreateReadOnlyCultureInfo(globConfig.Culture); 
                }
            }
            if (!String.IsNullOrEmpty(uiCulture)) {
                if (StringUtil.StringStartsWithIgnoreCase(uiCulture, AutoCulture)) 
                {
                    _appLevelAutoUICulture = true; 
                    string appLevelUICulture = GetFallbackCulture(uiCulture); 
                    if(appLevelUICulture != null) {
                        _appLevelUICulture = HttpServerUtility.CreateReadOnlyCultureInfo(uiCulture.Substring(5)); 
                    }
                }
                else {
                    _appLevelAutoUICulture = false; 
                    _appLevelUICulture = HttpServerUtility.CreateReadOnlyCultureInfo(globConfig.UICulture);
                } 
            } 
        }
 
        internal static string GetFallbackCulture(string culture) {
            if((culture.Length > 5) && (culture.IndexOf(':') == 4)) {
                return culture.Substring(5);
            } 
            return null;
        } 
 
        //
        // Request mappings management functions 
        //

        private IHttpHandlerFactory GetFactory(HttpHandlerAction mapping) {
            HandlerFactoryCache entry = (HandlerFactoryCache)_handlerFactories[mapping.Type]; 
            if (entry == null) {
                entry = new HandlerFactoryCache(mapping); 
                _handlerFactories[mapping.Type] = entry; 
            }
 
            return entry.Factory;
        }

        private IHttpHandlerFactory GetFactory(string type) { 
            HandlerFactoryCache entry = (HandlerFactoryCache)_handlerFactories[type];
            if (entry == null) { 
                entry = new HandlerFactoryCache(type); 
                _handlerFactories[type] = entry;
            } 

            return entry.Factory;
        }
 

        /* 
         * Recycle all handlers mapped during the request processing 
         */
        private void RecycleHandlers() { 
            if (_handlerRecycleList != null) {
                int numHandlers = _handlerRecycleList.Count;

                for (int i = 0; i < numHandlers; i++) 
                    ((HandlerWithFactory)_handlerRecycleList[i]).Recycle();
 
                _handlerRecycleList = null; 
            }
        } 

        /*
         * Special exception to cancel module execution (not really an exception)
         * used in Response.End and when cancelling requests 
         */
        internal class CancelModuleException { 
            private bool _timeout; 

            internal CancelModuleException(bool timeout) { 
                _timeout = timeout;
            }

            internal bool Timeout { get { return _timeout;}} 
        }
 
        // Setup the asynchronous stuff and application variables 
        // context for the entire deal is already rooted for native handler
        internal void AssignContext(HttpContext context) { 
            Debug.Assert(HttpRuntime.UseIntegratedPipeline, "HttpRuntime.UseIntegratedPipeline");

            if (null == _context) {
                _stepManager.InitRequest(); 

                _context = context; 
                _context.ApplicationInstance = this; 

                if (_context.TraceIsEnabled) 
                    HttpRuntime.Profile.StartRequest(_context);

                // this will throw if config is invalid, so we do it after HttpContext.ApplicationInstance is set
                _context.SetImpersonationEnabled(); 
            }
        } 
 
        internal IAsyncResult BeginProcessRequestNotification(HttpContext context, AsyncCallback cb) {
            Debug.Trace("PipelineRuntime", "BeginProcessRequestNotification"); 

            HttpAsyncResult result;

            if (_context == null) { 
                //
                AssignContext(context); 
            } 

            // 
            // everytime initialization
            //

            context.CurrentModuleEventIndex = -1; 

            // Create the async result 
            result = new HttpAsyncResult(cb, context); 
            context.NotificationContext.AsyncResult = result;
 
            // enter notification execution loop

            ResumeSteps(null);
 
            return result;
        } 
 
        internal RequestNotificationStatus EndProcessRequestNotification(IAsyncResult result) {
            HttpAsyncResult ar = (HttpAsyncResult)result; 
            if (ar.Error != null)
                throw ar.Error;

            return ar.Status; 
        }
 
        internal void ReleaseAppInstance() { 
            if (_context != null)
            { 
                if (_context.TraceIsEnabled) {
                    HttpRuntime.Profile.EndRequest(_context);
                }
                _context.ClearReferences(); 
                if (_timeoutManagerInitialized) {
                    HttpRuntime.RequestTimeoutManager.Remove(_context); 
                    _timeoutManagerInitialized = false; 
                }
            } 
            RecycleHandlers();
            if (AsyncResult != null) {
                AsyncResult = null;
            } 
            _context = null;
            AppEvent = null; 
            HttpApplicationFactory.RecycleApplicationInstance(this); 
        }
 
        private void AddEventMapping(string moduleName,
                                      RequestNotification requestNotification,
                                      bool isPostNotification,
                                      IExecutionStep step) { 

            ThrowIfEventBindingDisallowed(); 
 
            // Add events to the IExecutionStep containers only if
            // InitSpecial has completed and InitInternal has not completed. 
            if (!IsContainerInitalizationAllowed) {
                return;
            }
 
            Debug.Assert(!String.IsNullOrEmpty(moduleName), "!String.IsNullOrEmpty(moduleName)");
            Debug.Trace("PipelineRuntime", "AddEventMapping: for " + moduleName + 
                        " for " + requestNotification + "\r\n" ); 

 
            PipelineModuleStepContainer container = GetModuleContainer(moduleName);
            //WOS 1985878: HttpModule unsubscribing an event handler causes AV in Integrated Mode
            if (container != null) {
#if DBG 
                container.DebugModuleName = moduleName;
#endif 
                container.AddEvent(requestNotification, isPostNotification, step); 
            }
        } 

        static internal List IntegratedModuleList {
            get {
                return _moduleConfigInfo; 
            }
        } 
 
        private HttpModuleCollection GetModuleCollection(IntPtr appContext) {
            if (_moduleConfigInfo != null) { 
                return BuildIntegratedModuleCollection(_moduleConfigInfo);
            }

            List moduleList = null; 

            IntPtr pModuleCollection = IntPtr.Zero; 
            IntPtr pBstrModuleName = IntPtr.Zero; 
            int cBstrModuleName = 0;
            IntPtr pBstrModuleType = IntPtr.Zero; 
            int cBstrModuleType = 0;
            IntPtr pBstrModulePrecondition = IntPtr.Zero;
            int cBstrModulePrecondition = 0;
            try { 
                int count = 0;
                int result = UnsafeIISMethods.MgdGetModuleCollection(appContext, out pModuleCollection, out count); 
                if (result < 0) { 
                    throw new HttpException(SR.GetString(SR.Cant_Read_Native_Modules, result.ToString("X8", CultureInfo.InvariantCulture)));
                } 
                moduleList = new List(count);

                for (uint index = 0; index < count; index++) {
                    result = UnsafeIISMethods.MgdGetNextModule(pModuleCollection, ref index, 
                                                               out pBstrModuleName, out cBstrModuleName,
                                                               out pBstrModuleType, out cBstrModuleType, 
                                                               out pBstrModulePrecondition, out cBstrModulePrecondition); 
                    if (result < 0) {
                        throw new HttpException(SR.GetString(SR.Cant_Read_Native_Modules, result.ToString("X8", CultureInfo.InvariantCulture))); 
                    }
                    string moduleName = (cBstrModuleName > 0) ? StringUtil.StringFromWCharPtr(pBstrModuleName, cBstrModuleName) : null;
                    string moduleType = (cBstrModuleType > 0) ? StringUtil.StringFromWCharPtr(pBstrModuleType, cBstrModuleType) : null;
                    string modulePrecondition = (cBstrModulePrecondition > 0) ? StringUtil.StringFromWCharPtr(pBstrModulePrecondition, cBstrModulePrecondition) : String.Empty; 
                    Marshal.FreeBSTR(pBstrModuleName);
                    pBstrModuleName = IntPtr.Zero; 
                    cBstrModuleName = 0; 
                    Marshal.FreeBSTR(pBstrModuleType);
                    pBstrModuleType = IntPtr.Zero; 
                    cBstrModuleType = 0;
                    Marshal.FreeBSTR(pBstrModulePrecondition);
                    pBstrModulePrecondition = IntPtr.Zero;
                    cBstrModulePrecondition = 0; 

                    if (!String.IsNullOrEmpty(moduleName) && !String.IsNullOrEmpty(moduleType)) { 
                        moduleList.Add(new ModuleConfigurationInfo(moduleName, moduleType, modulePrecondition)); 
                    }
                } 
            }
            finally {
                if (pModuleCollection != IntPtr.Zero) {
                    Marshal.Release(pModuleCollection); 
                    pModuleCollection = IntPtr.Zero;
                } 
                if (pBstrModuleName != IntPtr.Zero) { 
                    Marshal.FreeBSTR(pBstrModuleName);
                    pBstrModuleName = IntPtr.Zero; 
                }
                if (pBstrModuleType != IntPtr.Zero) {
                    Marshal.FreeBSTR(pBstrModuleType);
                    pBstrModuleType = IntPtr.Zero; 
                }
                if (pBstrModulePrecondition != IntPtr.Zero) { 
                    Marshal.FreeBSTR(pBstrModulePrecondition); 
                    pBstrModulePrecondition = IntPtr.Zero;
                } 
            }

            _moduleConfigInfo = moduleList;
 
            return BuildIntegratedModuleCollection(_moduleConfigInfo);
        } 
 
        HttpModuleCollection BuildIntegratedModuleCollection(List moduleList) {
            HttpModuleCollection modules = new HttpModuleCollection(); 

            foreach(ModuleConfigurationInfo mod in moduleList) {
#if DBG
                Debug.Trace("NativeConfig", "Runtime module: " + mod.Name + " of type " + mod.Type + "\n"); 
#endif
                ModulesEntry currentModule = new ModulesEntry(mod.Name, mod.Type, "type", null); 
 
                modules.AddModule(currentModule.ModuleName, currentModule.Create());
            } 

            return modules;
        }
 
        //
        // Internal classes to support [asynchronous] app execution logic 
        // 

        internal class AsyncAppEventHandler { 
            int _count;
            ArrayList _beginHandlers;
            ArrayList _endHandlers;
            ArrayList _stateObjects; 

            internal AsyncAppEventHandler() { 
                _count = 0; 
                _beginHandlers = new ArrayList();
                _endHandlers   = new ArrayList(); 
                _stateObjects  = new ArrayList();
            }

            internal void Reset() { 
                _count = 0;
                _beginHandlers.Clear(); 
                _endHandlers.Clear(); 
                _stateObjects.Clear();
            } 

            internal int Count {
                get {
                    return _count; 
                }
            } 
 
            internal void Add(BeginEventHandler beginHandler, EndEventHandler endHandler, Object state) {
                _beginHandlers.Add(beginHandler); 
                _endHandlers.Add(endHandler);
                _stateObjects.Add(state);
                _count++;
            } 

            internal void CreateExecutionSteps(HttpApplication app, ArrayList steps) { 
                for (int i = 0; i < _count; i++) { 
                    steps.Add(new AsyncEventExecutionStep(
                        app, 
                        (BeginEventHandler)_beginHandlers[i],
                        (EndEventHandler)_endHandlers[i],
                        _stateObjects[i]));
                } 
            }
        } 
 
        internal class AsyncAppEventHandlersTable {
            private Hashtable _table; 

            internal void AddHandler(Object eventId, BeginEventHandler beginHandler,
                                     EndEventHandler endHandler, Object state,
                                     RequestNotification requestNotification, 
                                     bool isPost, HttpApplication app) {
                if (_table == null) 
                    _table = new Hashtable(); 

                AsyncAppEventHandler asyncHandler = (AsyncAppEventHandler)_table[eventId]; 

                if (asyncHandler == null) {
                    asyncHandler = new AsyncAppEventHandler();
                    _table[eventId] = asyncHandler; 
                }
 
                asyncHandler.Add(beginHandler, endHandler, state); 

                if (HttpRuntime.UseIntegratedPipeline) { 
                    AsyncEventExecutionStep step =
                        new AsyncEventExecutionStep(app,
                                                    beginHandler,
                                                    endHandler, 
                                                    state);
 
                    app.AddEventMapping(app.CurrentModuleCollectionKey, requestNotification, isPost, step); 
                }
            } 

            internal AsyncAppEventHandler this[Object eventId] {
                get {
                    if (_table == null) 
                        return null;
                    return (AsyncAppEventHandler)_table[eventId]; 
                } 
            }
        } 

        // interface to represent one execution step
        internal interface IExecutionStep {
            void Execute(); 
            bool CompletedSynchronously { get;}
            bool IsCancellable { get; } 
        } 

        // execution step -- stub 
        internal class NoopExecutionStep : IExecutionStep {
            internal NoopExecutionStep() {
            }
 
            void IExecutionStep.Execute() {
            } 
 
            bool IExecutionStep.CompletedSynchronously {
                get { return true;} 
            }

            bool IExecutionStep.IsCancellable {
                get { return false; } 
            }
        } 
 
        // execution step -- call synchronous event
        internal class SyncEventExecutionStep : IExecutionStep { 
            private HttpApplication _application;
            private EventHandler    _handler;

            internal SyncEventExecutionStep(HttpApplication app, EventHandler handler) { 
                _application = app;
                _handler = handler; 
            } 

            internal EventHandler Handler { 
                get {
                    return _handler;
                }
            } 

            void IExecutionStep.Execute() { 
                string targetTypeStr = null; 

                if (_handler != null) { 
                    if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) {
                        targetTypeStr = _handler.Method.ReflectedType.ToString();

                        EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_ENTER, _application.Context.WorkerRequest, targetTypeStr); 
                    }
                    _handler(_application, _application.AppEvent); 
                    if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_LEAVE, _application.Context.WorkerRequest, targetTypeStr); 
                }
            } 

            bool IExecutionStep.CompletedSynchronously {
                [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
                get { return true;} 
            }
 
            bool IExecutionStep.IsCancellable { 
                [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
                get { return true; } 
            }
        }

        // execution step -- call asynchronous event 
        internal class AsyncEventExecutionStep : IExecutionStep {
            private HttpApplication     _application; 
            private BeginEventHandler   _beginHandler; 
            private EndEventHandler     _endHandler;
            private Object              _state; 
            private AsyncCallback       _completionCallback;
            private bool                _[....];          // per call
            private string              _targetTypeStr;
 
            internal AsyncEventExecutionStep(HttpApplication app, BeginEventHandler beginHandler, EndEventHandler endHandler, Object state)
                :this(app, beginHandler, endHandler, state, HttpRuntime.UseIntegratedPipeline) 
                { 
                }
 
            internal AsyncEventExecutionStep(HttpApplication app, BeginEventHandler beginHandler, EndEventHandler endHandler, Object state, bool useIntegratedPipeline) {

                _application = app;
                _beginHandler = beginHandler; 
                _endHandler = endHandler;
                _state = state; 
                _completionCallback = new AsyncCallback(this.OnAsyncEventCompletion); 
            }
 
            private void OnAsyncEventCompletion(IAsyncResult ar) {
                if (ar.CompletedSynchronously)  // handled in Execute()
                    return;
 
                Debug.Trace("PipelineRuntime", "AsyncStep.OnAsyncEventCompletion");
                HttpContext context = _application.Context; 
                Exception error = null; 

                try { 
                    _endHandler(ar);
                }
                catch (Exception e) {
                    error = e; 
                }
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_LEAVE, context.WorkerRequest, _targetTypeStr); 

                // re-set start time after an async completion (see VSWhidbey 231010) 
                context.SetStartTime();

                // Assert to disregard the user code up the stack
                ResumeStepsWithAssert(error); 
            }
 
            [PermissionSet(SecurityAction.Assert, Unrestricted=true)] 
            void ResumeStepsWithAssert(Exception error) {
                _application.ResumeStepsFromThreadPoolThread(error); 
            }

            void IExecutionStep.Execute() {
                _[....] = false; 

                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) { 
                    _targetTypeStr = _beginHandler.Method.ReflectedType.ToString(); 
                    EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_ENTER, _application.Context.WorkerRequest, _targetTypeStr);
                } 

                IAsyncResult ar = _beginHandler(_application, _application.AppEvent, _completionCallback, _state);

                if (ar.CompletedSynchronously) { 
                    _[....] = true;
                    _endHandler(ar); 
 
                    if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_LEAVE, _application.Context.WorkerRequest, _targetTypeStr);
                } 
            }

            bool IExecutionStep.CompletedSynchronously {
                get { return _[....];} 
            }
 
            bool IExecutionStep.IsCancellable { 
                get { return false; }
            } 
        }

        // execution step -- validate the path for canonicalization issues
        internal class ValidatePathExecutionStep : IExecutionStep { 
            private HttpApplication _application;
 
            internal ValidatePathExecutionStep(HttpApplication app) { 
                _application = app;
            } 

            void IExecutionStep.Execute() {
                _application.Context.ValidatePath();
            } 

            bool IExecutionStep.CompletedSynchronously { 
                get { return true; } 
            }
 
            bool IExecutionStep.IsCancellable {
                get { return false; }
            }
        } 

        // execution step -- validate request (virtual path, query string, entity body, etc) 
        internal class ValidateRequestExecutionStep : IExecutionStep { 
            private HttpApplication _application;
 
            internal ValidateRequestExecutionStep(HttpApplication app) {
                _application = app;
            }
 
            void IExecutionStep.Execute() {
                _application.Context.Request.ValidateInputIfRequiredByConfig(); 
            } 

            bool IExecutionStep.CompletedSynchronously { 
                get { return true; }
            }

            bool IExecutionStep.IsCancellable { 
                get { return false; }
            } 
        } 

        // materialize handler for integrated pipeline 
        // this does not map handler, rather that's done by the core
        // this does instantiate the managed type so that things that need to
        // look at it can
        internal class MaterializeHandlerExecutionStep : IExecutionStep { 
            private HttpApplication _application;
 
            internal MaterializeHandlerExecutionStep(HttpApplication app) { 
                _application = app;
            } 

            void IExecutionStep.Execute() {
                HttpContext context = _application.Context;
                HttpRequest request = context.Request; 
                IHttpHandler handler = null;
                string configType = null; 
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_ENTER, context.WorkerRequest);
 
                IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest;

                // Get handler
                if (context.RemapHandlerInstance != null){ 
                    //RemapHandler overrides all
                    context.Handler = context.RemapHandlerInstance; 
                } 
                else if (request.RewrittenUrl != null) {
                    // RewritePath, we need to re-map the handler 
                    bool handlerExists;
                    configType = wr.ReMapHandlerAndGetHandlerTypeString(context, request.Path, out handlerExists);
                    if (!handlerExists) {
                        // WOS 1973590: When RewritePath is used with missing handler in Integrated Mode,an empty response 200 is returned instead of 404 
                        throw new HttpException(404, SR.GetString(SR.Http_handler_not_found_for_request_type, request.RequestType));
                    } 
                } 
                else {
                    configType = wr.GetManagedHandlerType(); 
                }

                if (!String.IsNullOrEmpty(configType)) {
                    IHttpHandlerFactory factory = _application.GetFactory(configType); 
                    string pathTranslated = request.PhysicalPathInternal;
 
                    try { 
                        handler = factory.GetHandler(context, request.RequestType, request.FilePath, pathTranslated);
                    } 
                    catch (FileNotFoundException e) {
                        if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                            throw new HttpException(404, null, e);
                        else 
                            throw new HttpException(404, null);
                    } 
                    catch (DirectoryNotFoundException e) { 
                        if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                            throw new HttpException(404, null, e); 
                        else
                            throw new HttpException(404, null);
                    }
                    catch (PathTooLongException e) { 
                        if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated))
                            throw new HttpException(414, null, e); 
                        else 
                            throw new HttpException(414, null);
                    } 

                    context.Handler = handler;

                    // Remember for recycling 
                    if (_application._handlerRecycleList == null)
                        _application._handlerRecycleList = new ArrayList(); 
                    _application._handlerRecycleList.Add(new HandlerWithFactory(handler, factory)); 
                }
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_LEAVE, context.WorkerRequest);
            }

            bool IExecutionStep.CompletedSynchronously { 
                get { return true;}
            } 
 
            bool IExecutionStep.IsCancellable {
                get { return false; } 
            }
        }

 
        // execution step -- map HTTP handler (used to be a separate module)
        internal class MapHandlerExecutionStep : IExecutionStep { 
            private HttpApplication _application; 

            internal MapHandlerExecutionStep(HttpApplication app) { 
                _application = app;
            }

            void IExecutionStep.Execute() { 
                HttpContext context = _application.Context;
                HttpRequest request = context.Request; 
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_ENTER, context.WorkerRequest);
 
                context.Handler = _application.MapHttpHandler(
                    context,
                    request.RequestType,
                    request.FilePathObject, 
                    request.PhysicalPathInternal,
                    false /*useAppConfig*/); 
                Debug.Assert(context.ConfigurationPath == context.Request.FilePathObject, "context.ConfigurationPath (" + 
                             context.ConfigurationPath + ") != context.Request.FilePath (" + context.Request.FilePath + ")");
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_LEAVE, context.WorkerRequest);
            }

            bool IExecutionStep.CompletedSynchronously { 
                get { return true;}
            } 
 
            bool IExecutionStep.IsCancellable {
                get { return false; } 
            }
        }

        // execution step -- call HTTP handler (used to be a separate module) 
        internal class CallHandlerExecutionStep : IExecutionStep {
            private HttpApplication   _application; 
            private AsyncCallback     _completionCallback; 
            private IHttpAsyncHandler _handler;       // per call
            private bool              _[....];          // per call 

            internal CallHandlerExecutionStep(HttpApplication app) {
                _application = app;
                _completionCallback = new AsyncCallback(this.OnAsyncHandlerCompletion); 
            }
 
            private void OnAsyncHandlerCompletion(IAsyncResult ar) { 
                if (ar.CompletedSynchronously)  // handled in Execute()
                    return; 

                HttpContext context = _application.Context;
                Exception error = null;
 
                try {
                    try { 
                        _handler.EndProcessRequest(ar); 
                    }
                    finally { 
                        // In Integrated mode, generate the necessary response headers
                        // after the ASP.NET handler runs.  If EndProcessRequest throws,
                        // the headers will be generated by ReportRuntimeError
                        context.Response.GenerateResponseHeadersForHandler(); 
                    }
                } 
                catch (Exception e) { 
                    if (e is ThreadAbortException || e.InnerException != null && e.InnerException is ThreadAbortException) {
                        // Response.End happened during async operation 
                        _application.CompleteRequest();
                    }
                    else {
                        error = e; 
                    }
                } 
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Information, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest);
 
                _handler = null; // not to remember

                // re-set start time after an async completion (see VSWhidbey 231010)
                context.SetStartTime(); 

                // Assert to disregard the user code up the stack 
                ResumeStepsWithAssert(error); 
            }
 
            [PermissionSet(SecurityAction.Assert, Unrestricted=true)]
            void ResumeStepsWithAssert(Exception error) {
                _application.ResumeStepsFromThreadPoolThread(error);
            } 

            void IExecutionStep.Execute() { 
                HttpContext context = _application.Context; 
                IHttpHandler handler = context.Handler;
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Information, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_ENTER, context.WorkerRequest);

                if (handler != null && HttpRuntime.UseIntegratedPipeline) {
                    IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest; 
                    if (wr != null && wr.IsHandlerExecutionDenied()) {
                        _[....] = true; 
                        HttpException error = new HttpException(403, SR.GetString(SR.Handler_access_denied)); 
                        error.SetFormatter(new PageForbiddenErrorFormatter(context.Request.Path, SR.GetString(SR.Handler_access_denied)));
                        throw error; 
                    }
                }

                if (handler == null) { 
                    _[....] = true;
                } 
                else if (handler is IHttpAsyncHandler) { 
                    // asynchronous handler
                    IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler)handler; 

                    _[....] = false;
                    _handler = asyncHandler;
                    IAsyncResult ar = asyncHandler.BeginProcessRequest(context, _completionCallback, null); 

                    if (ar.CompletedSynchronously) { 
                        _[....] = true; 
                        _handler = null; // not to remember
 
                        try {
                            asyncHandler.EndProcessRequest(ar);
                        }
                        finally { 
                            //  In Integrated mode, generate the necessary response headers
                            //  after the ASP.NET handler runs 
                            context.Response.GenerateResponseHeadersForHandler(); 
                        }
 
                        if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Information, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest);
                    }
                }
                else { 
                    // synchronous handler
                    _[....] = true; 
 
                    // disable async operations
                    //_application.SyncContext.Disable(); 

                    // make sure completions of async operations don't block
                    // to enable [....] handlers that poll for async completions
                    context.SyncContext.SetSyncCaller(); 

                    try { 
                        handler.ProcessRequest(context); 
                    }
                    finally { 
                        context.SyncContext.ResetSyncCaller();
                        if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Information, EtwTraceFlags.Page)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LEAVE, context.WorkerRequest);

                        // In Integrated mode, generate the necessary response headers 
                        // after the ASP.NET handler runs
                        context.Response.GenerateResponseHeadersForHandler(); 
                    } 
                }
            } 

            bool IExecutionStep.CompletedSynchronously {
                get { return _[....];}
            } 

            bool IExecutionStep.IsCancellable { 
                // launching of async handler should not be cancellable 
                get { return (_application.Context.Handler is IHttpAsyncHandler) ? false : true; }
            } 
        }

        // execution step -- call response filter
        internal class CallFilterExecutionStep : IExecutionStep { 
            private HttpApplication _application;
 
            internal CallFilterExecutionStep(HttpApplication app) { 
                _application = app;
            } 

            void IExecutionStep.Execute() {
                try {
                    _application.Context.Response.FilterOutput(); 
                }
                finally { 
                    // if this is the UpdateCache notification, then disable the LogRequest notification (which handles the error case) 
                    if (HttpRuntime.UseIntegratedPipeline && (_application.Context.CurrentNotification == RequestNotification.UpdateRequestCache)) {
                        _application.Context.DisableNotifications(RequestNotification.LogRequest, 0 /*postNotifications*/); 
                    }
                }
            }
 
            bool IExecutionStep.CompletedSynchronously {
                get { return true;} 
            } 

            bool IExecutionStep.IsCancellable { 
                get { return true; }
            }
        }
 
        // integrated pipeline execution step for RaiseOnPreSendRequestHeaders and RaiseOnPreSendRequestContent
        internal class SendResponseExecutionStep : IExecutionStep { 
            private HttpApplication _application; 
            private EventHandler _handler;
            private bool _isHeaders; 

            internal SendResponseExecutionStep(HttpApplication app, EventHandler handler, bool isHeaders) {
                _application = app;
                _handler = handler; 
                _isHeaders = isHeaders;
            } 
 
            void IExecutionStep.Execute() {
 
                // IIS only has a SendResponse notification, so we check the flags
                // to determine whether this notification is for headers or content.
                // The step uses _isHeaders to keep track of whether this is for headers or content.
                if (_application.Context.IsSendResponseHeaders && _isHeaders 
                    || !_isHeaders) {
 
                    string targetTypeStr = null; 

                    if (_handler != null) { 
                        if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) {
                            targetTypeStr = _handler.Method.ReflectedType.ToString();

                            EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_ENTER, _application.Context.WorkerRequest, targetTypeStr); 
                        }
                        _handler(_application, _application.AppEvent); 
                        if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Module)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_PIPELINE_LEAVE, _application.Context.WorkerRequest, targetTypeStr); 
                    }
                } 
            }

            bool IExecutionStep.CompletedSynchronously {
                get { return true;} 
            }
 
            bool IExecutionStep.IsCancellable { 
                get { return true; }
            } 
        }

        internal class UrlMappingsExecutionStep : IExecutionStep {
            private HttpApplication _application; 

 
            internal UrlMappingsExecutionStep(HttpApplication app) { 
                _application = app;
            } 

            void IExecutionStep.Execute() {
                HttpContext context = _application.Context;
                UrlMappingsModule.UrlMappingRewritePath(context); 
            }
 
            bool IExecutionStep.CompletedSynchronously { 
                get { return true;}
            } 

            bool IExecutionStep.IsCancellable {
                get { return false; }
            } 
        }
 
        internal abstract class StepManager { 
            protected HttpApplication _application;
            protected bool _requestCompleted; 

            internal StepManager(HttpApplication application) {
                _application = application;
            } 

            internal bool IsCompleted { get { return _requestCompleted; } } 
 
            internal abstract void BuildSteps(WaitCallback stepCallback);
 
            internal void CompleteRequest() {
                _requestCompleted = true;
                if (HttpRuntime.UseIntegratedPipeline) {
                    HttpContext context = _application.Context; 
                    if (context != null && context.NotificationContext != null) {
                        context.NotificationContext.RequestCompleted = true; 
                    } 
                }
            } 

            internal abstract void InitRequest();

            internal abstract void ResumeSteps(Exception error); 
        }
 
        internal class ApplicationStepManager : StepManager { 
            private IExecutionStep[] _execSteps;
            private WaitCallback _resumeStepsWaitCallback; 
            private int _currentStepIndex;
            private int _numStepCalls;
            private int _numSyncStepCalls;
            private int _endRequestStepIndex; 

            internal ApplicationStepManager(HttpApplication app): base(app) { 
            } 

            internal override void BuildSteps(WaitCallback stepCallback ) { 
                ArrayList steps = new ArrayList();
                HttpApplication app = _application;

                bool urlMappingsEnabled = false; 
                UrlMappingsSection urlMappings = RuntimeConfig.GetConfig().UrlMappings;
                urlMappingsEnabled = urlMappings.IsEnabled && ( urlMappings.UrlMappings.Count > 0 ); 
 
                steps.Add(new ValidateRequestExecutionStep(app));
                steps.Add(new ValidatePathExecutionStep(app)); 

                if (urlMappingsEnabled)
                    steps.Add(new UrlMappingsExecutionStep(app)); // url mappings
 
                app.CreateEventExecutionSteps(HttpApplication.EventBeginRequest, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventAuthenticateRequest, steps); 
                app.CreateEventExecutionSteps(HttpApplication.EventDefaultAuthentication, steps); 
                app.CreateEventExecutionSteps(HttpApplication.EventPostAuthenticateRequest, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventAuthorizeRequest, steps); 
                app.CreateEventExecutionSteps(HttpApplication.EventPostAuthorizeRequest, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventResolveRequestCache, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPostResolveRequestCache, steps);
                steps.Add(new MapHandlerExecutionStep(app));     // map handler 
                app.CreateEventExecutionSteps(HttpApplication.EventPostMapRequestHandler, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventAcquireRequestState, steps); 
                app.CreateEventExecutionSteps(HttpApplication.EventPostAcquireRequestState, steps); 
                app.CreateEventExecutionSteps(HttpApplication.EventPreRequestHandlerExecute, steps);
                steps.Add(new CallHandlerExecutionStep(app));  // execute handler 
                app.CreateEventExecutionSteps(HttpApplication.EventPostRequestHandlerExecute, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventReleaseRequestState, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPostReleaseRequestState, steps);
                steps.Add(new CallFilterExecutionStep(app));  // filtering 
                app.CreateEventExecutionSteps(HttpApplication.EventUpdateRequestCache, steps);
                app.CreateEventExecutionSteps(HttpApplication.EventPostUpdateRequestCache, steps); 
                _endRequestStepIndex = steps.Count; 
                app.CreateEventExecutionSteps(HttpApplication.EventEndRequest, steps);
                steps.Add(new NoopExecutionStep()); // the last is always there 

                _execSteps = new IExecutionStep[steps.Count];
                steps.CopyTo(_execSteps);
 
                // callback for async completion when reposting to threadpool thread
                _resumeStepsWaitCallback = stepCallback; 
            } 

            internal override void InitRequest() { 
                _currentStepIndex   = -1;
                _numStepCalls       = 0;
                _numSyncStepCalls   = 0;
                _requestCompleted   = false; 
            }
 
            // This attribute prevents undesirable 'just-my-code' debugging behavior (VSWhidbey 404406/VSWhidbey 609188) 
            [System.Diagnostics.DebuggerStepperBoundaryAttribute]
            internal override void ResumeSteps(Exception error) { 
                bool appCompleted  = false;
                bool stepCompletedSynchronously = true;
                HttpApplication app = _application;
                HttpContext context = app.Context; 
                ThreadContext threadContext = null;
                AspNetSynchronizationContext syncContext = context.SyncContext; 
 
                Debug.Trace("Async", "HttpApplication.ResumeSteps");
 
                lock (_application) {
                    // avoid ---- between the app code and fast async completion from a module

                    try { 
                        threadContext = app.OnThreadEnter();
                    } 
                    catch (Exception e) { 
                        if (error == null)
                            error = e; 
                    }

                    try {
                        try { 
                            for (;;) {
                                // record error 
 
                                if (syncContext.Error != null) {
                                    error = syncContext.Error; 
                                    syncContext.ClearError();
                                }

                                if (error != null) { 
                                    app.RecordError(error);
                                    error = null; 
                                } 

                                // check for any outstanding async operations 

                                if (syncContext.PendingOperationsCount > 0) {
#if DBG
                                    Debug.Trace("Async", "Application has " + syncContext.PendingOperationsCount + " pending async operations"); 
#endif
                                    // wait until all pending async operations complete 
                                    syncContext.SetLastCompletionWorkItem(_resumeStepsWaitCallback); 
                                    break;
                                } 

                                // advance to next step

                                if (_currentStepIndex < _endRequestStepIndex && (context.Error != null || _requestCompleted)) { 
                                    // end request
                                    context.Response.FilterOutput(); 
                                    _currentStepIndex = _endRequestStepIndex; 
                                }
                                else { 
                                    _currentStepIndex++;
                                }

                                if (_currentStepIndex >= _execSteps.Length) { 
                                    appCompleted = true;
                                    break; 
                                } 

                                // execute the current step 

                                _numStepCalls++;          // count all calls

                                // enable launching async operations before each new step 
                                context.SyncContext.Enable();
 
                                // call to execute current step catching thread abort exception 
                                error = app.ExecuteStep(_execSteps[_currentStepIndex], ref stepCompletedSynchronously);
 
                                // unwind the stack in the async case
                                if (!stepCompletedSynchronously)
                                    break;
 
                                _numSyncStepCalls++;      // count synchronous calls
                            } 
                        } 
                        finally {
                            if (threadContext != null) { 
                                try {
                                    threadContext.Leave();
                                }
                                catch { 
                                }
                            } 
                        } 
                    }
                    catch { // Protect against exception filters 
                        throw;
                    }

                }   // lock 

                if (appCompleted) { 
                    // unroot context (async app operations ended) 
                    context.Unroot();
 
                    // async completion
                    app.AsyncResult.Complete((_numStepCalls == _numSyncStepCalls), null, null);
                    app.ReleaseAppInstance();
                } 
            }
        } 
 
        internal class PipelineStepManager : StepManager {
 
            WaitCallback _resumeStepsWaitCallback;
            bool _validatePathCalled;
            bool _validateInputCalled;
 
            internal PipelineStepManager(HttpApplication app): base(app) {
            } 
 
            internal override void BuildSteps(WaitCallback stepCallback) {
                Debug.Trace("PipelineRuntime", "BuildSteps"); 
                //ArrayList steps = new ArrayList();
                HttpApplication app = _application;

                // add special steps that don't currently 
                // correspond to a configured handler
 
                IExecutionStep materializeStep = new MaterializeHandlerExecutionStep(app); 

                // implicit map step 
                app.AddEventMapping(
                    HttpApplication.IMPLICIT_HANDLER,
                    RequestNotification.MapRequestHandler,
                    false, materializeStep); 

                // implicit handler routing step 
                IExecutionStep handlerStep = new CallHandlerExecutionStep(app); 

                app.AddEventMapping( 
                    HttpApplication.IMPLICIT_HANDLER,
                    RequestNotification.ExecuteRequestHandler,
                    false, handlerStep);
 
                // add implicit request filtering step
                IExecutionStep filterStep = new CallFilterExecutionStep(app); 
 
                // normally, this executes during UpdateRequestCache as a high priority module
                app.AddEventMapping( 
                    HttpApplication.IMPLICIT_FILTER_MODULE,
                    RequestNotification.UpdateRequestCache,
                    false, filterStep);
 
                // for error conditions, this executes during LogRequest as a high priority module
                app.AddEventMapping( 
                    HttpApplication.IMPLICIT_FILTER_MODULE, 
                    RequestNotification.LogRequest,
                    false, filterStep); 

                _resumeStepsWaitCallback = stepCallback;
            }
 
            internal override void InitRequest() {
                _requestCompleted = false; 
                _validatePathCalled = false; 
                _validateInputCalled = false;
            } 

            // PipelineStepManager::ResumeSteps
            // called from IIS7 (on IIS thread) via BeginProcessRequestNotification
            // or from an async completion (on CLR thread) via HttpApplication::ResumeStepsFromThreadPoolThread 
            // This attribute prevents undesirable 'just-my-code' debugging behavior (VSWhidbey 404406/VSWhidbey 609188)
            [System.Diagnostics.DebuggerStepperBoundaryAttribute] 
            internal override void ResumeSteps(Exception error) { 
                HttpContext context = _application.Context;
                IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest; 
                AspNetSynchronizationContext syncContext = context.SyncContext;

                RequestNotificationStatus status = RequestNotificationStatus.Continue;
                HttpApplication.ThreadContext threadContext = null; 
                bool isSynchronousCompletion = false;
                bool needToComplete = false; 
                bool stepCompletedSynchronously = false; 
                int currentModuleLastEventIndex = _application.CurrentModuleContainer.GetEventCount(context.CurrentNotification, context.IsPostNotification) - 1;
 
                // DevDiv Bugs 187441: IIS7 Integrated Mode: Problem flushing Response from background threads in IIS7 integrated mode
                bool isReEntry = context.NotificationContext.IsReEntry;
                if (!isReEntry) // currently we only re-enter for SendResponse
                { 
#pragma warning disable 0618
                    //@ 
                    Monitor.Enter(_application); 
#pragma warning restore 0618
                } 
                try {
                    bool locked = false;
                    try {
                        // As a performance optimization, ASP.NET uses the IIS IHttpContext::IndicateCompletion function to continue executing notifications 
                        // on a thread that is associated with the AppDomain.  This is done by calling IndicateCompletion from within the AppDomain, instead
                        // of returning to native code.  This technique can only be used for notifications that complete synchronously. 
 
                        // There are two cases where notifications happen on a thread that has an initialized ThreadContext, and therefore does not need
                        // to call ThreadContext.OnThreadEnter.  These include SendResponse notifications and notifications that occur within a call to 
                        // IndicateCompletion.  Note that SendResponse notifications occur on-demand, i.e., they happen when another notification triggers
                        // a SendResponse, at which point it blocks until the SendResponse notification completes.

                        if (!isReEntry) { // currently we only re-enter for SendResponse 
                            if (context.InIndicateCompletion) {
                                // we already have a ThreadContext 
                                threadContext = context.IndicateCompletionContext; 
                                if (context.UsesImpersonation) {
                                    // UsesImpersonation is set to true after RQ_AUTHENTICATE_REQUEST 
                                    threadContext.SetImpersonationContext();
                                }
                            }
                            else { 
                                // we need to create a new ThreadContext
                                threadContext = _application.OnThreadEnter(context.UsesImpersonation); 
                            } 
                        }
 
                        for(;;) {
#if DBG
                            Debug.Trace("PipelineRuntime", "ResumeSteps: CurrentModuleEventIndex=" + context.CurrentModuleEventIndex);
#endif 

                            // check and record errors into the HttpContext 
                            if (syncContext.Error != null) { 
                                error = syncContext.Error;
                                syncContext.ClearError(); 
                            }
                            if (error != null) {
                                // the error can be cleared by the user
                                _application.RecordError(error); 
                                error = null;
                            } 
 
                            if (!_validateInputCalled || !_validatePathCalled) {
                                error = ValidateHelper(context); 
                                if (error != null) {
                                    continue;
                                }
                            } 

                            // check for any outstanding async operations 
                            if (syncContext.PendingOperationsCount > 0) { 
#if DBG
                                Debug.Trace("Async", "Application has " + syncContext.PendingOperationsCount + " pending async operations"); 
#endif
                                // Since the step completed asynchronously, this thread must return RequestNotificationStatus.Pending to IIS,
                                // and the async completion of this step must call IIS7WorkerRequest::PostCompletion.  The async completion of
                                // this step will call ResumeSteps again. 
                                 context.NotificationContext.PendingAsyncCompletion = true;
 
                                // wait until all pending async operations complete 
                                syncContext.SetLastCompletionWorkItem(_resumeStepsWaitCallback);
 
                                break;
                            }

                            // LogRequest and EndRequest never report errors, and never return a status of FinishRequest. 
                            bool needToFinishRequest = ( context.NotificationContext.Error != null || context.NotificationContext.RequestCompleted )
                                && context.CurrentNotification != RequestNotification.LogRequest 
                                && context.CurrentNotification != RequestNotification.EndRequest; 

                            if (needToFinishRequest || context.CurrentModuleEventIndex == currentModuleLastEventIndex) { 

                                // if an error occured or someone completed the request, set the status to FinishRequest
                                status = needToFinishRequest ? RequestNotificationStatus.FinishRequest : RequestNotificationStatus.Continue;
 
                                // async case
                                if (context.NotificationContext.PendingAsyncCompletion) { 
                                    context.Response.SyncStatusIntegrated(); 
                                    context.NotificationContext.PendingAsyncCompletion = false;
                                    isSynchronousCompletion = false; 
                                    needToComplete = true;
                                    break;
                                }
 
                                // [....] case (we might be able to stay in managed code and execute another notification)
                                if (needToFinishRequest || UnsafeIISMethods.MgdGetNextNotification(wr.RequestContext, RequestNotificationStatus.Continue) != 1) { 
                                    isSynchronousCompletion = true; 
                                    needToComplete = true;
                                    break; 
                                }

                                int currentModuleIndex = 0;
                                bool isPostNotification = false; 
                                int currentNotification = 0;
 
                                UnsafeIISMethods.MgdGetCurrentNotificationInfo(wr.RequestContext, out currentModuleIndex, out isPostNotification, out currentNotification); 

                                // setup the HttpContext for this event/module combo 
                                context.CurrentModuleIndex = currentModuleIndex;
                                context.IsPostNotification = isPostNotification;
                                context.CurrentNotification = (RequestNotification) currentNotification;
                                context.CurrentModuleEventIndex = -1; 
                                currentModuleLastEventIndex = _application.CurrentModuleContainer.GetEventCount(context.CurrentNotification, context.IsPostNotification) - 1;
                            } 
 
                            context.CurrentModuleEventIndex++;
 
                            IExecutionStep step = _application.CurrentModuleContainer.GetNextEvent(context.CurrentNotification, context.IsPostNotification,
                                                                                                   context.CurrentModuleEventIndex);

                            // enable launching async operations before each new step 
                            context.SyncContext.Enable();
 
                            stepCompletedSynchronously = false; 
                            error = _application.ExecuteStep(step, ref stepCompletedSynchronously);
 
#if DBG
                            Debug.Trace("PipelineRuntime", "ResumeSteps: notification=" + context.CurrentNotification.ToString()
                                        + ", isPost=" + context.IsPostNotification
                                        + ", step=" + step.GetType().FullName 
                                        + ", completedSync="  + stepCompletedSynchronously
                                        + ", moduleName=" + _application.CurrentModuleContainer.DebugModuleName 
                                        + ", moduleIndex=" + context.CurrentModuleIndex 
                                        + ", eventIndex=" + context.CurrentModuleEventIndex);
#endif 


                            if (!stepCompletedSynchronously) {
                                // Since the step completed asynchronously, this thread must return RequestNotificationStatus.Pending to IIS, 
                                // and the async completion of this step must call IIS7WorkerRequest::PostCompletion.  The async completion of
                                // this step will call ResumeSteps again. 
                                //context.AcquireNotifcationContextLockBeforeUnwind(); 
                                _application.AcquireNotifcationContextLock(ref locked);
                                context.NotificationContext.PendingAsyncCompletion = true; 
                                break;
                            }
                            else {
                                context.Response.SyncStatusIntegrated(); 
                            }
                        } 
                    } 
                    finally {
                        if (locked) { 
                            _application.ReleaseNotifcationContextLock();
                        }
                        if (threadContext != null) {
                            if (context.InIndicateCompletion) { 
                                if (isSynchronousCompletion) {
                                    // this is a [....] completion on an IIS thread 
                                    threadContext.Synchronize(context); 
                                    //always undo impersonation so that the token is removed before returning to IIS (DDB 156421)
                                    threadContext.UndoImpersonationContext(); 
                                }
                                else {
                                    // We're returning pending on an IIS thread in a call to IndicateCompletion.
                                    // Leave the thread context now while we're still under the lock so that the 
                                    // async completion does not corrupt the state of HttpContext or IndicateCompletionContext.
                                    if (!threadContext.HasLeaveBeenCalled) { 
                                        lock (threadContext) { 
                                            if (!threadContext.HasLeaveBeenCalled) {
                                                threadContext.Leave(); 
                                                context.IndicateCompletionContext = null;
                                                context.InIndicateCompletion = false;
                                            }
                                        } 
                                    }
                                } 
                            } 
                            else if (isSynchronousCompletion){
                                // this is a [....] completion on an IIS thread 
                                threadContext.Synchronize(context);
                                // get ready to call IndicateCompletion
                                context.IndicateCompletionContext = threadContext;
                                //always undo impersonation so that the token is removed before returning to IIS (DDB 156421) 
                                threadContext.UndoImpersonationContext();
                            } 
                            else { 
                                // We're not in a call to IndicateCompletion.  We're either returning pending or
                                // we're in an async completion, and therefore we must clean-up the thread state. Impersonation is reverted 
                                threadContext.Leave();
                            }
                        }
                    } 

                    // WOS #1703315: we cannot complete until after OnThreadLeave is called. 
                    if (needToComplete) { 
                        // call HttpRuntime::OnRequestNotificationCompletion
                        _application.AsyncResult.Complete(isSynchronousCompletion, null /*result*/, null /*error*/, status); 
                    }
                } // end of try statement that begins after Monitor.Enter(_application)
                finally {
                    if (!isReEntry) 
                    {
                        Monitor.Exit(_application); 
                    } 
                }
            } 

            private Exception ValidateHelper(HttpContext context) {
                if (!_validateInputCalled) {
                    _validateInputCalled = true; 
                    try {
                        context.Request.ValidateInputIfRequiredByConfig(); 
                    } 
                    catch(Exception e) {
                        return e; 
                    }
                }
                if (!_validatePathCalled) {
                    _validatePathCalled = true; 
                    try {
                        context.ValidatePath(); 
                    } 
                    catch(Exception e) {
                        return e; 
                    }
                }
                return null;
            } 
        }
    } 
} 

// 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