WebEvents.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / xsp / System / Web / Management / WebEvents.cs / 2 / WebEvents.cs

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

namespace System.Web.Management { 
    using System; 
    using System.Web;
    using System.Diagnostics; 
    using System.Security.Principal;
    using System.Threading;
    using System.Reflection;
    using System.Text; 
    using System.Web.Util;
    using System.Web.Configuration; 
    using System.Configuration.Provider; 
    using System.Collections;
    using System.Collections.Generic; 
    using System.Configuration;
    using System.Security;
    using Debug=System.Web.Util.Debug;
    using System.Web.Hosting; 
    using System.Web.UI;
    using System.Globalization; 
    using System.Runtime.Remoting.Messaging; 
    using System.Security.Permissions;
    using System.Web.Caching; 

    // This enum matches the native one enum WebEventType (in webevent.h).
    internal enum WebEventType : int {
        WEBEVENT_BASE_EVENT = 0, 
        WEBEVENT_MANAGEMENT_EVENT,
        WEBEVENT_APP_LIFETIME_EVENT, 
        WEBEVENT_REQUEST_EVENT, 
        WEBEVENT_HEARTBEAT_EVENT,
        WEBEVENT_BASE_ERROR_EVENT, 
        WEBEVENT_REQUEST_ERROR_EVENT,
        WEBEVENT_ERROR_EVENT,
        WEBEVENT_AUDIT_EVENT,
        WEBEVENT_SUCCESS_AUDIT_EVENT, 
        WEBEVENT_AUTHENTICATION_SUCCESS_AUDIT_EVENT,
        WEBEVENT_FAILURE_AUDIT_EVENT, 
        WEBEVENT_AUTHENTICATION_FAILURE_AUDIT_EVENT, 
        WEBEVENT_VIEWSTATE_FAILURE_AUDIT_EVENT,
    }; 

    internal enum WebEventFieldType : int {
        String = 0,
        Int = 1, 
        Bool = 2,
        Long = 3, 
        Date = 4, 
    }
 
    // Used for marshalling over to IIS Trace
    internal class WebEventFieldData {
        string _name;
        public string Name { 
            get {
                return _name; 
            } 
        }
 
        string _data;
        public string Data {
            get {
                return _data; 
            }
        } 
 
        WebEventFieldType _type;
        public WebEventFieldType Type { 
            get {
                return _type;
            }
        } 

        public WebEventFieldData(string name, string data, WebEventFieldType type) { 
            _name = name; 
            _data = data;
            _type = type; 
        }
    }

 
    // Interface for event provider
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public abstract class WebEventProvider : ProviderBase {
 
        // methods
        public abstract void ProcessEvent(WebBaseEvent raisedEvent);
        public abstract void Shutdown();
        public abstract void Flush(); 

        int _exceptionLogged; 
 
        internal void LogException(Exception e) {
            // In order to not overflow the eventlog, we only log one exception per provider instance. 
            if (Interlocked.CompareExchange( ref _exceptionLogged, 1, 0) == 0) {
                // Log all errors in eventlog
                UnsafeNativeMethods.LogWebeventProviderFailure(
                                        HttpRuntime.AppDomainAppVirtualPath, 
                                        Name,
                                        e.ToString()); 
            } 
        }
    } 

    // Interface for custom event evaluator

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public interface IWebEventCustomEvaluator { 
        bool CanFire(WebBaseEvent raisedEvent, RuleFiringRecord record); 
    }
 
    ////////////////
    // Events
    ////////////////
 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebBaseEvent {
        DateTime        _eventTimeUtc; 
        int             _code;
        int             _detailCode;
        Object          _source;
        string          _message; 
        long            _sequenceNumber;
        long            _occurrenceNumber; 
        Guid            _id  = Guid.Empty; 

        static long                         s_globalSequenceNumber = 0; 
        static WebApplicationInformation    s_applicationInfo = new WebApplicationInformation();
        const string                        WEBEVENT_RAISE_IN_PROGRESS = "_WEvtRIP";

        // A array that cache the result of eventCode to SystemEventType mapping. 
        static readonly SystemEventType[,]  s_eventCodeToSystemEventTypeMappings = new SystemEventType[WebEventCodes.GetEventArrayDimensionSize(0),
                                                                  WebEventCodes.GetEventArrayDimensionSize(1)]; 
 
        // A array that store the # of occurrence per custom event code.
        static readonly long[,]             s_eventCodeOccurrence = new long[WebEventCodes.GetEventArrayDimensionSize(0), 
                                                                  WebEventCodes.GetEventArrayDimensionSize(1)];

        static Hashtable                    s_customEventCodeOccurrence = new Hashtable();
        #pragma warning disable 0649 
        static ReadWriteSpinLock            s_lockCustomEventCodeOccurrence;
        #pragma warning restore 0649 
 
        static WebBaseEvent() {
 
            // Initialize the mappings.  We will fill up each entry on demand by calling
            // SystemEventTypeFromEventCode().

            for (int i = 0; i < s_eventCodeToSystemEventTypeMappings.GetLength(0); i++) { 
                for (int j = 0; j < s_eventCodeToSystemEventTypeMappings.GetLength(1); j++) {
                    s_eventCodeToSystemEventTypeMappings[i,j] = SystemEventType.Unknown; 
                } 
            }
 
            for (int i = 0; i < s_eventCodeOccurrence.GetLength(0); i++) {
                for (int j = 0; j < s_eventCodeOccurrence.GetLength(1); j++) {
                    s_eventCodeOccurrence[i,j] = 0;
                } 
            }
        } 
 
        void Init(string message, Object eventSource, int eventCode, int eventDetailCode) {
            if (eventCode < 0) { 
                throw new ArgumentOutOfRangeException("eventCode",
                    SR.GetString(SR.Invalid_eventCode_error));
            }
 
            if (eventDetailCode < 0) {
                throw new ArgumentOutOfRangeException("eventDetailCode", 
                    SR.GetString(SR.Invalid_eventDetailCode_error)); 
            }
 
            _code = eventCode;
            _detailCode = eventDetailCode;
            _source = eventSource;
            _eventTimeUtc = DateTime.UtcNow; 
            _message = message;
 
            // Creation of _id is always delayed until it's needed. 
        }
 
        // ctors
        internal protected WebBaseEvent(string message, Object eventSource, int eventCode) {
            Init(message, eventSource, eventCode, WebEventCodes.UndefinedEventDetailCode);
        } 

        internal protected WebBaseEvent(string message, Object eventSource, int eventCode, int eventDetailCode) { 
            Init(message, eventSource, eventCode, eventDetailCode); 
        }
 
        internal WebBaseEvent() {
            // For creating dummy event.  See GetSystemDummyEvent()
        }
 
        internal bool IsSystemEvent {
            get { 
                return (_code < WebEventCodes.WebExtendedBase); 
            }
        } 

        // Properties

        public DateTime EventTime { get { return _eventTimeUtc.ToLocalTime(); } } 

        public DateTime EventTimeUtc { get { return _eventTimeUtc; } } 
 
        public String Message { get { return _message; } }
 
        public Object EventSource { get { return _source; } }

        public long EventSequence { get { return _sequenceNumber; } }
 
        public long EventOccurrence { get { return _occurrenceNumber; } }
 
        public int EventCode { get { return _code; } } 

        public int EventDetailCode { get { return _detailCode; } } 

        public Guid EventID {
            get {
                if (_id == Guid.Empty) { 
                    lock(this) {
                        if (_id == Guid.Empty) { 
                            _id = Guid.NewGuid(); 
                        }
                    } 
                }

                return _id;
            } 
        }
 
        public static WebApplicationInformation ApplicationInformation { 
            get { return s_applicationInfo; }
        } 

        virtual internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) {
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_code, EventCode.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_message, Message)); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_time, EventTime.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_time_Utc, EventTimeUtc.ToString(CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_id, EventID.ToString("N", CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_sequence, EventSequence.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_occurrence, EventOccurrence.ToString(CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_detail_code, EventDetailCode.ToString(CultureInfo.InstalledUICulture)));

            if (includeAppInfo) {
                formatter.AppendLine(String.Empty); 
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_application_information));
                formatter.IndentationLevel += 1; 
                ApplicationInformation.FormatToString(formatter); 
                formatter.IndentationLevel -= 1;
            } 
        }


        public override string ToString() { 
            return ToString(true, true);
        } 
 
        public virtual string ToString(bool includeAppInfo, bool includeCustomEventDetails) {
            WebEventFormatter   formatter = new WebEventFormatter(); 

            FormatToString(formatter, includeAppInfo);

            if (!IsSystemEvent && includeCustomEventDetails) { 
                formatter.AppendLine(String.Empty);
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_custom_event_details)); 
                formatter.IndentationLevel += 1; 
                FormatCustomEventDetails(formatter);
                formatter.IndentationLevel -= 1; 
            }

            return formatter.ToString();
        } 

        virtual public void FormatCustomEventDetails(WebEventFormatter formatter) { 
        } 

        internal int InferEtwTraceVerbosity() { 
            WebEventType type = WebBaseEvent.WebEventTypeFromWebEvent(this);
            switch (type) {
                case WebEventType.WEBEVENT_VIEWSTATE_FAILURE_AUDIT_EVENT:
                case WebEventType.WEBEVENT_BASE_ERROR_EVENT: 
                case WebEventType.WEBEVENT_REQUEST_ERROR_EVENT:
                case WebEventType.WEBEVENT_FAILURE_AUDIT_EVENT: 
                case WebEventType.WEBEVENT_AUTHENTICATION_FAILURE_AUDIT_EVENT: 
                case WebEventType.WEBEVENT_ERROR_EVENT:
                    return EtwTraceLevel.Warning; 
                case WebEventType.WEBEVENT_AUDIT_EVENT:
                case WebEventType.WEBEVENT_SUCCESS_AUDIT_EVENT:
                case WebEventType.WEBEVENT_AUTHENTICATION_SUCCESS_AUDIT_EVENT:
                    return EtwTraceLevel.Information; 
                case WebEventType.WEBEVENT_BASE_EVENT:
                case WebEventType.WEBEVENT_MANAGEMENT_EVENT: 
                case WebEventType.WEBEVENT_REQUEST_EVENT: 
                default:
                    return EtwTraceLevel.Verbose; 
            }
        }

        internal void DeconstructWebEvent(out int eventType, out int fieldCount, out string[] fieldNames, out int[] fieldTypes, out string[] fieldData) { 
            List fields = new List();
 
            eventType = (int)WebBaseEvent.WebEventTypeFromWebEvent(this); 
            GenerateFieldsForMarshal(fields);
            fieldCount = fields.Count; 
            fieldNames = new string[fieldCount];
            fieldData = new string[fieldCount];
            fieldTypes = new int[fieldCount];
 
            for (int i = 0; i < fieldCount; ++i) {
                fieldNames[i] = fields[i].Name; 
                fieldData[i] = fields[i].Data; 
                fieldTypes[i] = (int)fields[i].Type;
            } 
        }

        internal virtual void GenerateFieldsForMarshal(List fields) {
            fields.Add(new WebEventFieldData("EventTime", EventTimeUtc.ToString(), WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("EventID", EventID.ToString(), WebEventFieldType.String));
            fields.Add(new WebEventFieldData("EventMessage", Message, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("ApplicationDomain", WebBaseEvent.ApplicationInformation.ApplicationDomain, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("TrustLevel", WebBaseEvent.ApplicationInformation.TrustLevel, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("ApplicationVirtualPath", WebBaseEvent.ApplicationInformation.ApplicationVirtualPath, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("ApplicationPath", WebBaseEvent.ApplicationInformation.ApplicationPath, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("MachineName", WebBaseEvent.ApplicationInformation.MachineName, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("EventCode", EventCode.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Int));
            fields.Add(new WebEventFieldData("EventDetailCode", EventDetailCode.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Int)); 
            fields.Add(new WebEventFieldData("SequenceNumber", EventSequence.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Long));
            fields.Add(new WebEventFieldData("Occurrence", EventOccurrence.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Long)); 
        } 

        internal virtual void PreProcessEventInit() { 
        }

        static void FindEventCode(Exception e, ref int eventCode, ref int eventDetailsCode, ref Exception eStack) {
            eventDetailsCode = WebEventCodes.UndefinedEventDetailCode; 

            if (e is ConfigurationException) { 
                eventCode = WebEventCodes.WebErrorConfigurationError; 
            }
            else if (e is HttpRequestValidationException) { 
                eventCode = WebEventCodes.RuntimeErrorValidationFailure;
            }
            else if (e is HttpCompileException) {
                eventCode = WebEventCodes.WebErrorCompilationError; 
            }
            else if (e is SecurityException) { 
                eventCode = WebEventCodes.AuditUnhandledSecurityException; 
            }
            else if (e is UnauthorizedAccessException) { 
                eventCode = WebEventCodes.AuditUnhandledAccessException;
            }
            else  if (e is HttpParseException) {
                eventCode = WebEventCodes.WebErrorParserError; 
            }
            else if (e is HttpException && e.InnerException is ViewStateException) { 
                ViewStateException vse = (ViewStateException)e.InnerException; 
                eventCode = WebEventCodes.AuditInvalidViewStateFailure;
                if (vse._macValidationError) { 
                    eventDetailsCode = WebEventCodes.InvalidViewStateMac;
                }
                else {
                    eventDetailsCode = WebEventCodes.InvalidViewState; 
                }
 
                eStack = vse; 
            }
            else if (e is HttpException && ((HttpException)e).WebEventCode != WebEventCodes.UndefinedEventCode) { 
                eventCode = ((HttpException)e).WebEventCode;
            }
            else {
                // We don't know what it is.  Let's see if we can find it out by using the inner exception. 

                if (e.InnerException != null) { 
                    // We will call FindEventCode recusively to find out if e.InnerException is the real one. 

                    if (eStack == null) { 
                        // Set eStack here.  If the recursive call ends up landing in
                        // WebEventCodes.RuntimeErrorUnhandledException, we'll use the original
                        // inner exception as our final result.
                        eStack = e.InnerException; 
                    }
 
                    FindEventCode(e.InnerException, ref eventCode, ref eventDetailsCode, ref eStack); 
                }
                else { 
                    // It doesn't have an inner exception.  Just return the generic unhandled-exception
                    eventCode = WebEventCodes.RuntimeErrorUnhandledException;
                }
            } 

            if (eStack == null) { 
                eStack = e; 
            }
        } 

        static internal void RaiseRuntimeError(Exception e, object source) {
            Debug.Trace("WebEventRaiseError", "Error Event is raised; type=" + e.GetType().Name);
 
            if (!HealthMonitoringManager.Enabled) {
                return; 
            } 

            try { 
                int         eventCode = WebEventCodes.UndefinedEventCode;
                int         eventDetailsCode = WebEventCodes.UndefinedEventDetailCode;
                HttpContext context = HttpContext.Current;
                Exception   eStack = null; 

                if (context != null) { 
                    Page    page = context.Handler as Page; 

                    // Errors from Transacted pages can be wrapped by a 
                    // HttpException
                    if (page != null &&
                        page.IsTransacted &&
                        e.GetType() == typeof(HttpException) && 
                        e.InnerException != null) {
 
                        e = e.InnerException; 
                    }
                } 

                FindEventCode(e, ref eventCode, ref eventDetailsCode, ref eStack);
                WebBaseEvent.RaiseSystemEvent(source, eventCode, eventDetailsCode, eStack);
            } 
            catch {
            } 
        } 

        virtual internal protected void IncrementPerfCounters() { 
            PerfCounters.IncrementCounter(AppPerfCounter.EVENTS_TOTAL);
        }

        class CustomEventCodeOccurrence { 
            internal long    _occurrence;
        } 
 
        internal void IncrementTotalCounters(int index0, int index1) {
            _sequenceNumber = Interlocked.Increment(ref s_globalSequenceNumber); 

            if (index0 != -1) {
                _occurrenceNumber = Interlocked.Increment(ref s_eventCodeOccurrence[index0, index1]);
            } 
            else {
                CustomEventCodeOccurrence ceco = (CustomEventCodeOccurrence)s_customEventCodeOccurrence[_code]; 
 
                if (ceco == null) {
                    s_lockCustomEventCodeOccurrence.AcquireWriterLock(); 
                    try {
                        ceco = (CustomEventCodeOccurrence)s_customEventCodeOccurrence[_code];
                        if (ceco == null) {
                            ceco = new CustomEventCodeOccurrence(); 
                            s_customEventCodeOccurrence[_code] = ceco;
                        } 
                    } 
                    finally {
                        s_lockCustomEventCodeOccurrence.ReleaseWriterLock(); 
                    }
                }

                _occurrenceNumber = Interlocked.Increment(ref ceco._occurrence); 
            }
        } 
 
        [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)]
        virtual public void Raise() { 
            Raise(this);
        }

        // Internally raised events don't go thru this method.  They go directly to RaiseSystemEvent --> RaiseInternal 
        [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)]
        static public void Raise(WebBaseEvent eventRaised) { 
            if (eventRaised.EventCode < WebEventCodes.WebExtendedBase) { 
                throw new HttpException(SR.GetString(SR.System_eventCode_not_allowed,
                        eventRaised.EventCode.ToString(CultureInfo.CurrentCulture), 
                        WebEventCodes.WebExtendedBase.ToString(CultureInfo.CurrentCulture)));
            }

            if (!HealthMonitoringManager.Enabled) { 
                Debug.Trace(
                    "WebEventRaiseDetails", "Can't fire event because we are disabled or we can't configure HealthMonManager"); 
                return; 
            }
 
            RaiseInternal(eventRaised, null, -1, -1);
        }

        static internal void RaiseInternal(WebBaseEvent eventRaised, ArrayList firingRuleInfos, int index0, int index1) { 
            bool    preProcessEventInitCalled = false;
            bool    inProgressSet = false; 
            object  o; 
            ProcessImpersonationContext ictx = null;
            HttpContext context = HttpContext.Current; 

            Debug.Trace(
                "WebEventRaiseDetails", "Event is raised; event class = " + eventRaised.GetType().Name);
 
            // Use CallContext to make sure we detect an infinite loop where a provider calls Raise().
            o = CallContext.GetData(WEBEVENT_RAISE_IN_PROGRESS); 
            if (o != null && (bool)o) { 
                Debug.Trace(
                    "WebEventRaiseDetails", "An event is raised while we're raising an event.  Ignore it."); 
                return;
            }

            eventRaised.IncrementPerfCounters(); 
            eventRaised.IncrementTotalCounters(index0, index1);
 
            // Find the list of rules that match this event 
            if (firingRuleInfos == null) {
                HealthMonitoringManager manager = HealthMonitoringManager.Manager(); 

                Debug.Assert(manager != null, "manager != null");

                firingRuleInfos = manager._sectionHelper.FindFiringRuleInfos(eventRaised.GetType(), eventRaised.EventCode); 
            }
 
            if (firingRuleInfos.Count == 0) { 
                return;
            } 

            try {
                bool[]  matchingProviderArray = null;
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null)
                    EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_RAISE_START, 
                                   context.WorkerRequest, 
                                   eventRaised.GetType().FullName,
                                   eventRaised.EventCode.ToString(CultureInfo.InstalledUICulture), 
                                   eventRaised.EventDetailCode.ToString(CultureInfo.InstalledUICulture),
                                   null);

                try { 
                    foreach (HealthMonitoringSectionHelper.FiringRuleInfo firingRuleInfo in firingRuleInfos) {
                        HealthMonitoringSectionHelper.RuleInfo  ruleInfo = firingRuleInfo._ruleInfo; 
                        RuleFiringRecord record = ruleInfo._ruleFiringRecord; 

                        // Check if we should fire the event based on its throttling settings 
                        if (!record.CheckAndUpdate(eventRaised)) {
                            Debug.Trace("WebEventRaiseDetails",
                                    "Throttling settings not met; not fired");
                            continue; 
                        }
 
                        // It's valid for a rule to have no referenced provider 
                        if (ruleInfo._referencedProvider != null) {
                            if (!preProcessEventInitCalled) { 
                                // The event may need to do pre-ProcessEvent initialization
                                eventRaised.PreProcessEventInit();
                                preProcessEventInitCalled = true;
                            } 

                            // For rule infos that share the same provider, the _indexOfFirstRuleInfoWithSameProvider field 
                            // is the index of the first ruleInfo among them.  We use that index in the boolean array 
                            // matchingProviderArray to remember if we've already fired that provider.
                            // This is for the scenario where several rules are pointing to the same provider, 
                            // and even if >1 rule actually fire and pass all throttling check,
                            // the provider is stilled fired only once.
                            if (firingRuleInfo._indexOfFirstRuleInfoWithSameProvider != -1) {
                                if (matchingProviderArray == null) { 
                                    matchingProviderArray = new bool[firingRuleInfos.Count];
                                } 
 
                                if (matchingProviderArray[firingRuleInfo._indexOfFirstRuleInfoWithSameProvider]) {
                                    Debug.Trace("WebEventRaiseDetails", 
                                            "Rule with a matching provider already fired.");
                                    continue;
                                }
 
                                matchingProviderArray[firingRuleInfo._indexOfFirstRuleInfoWithSameProvider] = true;
                            } 
 
                            if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null)
                                EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_DELIVER_START, 
                                               context.WorkerRequest,
                                               ruleInfo._ruleSettings.Provider,
                                               ruleInfo._ruleSettings.Name,
                                               ruleInfo._ruleSettings.EventName, 
                                               null);
 
                            // In retail build, ignore errors from provider 
                            try {
                                if (ictx == null) { 
                                    ictx = new ProcessImpersonationContext();
                                }

                                if (!inProgressSet) { 
                                    CallContext.SetData(WEBEVENT_RAISE_IN_PROGRESS, true);
                                    inProgressSet = true; 
                                } 

                                Debug.Trace("WebEventRaiseDetails", "Calling ProcessEvent under " + WindowsIdentity.GetCurrent().Name); 
                                ruleInfo._referencedProvider.ProcessEvent(eventRaised);
                            }
                            catch (Exception e) {
                                try { 
                                    ruleInfo._referencedProvider.LogException(e);
                                } 
                                catch { 
                                    // ignore all errors
                                } 
                            }
                            finally {
                                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null)
                                    EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_DELIVER_END, 
                                                   context.WorkerRequest);
                            } 
                        } 
                    }
                } 
                finally {
                    // Resume client impersonation
                    if (ictx != null) {
                        ictx.Undo(); 
                    }
 
                    if (inProgressSet) { 
                        CallContext.FreeNamedDataSlot(WEBEVENT_RAISE_IN_PROGRESS);
                    } 

                    if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null)
                        EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_RAISE_END,
                                       context.WorkerRequest); 
                }
            } 
            catch { throw; }    // Prevent Exception Filter Security Issue (ASURT 122835) 
        }
 
        internal static void RaiseSystemEvent(string message, object source, int eventCode, int eventDetailCode, Exception exception) {
            RaiseSystemEventInternal(message, source, eventCode, eventDetailCode, exception, null);
        }
 
        internal static void RaiseSystemEvent(object source, int eventCode) {
            RaiseSystemEventInternal(null, source, eventCode, WebEventCodes.UndefinedEventDetailCode, null, null); 
        } 

        internal static void RaiseSystemEvent(object source, int eventCode, int eventDetailCode) { 
            RaiseSystemEventInternal(null, source, eventCode, eventDetailCode, null, null);
        }

        internal static void RaiseSystemEvent(object source, int eventCode, int eventDetailCode, Exception exception) { 
            RaiseSystemEventInternal(null, source, eventCode, eventDetailCode, exception, null);
        } 
 
        internal static void RaiseSystemEvent(object source, int eventCode, string nameToAuthenticate) {
            RaiseSystemEventInternal(null, source, eventCode, WebEventCodes.UndefinedEventDetailCode, null, nameToAuthenticate); 
        }

        static void RaiseSystemEventInternal(string message, object source,
                        int eventCode, int eventDetailCode, Exception exception, 
                        string nameToAuthenticate) {
            HealthMonitoringManager manager; 
            ArrayList       firingRuleInfos; 
            SystemEventTypeInfo typeInfo;
            SystemEventType     systemEventType; 
            int                 index0, index1;

            Debug.Trace(
                "WebEventRaiseDetails", "RaiseSystemEventInternal called; eventCode=" + eventCode + "; eventDetailCode=" + eventDetailCode); 

            if (!HealthMonitoringManager.Enabled) { 
                Debug.Trace( 
                    "WebEventRaiseDetails", "Can't fire event because we are disabled or we can't configure HealthMonManager");
                return; 
            }

            WebEventCodes.GetEventArrayIndexsFromEventCode(eventCode, out index0, out index1);
 
            GetSystemEventTypeInfo(eventCode, index0, index1, out typeInfo, out systemEventType);
            if (typeInfo == null) { 
                Debug.Assert(false, "Unexpected system event code = " + eventCode); 
                return;
            } 

            manager = HealthMonitoringManager.Manager();

            // Figure out if there is any provider that subscribes to it 
            firingRuleInfos = manager._sectionHelper.FindFiringRuleInfos(typeInfo._type, eventCode);
            if (firingRuleInfos.Count == 0) { 
                // Even if we're not firing it, we still have to increment some global counters 
                typeInfo._dummyEvent.IncrementPerfCounters();
                typeInfo._dummyEvent.IncrementTotalCounters(index0, index1); 
            }
            else {
                // We will fire the event
                WebBaseEvent.RaiseInternal( 
                                NewEventFromSystemEventType(false, systemEventType, message, source, eventCode, eventDetailCode,
                                                        exception, nameToAuthenticate), 
                                firingRuleInfos, index0, index1); 
            }
        } 

        // An enum of all the types of web event we will fire
        enum SystemEventType {
            Unknown = -1, 
            WebApplicationLifetimeEvent,
            WebHeartbeatEvent, 
            WebRequestEvent, 
            WebRequestErrorEvent,
            WebErrorEvent, 
            WebAuthenticationSuccessAuditEvent,
            WebSuccessAuditEvent,
            WebAuthenticationFailureAuditEvent,
            WebFailureAuditEvent, 
            WebViewStateFailureAuditEvent,
            Last 
        }; 

        class SystemEventTypeInfo { 
            internal WebBaseEvent       _dummyEvent;    // For calling IncrementPerfCounters. See RaiseSystemEventInternal for details.
            internal Type               _type;

            internal SystemEventTypeInfo(WebBaseEvent dummyEvent) { 
                _dummyEvent = dummyEvent;
                _type = dummyEvent.GetType(); 
            } 
        };
 
        // An array to cache the event type info for each system event type
        static SystemEventTypeInfo[]    s_systemEventTypeInfos = new SystemEventTypeInfo[(int)SystemEventType.Last];

        static void GetSystemEventTypeInfo(int eventCode, int index0, int index1, 
                        out SystemEventTypeInfo info, out SystemEventType systemEventType) {
 
            // Figure out what SystemEventType this eventCode maps to. 
            // For each eventCode, we store the result in a cache.
            systemEventType = s_eventCodeToSystemEventTypeMappings[index0, index1]; 
            if (systemEventType == SystemEventType.Unknown) {
                systemEventType = SystemEventTypeFromEventCode(eventCode);
                s_eventCodeToSystemEventTypeMappings[index0, index1] = systemEventType;
            } 

            // Based on the systemEventType, we read the SystemEventTypeInfo.  For each 
            // event type, we also cache the info 
            info = s_systemEventTypeInfos[(int)systemEventType];
            if (info != null) { 
                return;
            }

            info = new SystemEventTypeInfo(CreateDummySystemEvent(systemEventType)); 
            s_systemEventTypeInfos[(int)systemEventType] = info;
        } 
 
        static SystemEventType SystemEventTypeFromEventCode(int eventCode) {
            if (eventCode >= WebEventCodes.ApplicationCodeBase && 
                eventCode <= WebEventCodes.ApplicationCodeBaseLast) {
                switch(eventCode) {
                    case WebEventCodes.ApplicationStart:
                    case WebEventCodes.ApplicationShutdown: 
                    case WebEventCodes.ApplicationCompilationStart:
                    case WebEventCodes.ApplicationCompilationEnd: 
                        return SystemEventType.WebApplicationLifetimeEvent; 

                    case WebEventCodes.ApplicationHeartbeat: 
                        return SystemEventType.WebHeartbeatEvent;
                }
            }
 
            if (eventCode >= WebEventCodes.RequestCodeBase &&
                eventCode <= WebEventCodes.RequestCodeBaseLast) { 
                switch(eventCode) { 

                    case WebEventCodes.RequestTransactionComplete: 
                    case WebEventCodes.RequestTransactionAbort:
                        return SystemEventType.WebRequestEvent;
                }
            } 

            if (eventCode >= WebEventCodes.ErrorCodeBase && 
                eventCode <= WebEventCodes.ErrorCodeBaseLast) { 
                switch(eventCode) {
                    case WebEventCodes.RuntimeErrorRequestAbort: 
                    case WebEventCodes.RuntimeErrorViewStateFailure:
                    case WebEventCodes.RuntimeErrorValidationFailure:
                    case WebEventCodes.RuntimeErrorPostTooLarge:
                    case WebEventCodes.RuntimeErrorUnhandledException: 
                        return SystemEventType.WebRequestErrorEvent;
 
                    case WebEventCodes.WebErrorParserError: 
                    case WebEventCodes.WebErrorCompilationError:
                    case WebEventCodes.WebErrorConfigurationError: 
                    case WebEventCodes.WebErrorOtherError:
                    case WebEventCodes.WebErrorPropertyDeserializationError:
                    case WebEventCodes.WebErrorObjectStateFormatterDeserializationError:
                        return SystemEventType.WebErrorEvent; 
                }
            } 
 
            if (eventCode >= WebEventCodes.AuditCodeBase &&
                eventCode <= WebEventCodes.AuditCodeBaseLast) { 
                switch(eventCode) {
                    case WebEventCodes.AuditFormsAuthenticationSuccess:
                    case WebEventCodes.AuditMembershipAuthenticationSuccess:
                        return SystemEventType.WebAuthenticationSuccessAuditEvent; 

                    case WebEventCodes.AuditUrlAuthorizationSuccess: 
                    case WebEventCodes.AuditFileAuthorizationSuccess: 
                        return SystemEventType.WebSuccessAuditEvent;
 
                    case WebEventCodes.AuditFormsAuthenticationFailure:
                    case WebEventCodes.AuditMembershipAuthenticationFailure:
                        return SystemEventType.WebAuthenticationFailureAuditEvent;
 
                    case WebEventCodes.AuditUrlAuthorizationFailure:
                    case WebEventCodes.AuditFileAuthorizationFailure: 
                    case WebEventCodes.AuditUnhandledSecurityException: 
                    case WebEventCodes.AuditUnhandledAccessException:
                        return SystemEventType.WebFailureAuditEvent; 

                    case WebEventCodes.AuditInvalidViewStateFailure:
                        return SystemEventType.WebViewStateFailureAuditEvent;
                } 
            }
 
            if (eventCode >= WebEventCodes.MiscCodeBase && 
                eventCode <= WebEventCodes.MiscCodeBaseLast) {
                switch(eventCode) { 
                    case WebEventCodes.WebEventProviderInformation:
                        Debug.Assert(false, "WebEventProviderInformation shouldn't be used to Raise an event");
                        return SystemEventType.Unknown;
                } 
            }
 
            return SystemEventType.Unknown; 
        }
 
        static WebBaseEvent CreateDummySystemEvent(SystemEventType systemEventType) {
            return NewEventFromSystemEventType(true, systemEventType, null,
                        null, 0, 0, null, null);
        } 

        static WebBaseEvent NewEventFromSystemEventType(bool createDummy, SystemEventType systemEventType, string message, 
                        object source,int eventCode, int eventDetailCode, Exception exception, 
                        string nameToAuthenticate) {
            // If createDummy == true, it means we're only creating a dummy event for the sake of using 
            // it to call IncrementPerfCounters()

            if (!createDummy && message == null) {
                message = WebEventCodes.MessageFromEventCode(eventCode, eventDetailCode); 
            }
 
            // Code view note for the future: 
            // If the number of systemEventType increases tremendoulsy, we may need to
            // avoid using switch, and change to use a "factory" to create new event. 

            switch(systemEventType) {
                case SystemEventType.WebApplicationLifetimeEvent:
                    return createDummy ? new WebApplicationLifetimeEvent() : new WebApplicationLifetimeEvent(message, source, eventCode, eventDetailCode); 

                case SystemEventType.WebHeartbeatEvent: 
                    return createDummy ? new WebHeartbeatEvent() : new WebHeartbeatEvent(message, eventCode); 

                case SystemEventType.WebRequestEvent: 
                    return createDummy ? new WebRequestEvent() : new WebRequestEvent(message, source, eventCode, eventDetailCode);

                case SystemEventType. WebRequestErrorEvent:
                    return createDummy ? new WebRequestErrorEvent() : new WebRequestErrorEvent(message, source, eventCode, eventDetailCode, exception); 

                case SystemEventType.WebErrorEvent: 
                    return createDummy ? new WebErrorEvent() : new WebErrorEvent(message, source, eventCode, eventDetailCode, exception); 

                case SystemEventType.WebAuthenticationSuccessAuditEvent: 
                    return createDummy ? new WebAuthenticationSuccessAuditEvent() : new WebAuthenticationSuccessAuditEvent(message, source, eventCode, eventDetailCode, nameToAuthenticate);

                case SystemEventType.WebSuccessAuditEvent:
                    return createDummy ? new WebSuccessAuditEvent() : new WebSuccessAuditEvent(message, source, eventCode, eventDetailCode); 

                case SystemEventType.WebAuthenticationFailureAuditEvent: 
                    return createDummy ? new WebAuthenticationFailureAuditEvent() : new WebAuthenticationFailureAuditEvent(message, source, eventCode, eventDetailCode, nameToAuthenticate); 

                case SystemEventType.WebFailureAuditEvent: 
                    return createDummy ? new WebFailureAuditEvent() : new WebFailureAuditEvent(message, source, eventCode, eventDetailCode);

                case SystemEventType.WebViewStateFailureAuditEvent:
                    return createDummy ? new WebViewStateFailureAuditEvent() : new WebViewStateFailureAuditEvent(message, source, eventCode, eventDetailCode, (System.Web.UI.ViewStateException)exception); 

                default: 
                    Debug.Assert(false, "Unexpected event type = " + systemEventType); 
                    return null;
            } 
        }

        static string CreateWebEventResourceCacheKey(String key) {
            return CacheInternal.PrefixWebEventResource + key; 
        }
 
        internal static String FormatResourceStringWithCache(String key) { 
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;
            string s; 

            string cacheKey = CreateWebEventResourceCacheKey(key);

            s = (string) cacheInternal.Get(cacheKey); 
            if (s != null) {
                return s; 
            } 

            s = SR.Resources.GetString(key, CultureInfo.InstalledUICulture); 
            if (s != null) {
                cacheInternal.UtcInsert(cacheKey, s);
            }
 
            return s;
        } 
 
        internal static String FormatResourceStringWithCache(String key, String arg0) {
            string fmt = FormatResourceStringWithCache(key); 
            return(fmt != null) ? String.Format(fmt, arg0) : null;
        }

        internal static WebEventType WebEventTypeFromWebEvent(WebBaseEvent eventRaised) { 
            // Note:
            // eventRaised can belong to one of the following classes, or can inherit from one of them. 
            // In order to figure out precisely the WebEventType closest to the type of eventRaised, 
            // we will start our comparison from the leaf nodes in the class hierarchy and work our
            // way up. 

            // Webevent class hierarchy (with the info contained in each class):

            /* 

            - WebBaseEvent (basic) 
                - WebManagementEvent (+ WebProcessInformation) 
                    - WebHeartbeatEvent (+ WebProcessStatistics)
                    - WebApplicationLifetimeEvent 
                    - WebRequestEvent (+ WebRequestInformation)
                    - WebBaseErrorEvent (+ Exception)
                        - WebRequestErrorEvent (+ WebRequestInformation + WebThreadInformation)
                        - WebErrorEvent (+ WebRequestInformation + WebThreadInformation) 
                    - WebAuditEvent (+ WebRequestInformation)
                        - WebSuccessAuditEvent 
                            - WebAuthenticationSuccessAuditEvent (+ NameToAuthenticate) 
                        - WebFailureAuditEvent
                            - WebAuthenticationFailureAuditEvent (+ NameToAuthenticate) 
                            - WebViewStateFailureAuditEvent (+ ViewStateException)
            */

            // Hierarchy level 5 

            if (eventRaised is WebAuthenticationSuccessAuditEvent) { 
                return WebEventType.WEBEVENT_AUTHENTICATION_SUCCESS_AUDIT_EVENT; 
            }
 
            if (eventRaised is WebAuthenticationFailureAuditEvent) {
                return WebEventType.WEBEVENT_AUTHENTICATION_FAILURE_AUDIT_EVENT;
            }
 
            if (eventRaised is WebViewStateFailureAuditEvent) {
                return WebEventType.WEBEVENT_VIEWSTATE_FAILURE_AUDIT_EVENT; 
            } 

            // Hierarchy level 4 

            if (eventRaised is WebRequestErrorEvent) {
                return WebEventType.WEBEVENT_REQUEST_ERROR_EVENT;
            } 

            if (eventRaised is WebErrorEvent) { 
                return WebEventType.WEBEVENT_ERROR_EVENT; 
            }
 
            if (eventRaised is WebSuccessAuditEvent) {
                return WebEventType.WEBEVENT_SUCCESS_AUDIT_EVENT;
            }
 
            if (eventRaised is WebFailureAuditEvent) {
                return WebEventType.WEBEVENT_FAILURE_AUDIT_EVENT; 
            } 

            // Hierarchy level 3 

            if (eventRaised is WebHeartbeatEvent) {
                return WebEventType.WEBEVENT_HEARTBEAT_EVENT;
            } 

            if (eventRaised is WebApplicationLifetimeEvent) { 
                return WebEventType.WEBEVENT_APP_LIFETIME_EVENT; 
            }
 
            if (eventRaised is WebRequestEvent) {
                return WebEventType.WEBEVENT_REQUEST_EVENT;
            }
 
            if (eventRaised is WebBaseErrorEvent) {
                return WebEventType.WEBEVENT_BASE_ERROR_EVENT; 
            } 

            if (eventRaised is WebAuditEvent) { 
                return WebEventType.WEBEVENT_AUDIT_EVENT;
            }

            // Hierarchy level 2 

            if (eventRaised is WebManagementEvent) { 
                return WebEventType.WEBEVENT_MANAGEMENT_EVENT; 
            }
 
            // Hierarchy level 1

            return WebEventType.WEBEVENT_BASE_EVENT;
        } 

        static internal void RaisePropertyDeserializationWebErrorEvent(SettingsProperty property, object source, Exception exception) { 
            if (HttpContext.Current == null) { 
                return;
            } 

            WebBaseEvent.RaiseSystemEvent(
                SR.GetString(SR.Webevent_msg_Property_Deserialization,
                            property.Name, property.SerializeAs.ToString(), property.PropertyType.AssemblyQualifiedName ), 
                source,
                WebEventCodes.WebErrorPropertyDeserializationError, 
                WebEventCodes.UndefinedEventDetailCode, 
                exception);
        } 
    }


    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebEventFormatter { 
        int             _level; 
        StringBuilder   _sb;
        int             _tabSize; 

        void AddTab() {
            int level = _level;
 
            while (level > 0) {
                _sb.Append(' ', _tabSize); 
                level--; 
            }
        } 

        internal WebEventFormatter() {
            _level = 0;
            _sb = new StringBuilder(); 
            _tabSize = 4;
        } 
 
        public void AppendLine(string s) {
            AddTab(); 
            _sb.Append(s);
            _sb.Append('\n');
        }
 
        new public string ToString() {
            return _sb.ToString(); 
        } 

        public int IndentationLevel { 
            get { return _level; }
            set { _level = Math.Max(value, 0); }
        }
 
        public int TabSize {
            get { return _tabSize; } 
            set { _tabSize = Math.Max(value, 0); } 
        }
    } 

    // This class is a base class for all events that require application and process information.
    //
    // WebManagementEvent is the base class for all our webevent classes (except for WebBaseEvent) 
    // Please note that we allow customer to inherit from our webevent classes to make it easier to
    // create custom webevent that contains useful information. 
    // However, WebManagementEvent (and other child events) contains sensitive information (e.g. process id, process account name) 
    // that cannot be obtained unless in full-trust.
    // 
    // In non-fulltrust app, we still want code inside system.web.dll to create these webevents
    // even if there is user code on the stack (we either assert or call unmanaged code to get those info).
    // So to protect these full-trust information from non-fulltrust app, we InheritanceDemand FullTrust
    // if the customer wants to inherit from WebManagementEvent. 
    //
    // For details, see VSWhidbey 256684. 
    // 
    [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)]
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebManagementEvent : WebBaseEvent {
        static WebProcessInformation        s_processInfo = new WebProcessInformation();
 
        internal protected WebManagementEvent(string message, object eventSource, int eventCode)
            :base(message, eventSource, eventCode) { 
        } 

        internal protected WebManagementEvent(string message, object eventSource, int eventCode, int eventDetailCode) 
            :base(message, eventSource, eventCode, eventDetailCode) {
        }

        internal WebManagementEvent() { 
            // For creating dummy event.  See GetSystemDummyEvent()
        } 
 
        // properties
        public WebProcessInformation ProcessInformation { 
            get { return s_processInfo; }
        }

        internal override void GenerateFieldsForMarshal(List fields) { 
            base.GenerateFieldsForMarshal(fields);
            fields.Add(new WebEventFieldData("AccountName", ProcessInformation.AccountName, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("ProcessName", ProcessInformation.ProcessName, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("ProcessID", ProcessInformation.ProcessID.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Int));
        } 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) {
            base.FormatToString(formatter, includeAppInfo);
 
            formatter.AppendLine(String.Empty);
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_process_information)); 
 
            formatter.IndentationLevel += 1;
            ProcessInformation.FormatToString(formatter); 
            formatter.IndentationLevel -= 1;
        }

    } 

 
    // This event is raised at periodic intervals (default 30 seconds) and provides information 
    // relative to the state of the running appdomin.
 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebHeartbeatEvent : WebManagementEvent {
        static WebProcessStatistics    s_procStats = new WebProcessStatistics(); 

        internal protected WebHeartbeatEvent(string message, int eventCode) 
            :base(message, null, eventCode) 
        {
        } 

        internal WebHeartbeatEvent() {
            // For creating dummy event.  See GetSystemDummyEvent()
        } 

 
        public WebProcessStatistics ProcessStatistics {get {return s_procStats;}} 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) { 
            base.FormatToString(formatter, includeAppInfo);

            formatter.AppendLine(String.Empty);
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_process_statistics)); 

            formatter.IndentationLevel += 1; 
            s_procStats.FormatToString(formatter); 
            formatter.IndentationLevel -= 1;
        } 
    }


    // This event represents a notable event in the lifetime of an application (app domain) 
    // including startup and shutdown events.  When an app domain is terminated, the reason
    // will be expressed in the Message field (e.g. compilation threshold exceed, Shutdown 
    // called explicitly, etc.). 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebApplicationLifetimeEvent : WebManagementEvent {

        internal protected WebApplicationLifetimeEvent(string message, object eventSource, int eventCode) 
            :base(message, eventSource, eventCode)
        { 
        } 

 
        internal protected WebApplicationLifetimeEvent(string message, object eventSource, int eventCode, int eventDetailCode)
            :base(message, eventSource, eventCode, eventDetailCode)
        {
        } 

        internal WebApplicationLifetimeEvent() { 
            // For creating dummy event.  See GetSystemDummyEvent() 
        }
 
        static internal int DetailCodeFromShutdownReason(ApplicationShutdownReason reason) {
            switch (reason) {
            case ApplicationShutdownReason.HostingEnvironment:
                return WebEventCodes.ApplicationShutdownHostingEnvironment; 

            case ApplicationShutdownReason.ChangeInGlobalAsax: 
                return WebEventCodes.ApplicationShutdownChangeInGlobalAsax; 

            case ApplicationShutdownReason.ConfigurationChange: 
                return WebEventCodes.ApplicationShutdownConfigurationChange;

            case ApplicationShutdownReason.UnloadAppDomainCalled:
                return WebEventCodes.ApplicationShutdownUnloadAppDomainCalled; 

            case ApplicationShutdownReason.ChangeInSecurityPolicyFile: 
                return WebEventCodes.ApplicationShutdownChangeInSecurityPolicyFile; 

            case ApplicationShutdownReason.BinDirChangeOrDirectoryRename: 
                return WebEventCodes.ApplicationShutdownBinDirChangeOrDirectoryRename;

            case ApplicationShutdownReason.BrowsersDirChangeOrDirectoryRename:
                return WebEventCodes.ApplicationShutdownBrowsersDirChangeOrDirectoryRename; 

            case ApplicationShutdownReason.CodeDirChangeOrDirectoryRename: 
                return WebEventCodes.ApplicationShutdownCodeDirChangeOrDirectoryRename; 

            case ApplicationShutdownReason.ResourcesDirChangeOrDirectoryRename: 
                return WebEventCodes.ApplicationShutdownResourcesDirChangeOrDirectoryRename;

            case ApplicationShutdownReason.IdleTimeout:
                return WebEventCodes.ApplicationShutdownIdleTimeout; 

            case ApplicationShutdownReason.PhysicalApplicationPathChanged: 
                return WebEventCodes.ApplicationShutdownPhysicalApplicationPathChanged; 

            case ApplicationShutdownReason.HttpRuntimeClose: 
                return WebEventCodes.ApplicationShutdownHttpRuntimeClose;

            case ApplicationShutdownReason.InitializationError:
                return WebEventCodes.ApplicationShutdownInitializationError; 

            case ApplicationShutdownReason.MaxRecompilationsReached: 
                return WebEventCodes.ApplicationShutdownMaxRecompilationsReached; 

            case ApplicationShutdownReason.BuildManagerChange: 
                return WebEventCodes.ApplicationShutdownBuildManagerChange;

            default:
                return WebEventCodes.ApplicationShutdownUnknown; 
            }
        } 
 
        override internal protected void IncrementPerfCounters() {
            base.IncrementPerfCounters(); 
            PerfCounters.IncrementCounter(AppPerfCounter.EVENTS_APP);
        }
    }
 
    // This class serves as a base for non-error events that provide
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebRequestEvent : WebManagementEvent {
        WebRequestInformation   _requestInfo; 

        override internal void PreProcessEventInit() {
            base.PreProcessEventInit();
            InitRequestInformation(); 
        }
 
        internal protected WebRequestEvent(string message, object eventSource, int eventCode) 
        :base(message, eventSource, eventCode)
        { 
        }

        internal protected WebRequestEvent(string message, object eventSource, int eventCode, int eventDetailCode)
            :base(message, eventSource, eventCode, eventDetailCode) 
        {
        } 
 
        internal WebRequestEvent() {
            // For creating dummy event.  See GetSystemDummyEvent() 
        }

        void InitRequestInformation() {
            if (_requestInfo == null) { 
                _requestInfo = new WebRequestInformation();
            } 
        } 

        public WebRequestInformation RequestInformation { 
            get {
                InitRequestInformation();
                return _requestInfo;
            } 
        }
 
        internal override void GenerateFieldsForMarshal(List fields) { 
            base.GenerateFieldsForMarshal(fields);
            fields.Add(new WebEventFieldData("RequestUrl", RequestInformation.RequestUrl, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("RequestPath", RequestInformation.RequestPath, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserHostAddress", RequestInformation.UserHostAddress, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserName", RequestInformation.Principal.Identity.Name, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserAuthenticated", RequestInformation.Principal.Identity.IsAuthenticated.ToString(), WebEventFieldType.Bool)); 
            fields.Add(new WebEventFieldData("UserAuthenticationType", RequestInformation.Principal.Identity.AuthenticationType, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("RequestThreadAccountName", RequestInformation.ThreadAccountName, WebEventFieldType.String)); 
        } 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) { 
            base.FormatToString(formatter, includeAppInfo);

            formatter.AppendLine(String.Empty);
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_information)); 

            formatter.IndentationLevel += 1; 
            RequestInformation.FormatToString(formatter); 
            formatter.IndentationLevel -= 1;
        } 

        override internal protected void IncrementPerfCounters() {
            base.IncrementPerfCounters();
            PerfCounters.IncrementCounter(AppPerfCounter.EVENTS_WEB_REQ); 
        }
    } 
 
    // This is the base class for all error events.
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebBaseErrorEvent : WebManagementEvent {
        Exception               _exception;
 
        void Init(Exception e) {
            _exception = e; 
        } 

        internal protected WebBaseErrorEvent(string message, object eventSource, int eventCode, Exception e) 
            :base(message, eventSource, eventCode)
        {
            Init(e);
        } 

        internal protected WebBaseErrorEvent(string message, object eventSource, int eventCode, int eventDetailCode, Exception e) 
            :base(message, eventSource, eventCode, eventDetailCode) 
        {
            Init(e); 
        }

        internal WebBaseErrorEvent() {
            // For creating dummy event.  See GetSystemDummyEvent() 
        }
 
        public Exception ErrorException { 
            get { return _exception; }
        } 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) {
            base.FormatToString(formatter, includeAppInfo);
 
            if (_exception == null) {
                return; 
            } 

            Exception   ex = _exception; 

            // Please note we arbitrary pick a level limit per bug VSWhidbey 143859
            for (int level = 0;
                  ex != null && level <= 2; 
                  ex = ex.InnerException, level++)  {
 
                formatter.AppendLine(String.Empty); 

                if (level == 0) { 
                    formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_exception_information));
                }
                else {
                    formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_inner_exception_information, level.ToString(CultureInfo.InstalledUICulture))); 
                }
 
                formatter.IndentationLevel += 1; 
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_exception_type, ex.GetType().ToString()));
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_exception_message, ex.Message)); 
                formatter.IndentationLevel -= 1;
            }
        }
 
        internal override void GenerateFieldsForMarshal(List fields) {
            base.GenerateFieldsForMarshal(fields); 
            fields.Add(new WebEventFieldData("ExceptionType", ErrorException.GetType().ToString(), WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("ExceptionMessage", ErrorException.Message, WebEventFieldType.String));
        } 

        override internal protected void IncrementPerfCounters() {
            base.IncrementPerfCounters();
            PerfCounters.IncrementCounter(AppPerfCounter.EVENTS_ERROR); 
            PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.GLOBAL_EVENTS_ERROR);
        } 
    } 

    // This class contains information about systemic errors, e.g. things related to 
    // configuration or application code (parser errors, compilation errors).

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebErrorEvent : WebBaseErrorEvent {
        WebRequestInformation   _requestInfo; 
        WebThreadInformation    _threadInfo; 

        void Init(Exception e) { 
        }

        override internal void PreProcessEventInit() {
            base.PreProcessEventInit(); 
            InitRequestInformation();
            InitThreadInformation(); 
        } 

        internal protected WebErrorEvent(string message, object eventSource, int eventCode, Exception exception) 
            :base(message, eventSource, eventCode, exception)
        {
            Init(exception);
        } 

        internal protected WebErrorEvent(string message, object eventSource, int eventCode, int eventDetailCode, Exception exception) 
            :base(message, eventSource, eventCode, eventDetailCode, exception) 
        {
            Init(exception); 
        }

        internal WebErrorEvent() {
            // For creating dummy event.  See GetSystemDummyEvent() 
        }
 
        void InitRequestInformation() { 
            if (_requestInfo == null) {
                _requestInfo = new WebRequestInformation(); 
            }
        }

        public WebRequestInformation RequestInformation { 
            get {
                InitRequestInformation(); 
                return _requestInfo; 
            }
        } 

        void InitThreadInformation() {
            if (_threadInfo == null) {
                _threadInfo = new WebThreadInformation(base.ErrorException); 
            }
        } 
 
        public WebThreadInformation ThreadInformation {
            get { 
                InitThreadInformation();
                return _threadInfo;
            }
        } 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) { 
            base.FormatToString(formatter, includeAppInfo); 

            formatter.AppendLine(String.Empty); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_information));

            formatter.IndentationLevel += 1;
            RequestInformation.FormatToString(formatter); 
            formatter.IndentationLevel -= 1;
 
            formatter.AppendLine(String.Empty); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_thread_information));
 
            formatter.IndentationLevel += 1;
            ThreadInformation.FormatToString(formatter);
            formatter.IndentationLevel -= 1;
        } 

        internal override void GenerateFieldsForMarshal(List fields) { 
            base.GenerateFieldsForMarshal(fields); 
            fields.Add(new WebEventFieldData("RequestUrl", RequestInformation.RequestUrl, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("RequestPath", RequestInformation.RequestPath, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("UserHostAddress", RequestInformation.UserHostAddress, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserName", RequestInformation.Principal.Identity.Name, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserAuthenticated", RequestInformation.Principal.Identity.IsAuthenticated.ToString(), WebEventFieldType.Bool));
            fields.Add(new WebEventFieldData("UserAuthenticationType", RequestInformation.Principal.Identity.AuthenticationType, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("RequestThreadAccountName", RequestInformation.ThreadAccountName, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("ThreadID", ThreadInformation.ThreadID.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Int)); 
            fields.Add(new WebEventFieldData("ThreadAccountName", ThreadInformation.ThreadAccountName, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("StackTrace", ThreadInformation.StackTrace, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("IsImpersonating", ThreadInformation.IsImpersonating.ToString(), WebEventFieldType.Bool)); 
        }

        override internal protected void IncrementPerfCounters() {
            base.IncrementPerfCounters(); 
            PerfCounters.IncrementCounter(AppPerfCounter.EVENTS_HTTP_INFRA_ERROR);
            PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.GLOBAL_EVENTS_HTTP_INFRA_ERROR); 
        } 
    }
 
    // This class provides information about errors that occur while servicing a request.
    // This include unhandled exceptions, viewstate errors, input validation errors, etc.
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebRequestErrorEvent : WebBaseErrorEvent {
        WebRequestInformation   _requestInfo; 
        WebThreadInformation    _threadInfo; 

        void Init(Exception e) { 
        }

        override internal void PreProcessEventInit() {
            base.PreProcessEventInit(); 
            InitRequestInformation();
            InitThreadInformation(); 
        } 

        internal protected WebRequestErrorEvent(string message, object eventSource, int eventCode, Exception exception) 
            :base(message, eventSource, eventCode, exception)
        {
            Init(exception);
        } 

        internal protected WebRequestErrorEvent(string message, object eventSource, int eventCode, int eventDetailCode, Exception exception) 
            :base(message, eventSource, eventCode, eventDetailCode, exception) 
        {
            Init(exception); 
        }

        internal WebRequestErrorEvent() {
            // For creating dummy event.  See GetSystemDummyEvent() 
        }
 
        // properties 

        void InitRequestInformation() { 
            if (_requestInfo == null) {
                _requestInfo = new WebRequestInformation();
            }
        } 

        public WebRequestInformation RequestInformation { 
            get { 
                InitRequestInformation();
                return _requestInfo; 
            }
        }

        void InitThreadInformation() { 
            if (_threadInfo == null) {
                _threadInfo = new WebThreadInformation(base.ErrorException); 
            } 
        }
 
        public WebThreadInformation ThreadInformation {
            get {
                InitThreadInformation();
                return _threadInfo; 
            }
        } 
 
        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) {
            base.FormatToString(formatter, includeAppInfo); 

            formatter.AppendLine(String.Empty);
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_information));
 
            formatter.IndentationLevel += 1;
            RequestInformation.FormatToString(formatter); 
            formatter.IndentationLevel -= 1; 

            formatter.AppendLine(String.Empty); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_thread_information));

            formatter.IndentationLevel += 1;
            ThreadInformation.FormatToString(formatter); 
            formatter.IndentationLevel -= 1;
        } 
 
        internal override void GenerateFieldsForMarshal(List fields) {
            base.GenerateFieldsForMarshal(fields); 
            fields.Add(new WebEventFieldData("RequestUrl", RequestInformation.RequestUrl, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("RequestPath", RequestInformation.RequestPath, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserHostAddress", RequestInformation.UserHostAddress, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserName", RequestInformation.Principal.Identity.Name, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("UserAuthenticated", RequestInformation.Principal.Identity.IsAuthenticated.ToString(), WebEventFieldType.Bool));
            fields.Add(new WebEventFieldData("UserAuthenticationType", RequestInformation.Principal.Identity.AuthenticationType, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("RequestThreadAccountName", RequestInformation.ThreadAccountName, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("ThreadID", ThreadInformation.ThreadID.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Int));
            fields.Add(new WebEventFieldData("ThreadAccountName", ThreadInformation.ThreadAccountName, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("StackTrace", ThreadInformation.StackTrace, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("IsImpersonating", ThreadInformation.IsImpersonating.ToString(), WebEventFieldType.Bool));
        }
 
        override internal protected void IncrementPerfCounters() {
            base.IncrementPerfCounters(); 
            PerfCounters.IncrementCounter(AppPerfCounter.EVENTS_HTTP_REQ_ERROR); 
            PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.GLOBAL_EVENTS_HTTP_REQ_ERROR);
        } 
    }


    // The base class for all audit events. 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebAuditEvent : WebManagementEvent {
        WebRequestInformation   _requestInfo; 

        override internal void PreProcessEventInit() {
            base.PreProcessEventInit();
            InitRequestInformation(); 
        }
 
        internal protected WebAuditEvent(string message, object eventSource, int eventCode) 
            :base(message, eventSource, eventCode)
        { 
        }

        internal protected WebAuditEvent(string message, object eventSource, int eventCode, int eventDetailCode)
            :base(message, eventSource, eventCode, eventDetailCode) 
        {
        } 
 
        internal WebAuditEvent() {
            // For creating dummy event.  See GetSystemDummyEvent() 
        }

        void InitRequestInformation() {
            if (_requestInfo == null) { 
                _requestInfo = new WebRequestInformation();
            } 
        } 

        public WebRequestInformation RequestInformation { 
            get {
                InitRequestInformation();
                return _requestInfo;
            } 
        }
 
        internal override void GenerateFieldsForMarshal(List fields) { 
            base.GenerateFieldsForMarshal(fields);
            fields.Add(new WebEventFieldData("RequestUrl", RequestInformation.RequestUrl, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("RequestPath", RequestInformation.RequestPath, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserHostAddress", RequestInformation.UserHostAddress, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserName", RequestInformation.Principal.Identity.Name, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserAuthenticated", RequestInformation.Principal.Identity.IsAuthenticated.ToString(), WebEventFieldType.Bool)); 
            fields.Add(new WebEventFieldData("UserAuthenticationType", RequestInformation.Principal.Identity.AuthenticationType, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("RequestThreadAccountName", RequestInformation.ThreadAccountName, WebEventFieldType.String)); 
        } 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) { 
            base.FormatToString(formatter, includeAppInfo);

            formatter.AppendLine(String.Empty);
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_information)); 

            formatter.IndentationLevel += 1; 
            RequestInformation.FormatToString(formatter); 
            formatter.IndentationLevel -= 1;
        } 
    }


    // This class provides information about all failure audits.  In most cases, 
    // applications will only want to enable failure audits.
 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebFailureAuditEvent : WebAuditEvent { 
        internal protected WebFailureAuditEvent(string message, object eventSource, int eventCode)
            :base(message, eventSource, eventCode)
        {
        } 

        internal protected WebFailureAuditEvent(string message, object eventSource, int eventCode, int eventDetailCode) 
            :base(message, eventSource, eventCode, eventDetailCode) 
        {
        } 

        internal WebFailureAuditEvent() {
            // For creating dummy event.  See GetSystemDummyEvent()
        } 

        override internal protected void IncrementPerfCounters() { 
            base.IncrementPerfCounters(); 
            PerfCounters.IncrementCounter(AppPerfCounter.AUDIT_FAIL);
            PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.GLOBAL_AUDIT_FAIL); 
        }
    }

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebAuthenticationFailureAuditEvent : WebFailureAuditEvent { 
 
        string  _nameToAuthenticate;
 
        void Init(string name) {
            _nameToAuthenticate = name;
        }
 
        internal protected WebAuthenticationFailureAuditEvent(string message, object eventSource, int eventCode, string nameToAuthenticate)
            :base(message, eventSource, eventCode) 
        { 
            Init(nameToAuthenticate);
        } 


        internal protected WebAuthenticationFailureAuditEvent(string message, object eventSource, int eventCode, int eventDetailCode, string nameToAuthenticate)
            :base(message, eventSource, eventCode, eventDetailCode) 
        {
            Init(nameToAuthenticate); 
        } 

        internal WebAuthenticationFailureAuditEvent() { 
            // For creating dummy event.  See GetSystemDummyEvent()
        }

        public string NameToAuthenticate { 
            get { return _nameToAuthenticate; }
        } 
 
        internal override void GenerateFieldsForMarshal(List fields) {
            base.GenerateFieldsForMarshal(fields); 
            fields.Add(new WebEventFieldData("NameToAuthenticate", NameToAuthenticate, WebEventFieldType.String));
        }

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) { 
            base.FormatToString(formatter, includeAppInfo);
 
            formatter.AppendLine(String.Empty); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_name_to_authenticate, _nameToAuthenticate));
 
        }
    }

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebViewStateFailureAuditEvent : WebFailureAuditEvent { 
 
        ViewStateException  _viewStateException;
 
        internal protected WebViewStateFailureAuditEvent(string message, object eventSource, int eventCode, ViewStateException viewStateException)
            :base(message, eventSource, eventCode)
        {
            _viewStateException = viewStateException; 
        }
 
 
        internal protected WebViewStateFailureAuditEvent(string message, object eventSource, int eventCode, int eventDetailCode, ViewStateException viewStateException)
            :base(message, eventSource, eventCode, eventDetailCode) 
        {
            _viewStateException = viewStateException;
        }
 
        internal WebViewStateFailureAuditEvent() {
            // For creating dummy event.  See GetSystemDummyEvent() 
        } 

        public ViewStateException ViewStateException { 
            get { return _viewStateException; }
        }

        internal override void GenerateFieldsForMarshal(List fields) { 
            base.GenerateFieldsForMarshal(fields);
            fields.Add(new WebEventFieldData("ViewStateExceptionMessage", ViewStateException.Message, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("RemoteAddress", ViewStateException.RemoteAddress, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("RemotePort", ViewStateException.RemotePort, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserAgent", ViewStateException.UserAgent, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("PersistedState", ViewStateException.PersistedState, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("Path", ViewStateException.Path, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("Referer", ViewStateException.Referer, WebEventFieldType.String));
        } 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) { 
            base.FormatToString(formatter, includeAppInfo); 

            formatter.AppendLine(String.Empty); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_ViewStateException_information));
            formatter.IndentationLevel += 1;
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_exception_message, _viewStateException.Message));
 
            formatter.IndentationLevel -= 1;
        } 
 
    }
 

    // This class provides information about all success audits.  In most cases,
    // applications will only want to enable failure audits.
 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebSuccessAuditEvent : WebAuditEvent { 
        internal protected WebSuccessAuditEvent(string message, object eventSource, int eventCode)
            :base(message, eventSource, eventCode) 
        {
        }

        internal protected WebSuccessAuditEvent(string message, object eventSource, int eventCode, int eventDetailCode) 
            :base(message, eventSource, eventCode, eventDetailCode)
        { 
        } 

        internal WebSuccessAuditEvent() { 
            // For creating dummy event.  See GetSystemDummyEvent()
        }

        override internal protected void IncrementPerfCounters() { 
            base.IncrementPerfCounters();
            PerfCounters.IncrementCounter(AppPerfCounter.AUDIT_SUCCESS); 
            PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.GLOBAL_AUDIT_SUCCESS); 
        }
    } 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebAuthenticationSuccessAuditEvent : WebSuccessAuditEvent { 

        string  _nameToAuthenticate; 
 
        void Init(string name) {
            _nameToAuthenticate = name; 
        }

        internal protected WebAuthenticationSuccessAuditEvent(string message, object eventSource, int eventCode, string nameToAuthenticate)
            :base(message, eventSource, eventCode) 
        {
            Init(nameToAuthenticate); 
        } 

        internal protected WebAuthenticationSuccessAuditEvent(string message, object eventSource, int eventCode, int eventDetailCode, string nameToAuthenticate) 
            :base(message, eventSource, eventCode, eventDetailCode)
        {
            Init(nameToAuthenticate);
        } 

        internal WebAuthenticationSuccessAuditEvent() { 
            // For creating dummy event.  See GetSystemDummyEvent() 
        }
 
        public string NameToAuthenticate {
            get { return _nameToAuthenticate; }
        }
 
        internal override void GenerateFieldsForMarshal(List fields) {
            base.GenerateFieldsForMarshal(fields); 
            fields.Add(new WebEventFieldData("NameToAuthenticate", NameToAuthenticate, WebEventFieldType.String)); 
        }
 
        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) {
            base.FormatToString(formatter, includeAppInfo);

            formatter.AppendLine(String.Empty); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_name_to_authenticate, _nameToAuthenticate));
        } 
    } 

 
    ////////////////
    // Information
    ////////////////
 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public sealed class WebProcessInformation { 
        // The information is per worker process instance.
 
        int     _processId;
        string  _processName;
        string  _accountName;
 
        internal WebProcessInformation() {
            // Can't use Process.ProcessName because it requires the running 
            // account to be part of the Performance Monitor Users group. 
            StringBuilder buf = new StringBuilder(256);
            if (UnsafeNativeMethods.GetModuleFileName(IntPtr.Zero, buf, 256) == 0) { 
                _processName = String.Empty;
            }
            else {
                int lastIndex; 

                _processName = buf.ToString(); 
                lastIndex = _processName.LastIndexOf('\\'); 
                if (lastIndex != -1) {
                    _processName = _processName.Substring(lastIndex + 1); 
                }
            }

            _processId = SafeNativeMethods.GetCurrentProcessId() ; 
            _accountName = HttpRuntime.WpUserId;
        } 
 
        public int ProcessID { get { return _processId; } }
 
        public string ProcessName { get { return _processName; } }

        public string AccountName { get { return (_accountName != null ? _accountName : String.Empty); } }
 
        public void FormatToString(WebEventFormatter formatter) {
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_process_id, ProcessID.ToString(CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_process_name, ProcessName)); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_account_name, AccountName));
        } 
    }


    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public sealed class WebApplicationInformation {
        // The information is per appdomain. 
 
        string  _appDomain;
        string  _trustLevel; 
        string  _appUrl;
        string  _appPath;
        string  _machineName;
 
        internal WebApplicationInformation() {
            _appDomain = Thread.GetDomain().FriendlyName; 
            _trustLevel = HttpRuntime.TrustLevel; 
            _appUrl = HttpRuntime.AppDomainAppVirtualPath;
 
            try {
                // We will get an exception if it's a non-ASP.NET app.
                _appPath = HttpRuntime.AppDomainAppPath;
            } 
            catch {
                _appPath = null; 
            } 
#if FEATURE_PAL // FEATURE_PAL does not fully implement Environment.MachineName
            _machineName = "dummymachinename"; 
#else // FEATURE_PAL
            _machineName = GetMachineNameWithAssert();
#endif // FEATURE_PAL
        } 

        public string ApplicationDomain { get { return _appDomain; } } 
 
        public string TrustLevel { get { return _trustLevel; } }
 
        public string ApplicationVirtualPath { get { return _appUrl; } }

        public string ApplicationPath { get { return _appPath; } }
 
        public string MachineName { get { return _machineName; } }
 
        public void FormatToString(WebEventFormatter formatter) { 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_application_domain, ApplicationDomain));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_trust_level, TrustLevel)); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_application_virtual_path, ApplicationVirtualPath));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_application_path, ApplicationPath));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_machine_name, MachineName));
        } 

        [PermissionSet(SecurityAction.Assert, Unrestricted = true)] 
        private string GetMachineNameWithAssert() { 
            return Environment.MachineName;
        } 

        public override string ToString() {
            WebEventFormatter formatter = new WebEventFormatter();
 
            FormatToString(formatter);
            return formatter.ToString(); 
        } 
    }
 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public sealed class WebRequestInformation {
 
        string      _requestUrl;
        string      _requestPath; 
        IPrincipal  _iprincipal; 
        string      _userHostAddress = null;
        string      _accountName; 

        internal    WebRequestInformation() {
            // Need to Assert() in order to get request information regardless of trust level. See VSWhidbey 416733
            InternalSecurityPermissions.ControlPrincipal.Assert(); 

            HttpContext context = HttpContext.Current; 
            HttpRequest request = null; 

            if (context != null) 
            {
                bool hideRequestResponseOriginal = context.HideRequestResponse;
                context.HideRequestResponse = false;
                request = context.Request; 
                context.HideRequestResponse = hideRequestResponseOriginal;
 
                _iprincipal = context.User; 
            } else {
                _iprincipal = null; 
            }

            if (request == null) {
                _requestUrl = String.Empty; 
                _requestPath = String.Empty;
                _userHostAddress = String.Empty; 
            } 
            else {
                _requestUrl = request.UrlInternal; 
                _requestPath = request.Path;
                _userHostAddress = request.UserHostAddress;
            }
 
            _accountName = WindowsIdentity.GetCurrent().Name;
        } 
 
        // The information is per request.
 
        public string RequestUrl {get {return _requestUrl;}}

        public string RequestPath {get {return _requestPath;}}
 
        public IPrincipal Principal {get {return _iprincipal;}}
 
        public string UserHostAddress { get { return _userHostAddress;} } 

        public string ThreadAccountName {get {return _accountName;}} 

        public void FormatToString(WebEventFormatter formatter) {
            string      user;
            string      authType; 
            bool        authed;
 
            if (Principal == null) { 
                user = String.Empty;
                authType = String.Empty; 
                authed = false;
            }
            else {
                IIdentity    id = Principal.Identity; 

                user = id.Name; 
                authed = id.IsAuthenticated; 
                authType = id.AuthenticationType;
            } 

            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_url, RequestUrl));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_path, RequestPath));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_user_host_address, UserHostAddress)); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_user, user));
 
            if (authed) { 
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_is_authenticated));
            } 
            else {
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_is_not_authenticated));
            }
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_authentication_type, authType)); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_thread_account_name, ThreadAccountName));
 
        } 
    }
 

    // Note that even all the information contained in WebProcessStatistics is obtained from static variables,
    // but we still don't want this class to be static.
    // 
    // Currently, WebProcessStatistics can be obtained only thru WebHeartbeatEvent, which in turn can be
    // created only by Full-trust app thru class inheritance. (System.Web.dll will also internally create it 
    // and the object will be available to our provider.)  Thus, WebProcessStatistics is available only 
    // to Full-trust app or provider.
    // 
    // But if we make WebProcessStatistics static, then all its public methods have to be static, and
    // they'll be fully available to all users.  No good.
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebProcessStatistics {
        static DateTime     s_startTime = DateTime.MinValue; 
        static DateTime     s_lastUpdated = DateTime.MinValue; 
        static int          s_threadCount;
        static long         s_workingSet; 
        static long         s_peakWorkingSet;
        static long         s_managedHeapSize;
        static int          s_appdomainCount;
        static int          s_requestsExecuting; 
        static int          s_requestsQueued;
        static int          s_requestsRejected; 
        static bool         s_getCurrentProcFailed = false; 
        static object       s_lockObject = new object();
 
        static TimeSpan      TS_ONE_SECOND = new TimeSpan(0, 0, 1);

        static WebProcessStatistics() {
            try { 
#if !FEATURE_PAL // FEATURE_PAL does not support this.  Make into a noop.
                s_startTime = Process.GetCurrentProcess().StartTime; 
#endif // !FEATURE_PAL 
            }
            catch { 
                s_getCurrentProcFailed = true;
            }
        }
 
        void Update() {
            DateTime    now = DateTime.Now; 
 
            if (now - s_lastUpdated < TS_ONE_SECOND) {
                return; 
            }

            lock (s_lockObject) {
                if (now - s_lastUpdated < TS_ONE_SECOND) { 
                    return;
                } 
 
                if (!s_getCurrentProcFailed) {
                    Process process = Process.GetCurrentProcess(); 
#if !FEATURE_PAL // FEATURE_PAL does not support these Process properties

                    s_threadCount = process.Threads.Count;
                    s_workingSet = (long)process.WorkingSet64; 
                    s_peakWorkingSet = (long)process.PeakWorkingSet64;
#else 
                    throw new NotImplementedException ("ROTORTODO"); 
#endif
                } 

                s_managedHeapSize = GC.GetTotalMemory(false);

                s_appdomainCount = HostingEnvironment.AppDomainsCount; 

                s_requestsExecuting = PerfCounters.GetGlobalCounter(GlobalPerfCounter.REQUESTS_CURRENT); 
                s_requestsQueued = PerfCounters.GetGlobalCounter(GlobalPerfCounter.REQUESTS_QUEUED); 
                s_requestsRejected = PerfCounters.GetGlobalCounter(GlobalPerfCounter.REQUESTS_REJECTED);
 
                s_lastUpdated = now;
            }
        }
 

        public DateTime ProcessStartTime {get {Update(); return s_startTime;}} 
 
        public int ThreadCount {get {Update(); return s_threadCount;}}
 
        public long WorkingSet {get {Update(); return s_workingSet;}}

        public long PeakWorkingSet {get {Update(); return s_peakWorkingSet;}}
 
        public long ManagedHeapSize {get {Update(); return s_managedHeapSize;}}
 
        public int AppDomainCount {get {Update(); return s_appdomainCount;}} 

        public int RequestsExecuting {get {Update(); return s_requestsExecuting;}} 

        public int RequestsQueued {get {Update(); return s_requestsQueued;}}

        public int RequestsRejected {get {Update(); return s_requestsRejected;}} 

 
        virtual public void FormatToString(WebEventFormatter formatter) { 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_process_start_time, ProcessStartTime.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_thread_count, ThreadCount.ToString(CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_working_set, WorkingSet.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_peak_working_set, PeakWorkingSet.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_managed_heap_size, ManagedHeapSize.ToString(CultureInfo.InstalledUICulture)));
 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_application_domain_count, AppDomainCount.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_requests_executing, RequestsExecuting.ToString(CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_queued, RequestsQueued.ToString(CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_rejected, RequestsRejected.ToString(CultureInfo.InstalledUICulture)));
        } 
    }


    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public sealed class WebThreadInformation {
        int     _threadId; 
        string  _accountName; 
        string  _stackTrace;
        bool    _isImpersonating; 
        internal const string IsImpersonatingKey = "ASPIMPERSONATING";

        internal WebThreadInformation(Exception exception) {
            _threadId = Thread.CurrentThread.ManagedThreadId; 
            _accountName = WindowsIdentity.GetCurrent().Name;
 
            if (exception != null) { 
                _stackTrace = new StackTrace(exception, true).ToString();
            } 
            else {
                _stackTrace = String.Empty;
            }
 
            _isImpersonating = exception.Data.Contains(IsImpersonatingKey);
        } 
 

        public int ThreadID {get {return _threadId;}} 

        public string ThreadAccountName {get {return _accountName;}}

        public string StackTrace {get {return _stackTrace;}} 

        public bool IsImpersonating {get {return _isImpersonating;}} 
 

        public void FormatToString(WebEventFormatter formatter) { 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_thread_id, ThreadID.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_thread_account_name, ThreadAccountName));

            if (IsImpersonating) { 
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_is_impersonating));
            } 
            else { 
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_is_not_impersonating));
            } 

            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_stack_trace, StackTrace));
        }
    } 

    // Class that represents the firing record (how many times, last firing time, etc) 
    // for each rule that inherits from WebBaseEvent. 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public sealed class RuleFiringRecord {
        internal DateTime   _lastFired;
        internal int        _timesRaised;
        internal int        _updatingLastFired; 

        static TimeSpan     TS_ONE_SECOND = new TimeSpan(0, 0, 1); 
 
        public DateTime LastFired { get { return _lastFired; } }
 

        public int TimesRaised { get { return _timesRaised; } }

        // Point to the ruleInfo that is used by this class 
        internal HealthMonitoringSectionHelper.RuleInfo    _ruleInfo;
 
        internal RuleFiringRecord(HealthMonitoringSectionHelper.RuleInfo ruleInfo) { 

            Debug.Assert(ruleInfo != null, "ruleInfo != null"); 

            _ruleInfo = ruleInfo;

            _lastFired = DateTime.MinValue; 
            _timesRaised = 0;
            _updatingLastFired = 0; 
        } 

        void UpdateLastFired(DateTime now, bool alreadyLocked) { 
            TimeSpan    tsDiff = now - _lastFired;

            if (tsDiff < TS_ONE_SECOND) {
                // If _lastFired was updated within one second, don't bother. 
                return;
            } 
 
            if (!alreadyLocked) {
                // If several threads are firing at the same time, only one thread will 
                // update record._lastFired.
                if (Interlocked.CompareExchange(ref _updatingLastFired, 1, 0) == 0) {
                    try {
                        _lastFired = now; 
                    }
                    finally { 
                        Interlocked.Exchange(ref _updatingLastFired, 0); 
                    }
                } 
            }
            else {
                _lastFired = now;
            } 
        }
 
        // Note: this method is thread safe 
        internal bool CheckAndUpdate(WebBaseEvent eventRaised) {
            DateTime    now = DateTime.Now; 
            int         timesRaised;
            HealthMonitoringManager manager = HealthMonitoringManager.Manager();

            timesRaised = Interlocked.Increment(ref _timesRaised); 

            if (manager == null) { 
                // Won't fire because we cannot configure healthmonitor 
                Debug.Trace("RuleFiringRecord", "Can't configure healthmonitor");
                return false; 
            }

            // Call custom evaluator first
            if (_ruleInfo._customEvaluatorType != null) { 

                IWebEventCustomEvaluator    icustom = (IWebEventCustomEvaluator) 
                        manager._sectionHelper._customEvaluatorInstances[_ruleInfo._customEvaluatorType]; 

#if (!DBG) 
                try {
#endif
                    // The event may need to do pre-ProcessEvent initialization
                    eventRaised.PreProcessEventInit(); 

                    if (!icustom.CanFire(eventRaised, this)) { 
                        Debug.Trace("RuleFiringRecord", "Custom evaluator returns false."); 
                        return false;
                    } 
#if (!DBG)
                }
                catch {
                    Debug.Trace("RuleFiringRecord", "Hit an exception when calling Custom evaluator"); 
                    // Return if we hit an error
                    return false; 
                } 
#endif
            } 

            if (timesRaised < _ruleInfo._minInstances) {
                Debug.Trace("RuleFiringRecord",
                        "MinInterval not met; timesRaised=" + timesRaised + 
                        "; _minInstances=" + _ruleInfo._minInstances);
                return false; 
            } 

            if (timesRaised > _ruleInfo._maxLimit) { 
                Debug.Trace("RuleFiringRecord",
                        "MaxLimit exceeded; timesRaised=" + timesRaised +
                        "; _maxLimit=" + _ruleInfo._maxLimit);
                return false; 
            }
 
            // Last step: Check MinInterval and update _lastFired 

            if (_ruleInfo._minInterval == TimeSpan.Zero) { 
                UpdateLastFired(now, false);
                return true;
            }
 
            if ((now - _lastFired) <= _ruleInfo._minInterval) {
                Debug.Trace("RuleFiringRecord", 
                        "MinInterval not met; now=" + now + 
                        "; _lastFired=" + _lastFired +
                        "; _ruleInfo._minInterval=" + _ruleInfo._minInterval); 
                return false;
            }

            // The lock is to prevent multiple threads from passing the 
            // same test simultaneously.
            lock (this) { 
                if ((now - _lastFired) <= _ruleInfo._minInterval) { 
                    Debug.Trace("RuleFiringRecord",
                            "MinInterval not met; now=" + now + 
                            "; _lastFired=" + _lastFired +
                            "; _ruleInfo._tsMinInterval=" + _ruleInfo._minInterval);
                    return false;
                } 

                UpdateLastFired(now, true); 
                return true; 
            }
        } 

    }

    internal class HealthMonitoringManager { 
        internal HealthMonitoringSectionHelper          _sectionHelper;
        internal bool           _enabled = false; 
 
        static Timer            s_heartbeatTimer = null;
        static HealthMonitoringManager s_manager = null; 
        static bool             s_inited = false;
        static bool             s_initing = false;
        static object           s_lockObject = new object();
 
        // If this method returns null, it means we failed during configuration.
        internal static HealthMonitoringManager Manager() { 
 
            if (s_initing) {
                Debug.Assert(!s_inited); 
                // If this is true, that means we are calling WebEventBase.Raise while
                // we are initializing.  That means Init() has caused a config exception.
                return null;
            } 

            if (s_inited) { 
                return s_manager; 
            }
 
            lock (s_lockObject) {
                if (s_inited) {
                    return s_manager;
                } 

                try { 
                    Debug.Assert(s_manager == null); 
                    s_initing = true;
                    s_manager = new HealthMonitoringManager();; 
                }
                finally {
                    s_initing = false;
                    s_inited = true; 
                }
            } 
 
            return s_manager;
        } 

        internal static bool Enabled {
            get {
                HealthMonitoringManager manager = HealthMonitoringManager.Manager(); 
                if (manager == null) {
                    return false; 
                } 

                return manager._enabled; 
            }
        }

        internal static void StartHealthMonitoringHeartbeat() { 
            HealthMonitoringManager manager = Manager();
            if (manager == null) { 
                Debug.Trace( 
                    "HealthMonitoringManager", "Can't fire heartbeat because we cannot configure HealthMon");
                return; 
            }

            if (!manager._enabled) {
                Debug.Trace( 
                    "WebEventRaiseDetails", "Can't fire heartbeat because we are disabled");
                return; 
            } 

            manager.StartHeartbeatTimer(); 
        }

        private HealthMonitoringManager() {
            _sectionHelper = HealthMonitoringSectionHelper.GetHelper(); 

            _enabled = _sectionHelper.Enabled; 
 
            if (!_enabled) {
                return; 
            }
        }

        internal static void Shutdown() { 
            WebEventManager.Shutdown();
            Dispose(); 
        } 

        internal static void Dispose() { 
            // Make sure this function won't throw
            try {
                if (s_heartbeatTimer != null) {
                    s_heartbeatTimer.Dispose(); 
                    s_heartbeatTimer = null;
                } 
            } 
            catch {
            } 
        }

        internal void HeartbeatCallback(object state) {
            Debug.Assert(HealthMonitoringManager.Enabled); 
            WebBaseEvent.RaiseSystemEvent(null, WebEventCodes.ApplicationHeartbeat);
        } 
 
        internal void StartHeartbeatTimer() {
            TimeSpan interval = _sectionHelper.HealthMonitoringSection.HeartbeatInterval; 

            if (interval == TimeSpan.Zero) {
                return;
            } 

#if DBG 
            if (!Debug.IsTagPresent("Timer") || Debug.IsTagEnabled("Timer")) 
#endif
            { 
                s_heartbeatTimer = new Timer(new TimerCallback(this.HeartbeatCallback), null,
                    TimeSpan.Zero, interval);
            }
        } 

        internal static HealthMonitoringSectionHelper.ProviderInstances ProviderInstances { 
            get { 
                HealthMonitoringManager manager = Manager();
 
                if (manager == null) {
                    return null;
                }
 
                if (!manager._enabled) {
                    return null; 
                } 

                return manager._sectionHelper._providerInstances; 
            }
        }
    }
 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public sealed class WebBaseEventCollection : ReadOnlyCollectionBase 
    {
        public WebBaseEventCollection(ICollection events) { 
            if (events == null) {
                throw new ArgumentNullException("events");
            }
 
            foreach (WebBaseEvent eventRaised in events) {
                InnerList.Add(eventRaised); 
            } 
        }
 
        internal WebBaseEventCollection(WebBaseEvent eventRaised) {
            if (eventRaised == null) {
                throw new ArgumentNullException("eventRaised");
            } 

            InnerList.Add(eventRaised); 
        } 

        // overloaded collection access methods 
        public WebBaseEvent this[int index] {
            get {
                return (WebBaseEvent) InnerList[index];
            } 
        }
 
        public int IndexOf(WebBaseEvent value) { 
            return InnerList.IndexOf(value);
        } 

        public bool Contains(WebBaseEvent value) {
            return InnerList.Contains(value);
        } 
    }
 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public static class WebEventManager
    { 

        [SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
        public static void Flush(string providerName) {
            HealthMonitoringSectionHelper.ProviderInstances   providers = HealthMonitoringManager.ProviderInstances; 

            if (providers == null) { 
                return; 
            }
 
            if (!providers.ContainsKey(providerName)) {
                throw new ArgumentException(SR.GetString(SR.Health_mon_provider_not_found, providerName));
            }
 
            using (new ApplicationImpersonationContext()) {
                providers[providerName].Flush(); 
            } 
        }
 
        [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        [SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
        public static void Flush() {
            HealthMonitoringSectionHelper.ProviderInstances providers = HealthMonitoringManager.ProviderInstances; 

            if (providers == null) { 
                return; 
            }
 
            using (new ApplicationImpersonationContext()) {
                foreach(DictionaryEntry de in providers) {
                    WebEventProvider    provider = (WebEventProvider)de.Value;
 
                    Debug.Trace("WebEventManager", "Flushing provider " + provider.Name);
                    provider.Flush(); 
                } 
            }
        } 

        internal static void Shutdown() {
            HealthMonitoringSectionHelper.ProviderInstances   providers = HealthMonitoringManager.ProviderInstances;
 
            if (providers == null) {
                return; 
            } 

            foreach(DictionaryEntry de in providers) { 
                WebEventProvider    provider = (WebEventProvider)de.Value;

                Debug.Trace("WebEventManager", "Shutting down provider " + provider.Name);
                provider.Shutdown(); 
            }
        } 
    } 

} 


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

namespace System.Web.Management { 
    using System; 
    using System.Web;
    using System.Diagnostics; 
    using System.Security.Principal;
    using System.Threading;
    using System.Reflection;
    using System.Text; 
    using System.Web.Util;
    using System.Web.Configuration; 
    using System.Configuration.Provider; 
    using System.Collections;
    using System.Collections.Generic; 
    using System.Configuration;
    using System.Security;
    using Debug=System.Web.Util.Debug;
    using System.Web.Hosting; 
    using System.Web.UI;
    using System.Globalization; 
    using System.Runtime.Remoting.Messaging; 
    using System.Security.Permissions;
    using System.Web.Caching; 

    // This enum matches the native one enum WebEventType (in webevent.h).
    internal enum WebEventType : int {
        WEBEVENT_BASE_EVENT = 0, 
        WEBEVENT_MANAGEMENT_EVENT,
        WEBEVENT_APP_LIFETIME_EVENT, 
        WEBEVENT_REQUEST_EVENT, 
        WEBEVENT_HEARTBEAT_EVENT,
        WEBEVENT_BASE_ERROR_EVENT, 
        WEBEVENT_REQUEST_ERROR_EVENT,
        WEBEVENT_ERROR_EVENT,
        WEBEVENT_AUDIT_EVENT,
        WEBEVENT_SUCCESS_AUDIT_EVENT, 
        WEBEVENT_AUTHENTICATION_SUCCESS_AUDIT_EVENT,
        WEBEVENT_FAILURE_AUDIT_EVENT, 
        WEBEVENT_AUTHENTICATION_FAILURE_AUDIT_EVENT, 
        WEBEVENT_VIEWSTATE_FAILURE_AUDIT_EVENT,
    }; 

    internal enum WebEventFieldType : int {
        String = 0,
        Int = 1, 
        Bool = 2,
        Long = 3, 
        Date = 4, 
    }
 
    // Used for marshalling over to IIS Trace
    internal class WebEventFieldData {
        string _name;
        public string Name { 
            get {
                return _name; 
            } 
        }
 
        string _data;
        public string Data {
            get {
                return _data; 
            }
        } 
 
        WebEventFieldType _type;
        public WebEventFieldType Type { 
            get {
                return _type;
            }
        } 

        public WebEventFieldData(string name, string data, WebEventFieldType type) { 
            _name = name; 
            _data = data;
            _type = type; 
        }
    }

 
    // Interface for event provider
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public abstract class WebEventProvider : ProviderBase {
 
        // methods
        public abstract void ProcessEvent(WebBaseEvent raisedEvent);
        public abstract void Shutdown();
        public abstract void Flush(); 

        int _exceptionLogged; 
 
        internal void LogException(Exception e) {
            // In order to not overflow the eventlog, we only log one exception per provider instance. 
            if (Interlocked.CompareExchange( ref _exceptionLogged, 1, 0) == 0) {
                // Log all errors in eventlog
                UnsafeNativeMethods.LogWebeventProviderFailure(
                                        HttpRuntime.AppDomainAppVirtualPath, 
                                        Name,
                                        e.ToString()); 
            } 
        }
    } 

    // Interface for custom event evaluator

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public interface IWebEventCustomEvaluator { 
        bool CanFire(WebBaseEvent raisedEvent, RuleFiringRecord record); 
    }
 
    ////////////////
    // Events
    ////////////////
 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebBaseEvent {
        DateTime        _eventTimeUtc; 
        int             _code;
        int             _detailCode;
        Object          _source;
        string          _message; 
        long            _sequenceNumber;
        long            _occurrenceNumber; 
        Guid            _id  = Guid.Empty; 

        static long                         s_globalSequenceNumber = 0; 
        static WebApplicationInformation    s_applicationInfo = new WebApplicationInformation();
        const string                        WEBEVENT_RAISE_IN_PROGRESS = "_WEvtRIP";

        // A array that cache the result of eventCode to SystemEventType mapping. 
        static readonly SystemEventType[,]  s_eventCodeToSystemEventTypeMappings = new SystemEventType[WebEventCodes.GetEventArrayDimensionSize(0),
                                                                  WebEventCodes.GetEventArrayDimensionSize(1)]; 
 
        // A array that store the # of occurrence per custom event code.
        static readonly long[,]             s_eventCodeOccurrence = new long[WebEventCodes.GetEventArrayDimensionSize(0), 
                                                                  WebEventCodes.GetEventArrayDimensionSize(1)];

        static Hashtable                    s_customEventCodeOccurrence = new Hashtable();
        #pragma warning disable 0649 
        static ReadWriteSpinLock            s_lockCustomEventCodeOccurrence;
        #pragma warning restore 0649 
 
        static WebBaseEvent() {
 
            // Initialize the mappings.  We will fill up each entry on demand by calling
            // SystemEventTypeFromEventCode().

            for (int i = 0; i < s_eventCodeToSystemEventTypeMappings.GetLength(0); i++) { 
                for (int j = 0; j < s_eventCodeToSystemEventTypeMappings.GetLength(1); j++) {
                    s_eventCodeToSystemEventTypeMappings[i,j] = SystemEventType.Unknown; 
                } 
            }
 
            for (int i = 0; i < s_eventCodeOccurrence.GetLength(0); i++) {
                for (int j = 0; j < s_eventCodeOccurrence.GetLength(1); j++) {
                    s_eventCodeOccurrence[i,j] = 0;
                } 
            }
        } 
 
        void Init(string message, Object eventSource, int eventCode, int eventDetailCode) {
            if (eventCode < 0) { 
                throw new ArgumentOutOfRangeException("eventCode",
                    SR.GetString(SR.Invalid_eventCode_error));
            }
 
            if (eventDetailCode < 0) {
                throw new ArgumentOutOfRangeException("eventDetailCode", 
                    SR.GetString(SR.Invalid_eventDetailCode_error)); 
            }
 
            _code = eventCode;
            _detailCode = eventDetailCode;
            _source = eventSource;
            _eventTimeUtc = DateTime.UtcNow; 
            _message = message;
 
            // Creation of _id is always delayed until it's needed. 
        }
 
        // ctors
        internal protected WebBaseEvent(string message, Object eventSource, int eventCode) {
            Init(message, eventSource, eventCode, WebEventCodes.UndefinedEventDetailCode);
        } 

        internal protected WebBaseEvent(string message, Object eventSource, int eventCode, int eventDetailCode) { 
            Init(message, eventSource, eventCode, eventDetailCode); 
        }
 
        internal WebBaseEvent() {
            // For creating dummy event.  See GetSystemDummyEvent()
        }
 
        internal bool IsSystemEvent {
            get { 
                return (_code < WebEventCodes.WebExtendedBase); 
            }
        } 

        // Properties

        public DateTime EventTime { get { return _eventTimeUtc.ToLocalTime(); } } 

        public DateTime EventTimeUtc { get { return _eventTimeUtc; } } 
 
        public String Message { get { return _message; } }
 
        public Object EventSource { get { return _source; } }

        public long EventSequence { get { return _sequenceNumber; } }
 
        public long EventOccurrence { get { return _occurrenceNumber; } }
 
        public int EventCode { get { return _code; } } 

        public int EventDetailCode { get { return _detailCode; } } 

        public Guid EventID {
            get {
                if (_id == Guid.Empty) { 
                    lock(this) {
                        if (_id == Guid.Empty) { 
                            _id = Guid.NewGuid(); 
                        }
                    } 
                }

                return _id;
            } 
        }
 
        public static WebApplicationInformation ApplicationInformation { 
            get { return s_applicationInfo; }
        } 

        virtual internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) {
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_code, EventCode.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_message, Message)); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_time, EventTime.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_time_Utc, EventTimeUtc.ToString(CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_id, EventID.ToString("N", CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_sequence, EventSequence.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_occurrence, EventOccurrence.ToString(CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_detail_code, EventDetailCode.ToString(CultureInfo.InstalledUICulture)));

            if (includeAppInfo) {
                formatter.AppendLine(String.Empty); 
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_application_information));
                formatter.IndentationLevel += 1; 
                ApplicationInformation.FormatToString(formatter); 
                formatter.IndentationLevel -= 1;
            } 
        }


        public override string ToString() { 
            return ToString(true, true);
        } 
 
        public virtual string ToString(bool includeAppInfo, bool includeCustomEventDetails) {
            WebEventFormatter   formatter = new WebEventFormatter(); 

            FormatToString(formatter, includeAppInfo);

            if (!IsSystemEvent && includeCustomEventDetails) { 
                formatter.AppendLine(String.Empty);
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_custom_event_details)); 
                formatter.IndentationLevel += 1; 
                FormatCustomEventDetails(formatter);
                formatter.IndentationLevel -= 1; 
            }

            return formatter.ToString();
        } 

        virtual public void FormatCustomEventDetails(WebEventFormatter formatter) { 
        } 

        internal int InferEtwTraceVerbosity() { 
            WebEventType type = WebBaseEvent.WebEventTypeFromWebEvent(this);
            switch (type) {
                case WebEventType.WEBEVENT_VIEWSTATE_FAILURE_AUDIT_EVENT:
                case WebEventType.WEBEVENT_BASE_ERROR_EVENT: 
                case WebEventType.WEBEVENT_REQUEST_ERROR_EVENT:
                case WebEventType.WEBEVENT_FAILURE_AUDIT_EVENT: 
                case WebEventType.WEBEVENT_AUTHENTICATION_FAILURE_AUDIT_EVENT: 
                case WebEventType.WEBEVENT_ERROR_EVENT:
                    return EtwTraceLevel.Warning; 
                case WebEventType.WEBEVENT_AUDIT_EVENT:
                case WebEventType.WEBEVENT_SUCCESS_AUDIT_EVENT:
                case WebEventType.WEBEVENT_AUTHENTICATION_SUCCESS_AUDIT_EVENT:
                    return EtwTraceLevel.Information; 
                case WebEventType.WEBEVENT_BASE_EVENT:
                case WebEventType.WEBEVENT_MANAGEMENT_EVENT: 
                case WebEventType.WEBEVENT_REQUEST_EVENT: 
                default:
                    return EtwTraceLevel.Verbose; 
            }
        }

        internal void DeconstructWebEvent(out int eventType, out int fieldCount, out string[] fieldNames, out int[] fieldTypes, out string[] fieldData) { 
            List fields = new List();
 
            eventType = (int)WebBaseEvent.WebEventTypeFromWebEvent(this); 
            GenerateFieldsForMarshal(fields);
            fieldCount = fields.Count; 
            fieldNames = new string[fieldCount];
            fieldData = new string[fieldCount];
            fieldTypes = new int[fieldCount];
 
            for (int i = 0; i < fieldCount; ++i) {
                fieldNames[i] = fields[i].Name; 
                fieldData[i] = fields[i].Data; 
                fieldTypes[i] = (int)fields[i].Type;
            } 
        }

        internal virtual void GenerateFieldsForMarshal(List fields) {
            fields.Add(new WebEventFieldData("EventTime", EventTimeUtc.ToString(), WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("EventID", EventID.ToString(), WebEventFieldType.String));
            fields.Add(new WebEventFieldData("EventMessage", Message, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("ApplicationDomain", WebBaseEvent.ApplicationInformation.ApplicationDomain, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("TrustLevel", WebBaseEvent.ApplicationInformation.TrustLevel, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("ApplicationVirtualPath", WebBaseEvent.ApplicationInformation.ApplicationVirtualPath, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("ApplicationPath", WebBaseEvent.ApplicationInformation.ApplicationPath, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("MachineName", WebBaseEvent.ApplicationInformation.MachineName, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("EventCode", EventCode.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Int));
            fields.Add(new WebEventFieldData("EventDetailCode", EventDetailCode.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Int)); 
            fields.Add(new WebEventFieldData("SequenceNumber", EventSequence.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Long));
            fields.Add(new WebEventFieldData("Occurrence", EventOccurrence.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Long)); 
        } 

        internal virtual void PreProcessEventInit() { 
        }

        static void FindEventCode(Exception e, ref int eventCode, ref int eventDetailsCode, ref Exception eStack) {
            eventDetailsCode = WebEventCodes.UndefinedEventDetailCode; 

            if (e is ConfigurationException) { 
                eventCode = WebEventCodes.WebErrorConfigurationError; 
            }
            else if (e is HttpRequestValidationException) { 
                eventCode = WebEventCodes.RuntimeErrorValidationFailure;
            }
            else if (e is HttpCompileException) {
                eventCode = WebEventCodes.WebErrorCompilationError; 
            }
            else if (e is SecurityException) { 
                eventCode = WebEventCodes.AuditUnhandledSecurityException; 
            }
            else if (e is UnauthorizedAccessException) { 
                eventCode = WebEventCodes.AuditUnhandledAccessException;
            }
            else  if (e is HttpParseException) {
                eventCode = WebEventCodes.WebErrorParserError; 
            }
            else if (e is HttpException && e.InnerException is ViewStateException) { 
                ViewStateException vse = (ViewStateException)e.InnerException; 
                eventCode = WebEventCodes.AuditInvalidViewStateFailure;
                if (vse._macValidationError) { 
                    eventDetailsCode = WebEventCodes.InvalidViewStateMac;
                }
                else {
                    eventDetailsCode = WebEventCodes.InvalidViewState; 
                }
 
                eStack = vse; 
            }
            else if (e is HttpException && ((HttpException)e).WebEventCode != WebEventCodes.UndefinedEventCode) { 
                eventCode = ((HttpException)e).WebEventCode;
            }
            else {
                // We don't know what it is.  Let's see if we can find it out by using the inner exception. 

                if (e.InnerException != null) { 
                    // We will call FindEventCode recusively to find out if e.InnerException is the real one. 

                    if (eStack == null) { 
                        // Set eStack here.  If the recursive call ends up landing in
                        // WebEventCodes.RuntimeErrorUnhandledException, we'll use the original
                        // inner exception as our final result.
                        eStack = e.InnerException; 
                    }
 
                    FindEventCode(e.InnerException, ref eventCode, ref eventDetailsCode, ref eStack); 
                }
                else { 
                    // It doesn't have an inner exception.  Just return the generic unhandled-exception
                    eventCode = WebEventCodes.RuntimeErrorUnhandledException;
                }
            } 

            if (eStack == null) { 
                eStack = e; 
            }
        } 

        static internal void RaiseRuntimeError(Exception e, object source) {
            Debug.Trace("WebEventRaiseError", "Error Event is raised; type=" + e.GetType().Name);
 
            if (!HealthMonitoringManager.Enabled) {
                return; 
            } 

            try { 
                int         eventCode = WebEventCodes.UndefinedEventCode;
                int         eventDetailsCode = WebEventCodes.UndefinedEventDetailCode;
                HttpContext context = HttpContext.Current;
                Exception   eStack = null; 

                if (context != null) { 
                    Page    page = context.Handler as Page; 

                    // Errors from Transacted pages can be wrapped by a 
                    // HttpException
                    if (page != null &&
                        page.IsTransacted &&
                        e.GetType() == typeof(HttpException) && 
                        e.InnerException != null) {
 
                        e = e.InnerException; 
                    }
                } 

                FindEventCode(e, ref eventCode, ref eventDetailsCode, ref eStack);
                WebBaseEvent.RaiseSystemEvent(source, eventCode, eventDetailsCode, eStack);
            } 
            catch {
            } 
        } 

        virtual internal protected void IncrementPerfCounters() { 
            PerfCounters.IncrementCounter(AppPerfCounter.EVENTS_TOTAL);
        }

        class CustomEventCodeOccurrence { 
            internal long    _occurrence;
        } 
 
        internal void IncrementTotalCounters(int index0, int index1) {
            _sequenceNumber = Interlocked.Increment(ref s_globalSequenceNumber); 

            if (index0 != -1) {
                _occurrenceNumber = Interlocked.Increment(ref s_eventCodeOccurrence[index0, index1]);
            } 
            else {
                CustomEventCodeOccurrence ceco = (CustomEventCodeOccurrence)s_customEventCodeOccurrence[_code]; 
 
                if (ceco == null) {
                    s_lockCustomEventCodeOccurrence.AcquireWriterLock(); 
                    try {
                        ceco = (CustomEventCodeOccurrence)s_customEventCodeOccurrence[_code];
                        if (ceco == null) {
                            ceco = new CustomEventCodeOccurrence(); 
                            s_customEventCodeOccurrence[_code] = ceco;
                        } 
                    } 
                    finally {
                        s_lockCustomEventCodeOccurrence.ReleaseWriterLock(); 
                    }
                }

                _occurrenceNumber = Interlocked.Increment(ref ceco._occurrence); 
            }
        } 
 
        [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)]
        virtual public void Raise() { 
            Raise(this);
        }

        // Internally raised events don't go thru this method.  They go directly to RaiseSystemEvent --> RaiseInternal 
        [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Medium)]
        static public void Raise(WebBaseEvent eventRaised) { 
            if (eventRaised.EventCode < WebEventCodes.WebExtendedBase) { 
                throw new HttpException(SR.GetString(SR.System_eventCode_not_allowed,
                        eventRaised.EventCode.ToString(CultureInfo.CurrentCulture), 
                        WebEventCodes.WebExtendedBase.ToString(CultureInfo.CurrentCulture)));
            }

            if (!HealthMonitoringManager.Enabled) { 
                Debug.Trace(
                    "WebEventRaiseDetails", "Can't fire event because we are disabled or we can't configure HealthMonManager"); 
                return; 
            }
 
            RaiseInternal(eventRaised, null, -1, -1);
        }

        static internal void RaiseInternal(WebBaseEvent eventRaised, ArrayList firingRuleInfos, int index0, int index1) { 
            bool    preProcessEventInitCalled = false;
            bool    inProgressSet = false; 
            object  o; 
            ProcessImpersonationContext ictx = null;
            HttpContext context = HttpContext.Current; 

            Debug.Trace(
                "WebEventRaiseDetails", "Event is raised; event class = " + eventRaised.GetType().Name);
 
            // Use CallContext to make sure we detect an infinite loop where a provider calls Raise().
            o = CallContext.GetData(WEBEVENT_RAISE_IN_PROGRESS); 
            if (o != null && (bool)o) { 
                Debug.Trace(
                    "WebEventRaiseDetails", "An event is raised while we're raising an event.  Ignore it."); 
                return;
            }

            eventRaised.IncrementPerfCounters(); 
            eventRaised.IncrementTotalCounters(index0, index1);
 
            // Find the list of rules that match this event 
            if (firingRuleInfos == null) {
                HealthMonitoringManager manager = HealthMonitoringManager.Manager(); 

                Debug.Assert(manager != null, "manager != null");

                firingRuleInfos = manager._sectionHelper.FindFiringRuleInfos(eventRaised.GetType(), eventRaised.EventCode); 
            }
 
            if (firingRuleInfos.Count == 0) { 
                return;
            } 

            try {
                bool[]  matchingProviderArray = null;
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null)
                    EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_RAISE_START, 
                                   context.WorkerRequest, 
                                   eventRaised.GetType().FullName,
                                   eventRaised.EventCode.ToString(CultureInfo.InstalledUICulture), 
                                   eventRaised.EventDetailCode.ToString(CultureInfo.InstalledUICulture),
                                   null);

                try { 
                    foreach (HealthMonitoringSectionHelper.FiringRuleInfo firingRuleInfo in firingRuleInfos) {
                        HealthMonitoringSectionHelper.RuleInfo  ruleInfo = firingRuleInfo._ruleInfo; 
                        RuleFiringRecord record = ruleInfo._ruleFiringRecord; 

                        // Check if we should fire the event based on its throttling settings 
                        if (!record.CheckAndUpdate(eventRaised)) {
                            Debug.Trace("WebEventRaiseDetails",
                                    "Throttling settings not met; not fired");
                            continue; 
                        }
 
                        // It's valid for a rule to have no referenced provider 
                        if (ruleInfo._referencedProvider != null) {
                            if (!preProcessEventInitCalled) { 
                                // The event may need to do pre-ProcessEvent initialization
                                eventRaised.PreProcessEventInit();
                                preProcessEventInitCalled = true;
                            } 

                            // For rule infos that share the same provider, the _indexOfFirstRuleInfoWithSameProvider field 
                            // is the index of the first ruleInfo among them.  We use that index in the boolean array 
                            // matchingProviderArray to remember if we've already fired that provider.
                            // This is for the scenario where several rules are pointing to the same provider, 
                            // and even if >1 rule actually fire and pass all throttling check,
                            // the provider is stilled fired only once.
                            if (firingRuleInfo._indexOfFirstRuleInfoWithSameProvider != -1) {
                                if (matchingProviderArray == null) { 
                                    matchingProviderArray = new bool[firingRuleInfos.Count];
                                } 
 
                                if (matchingProviderArray[firingRuleInfo._indexOfFirstRuleInfoWithSameProvider]) {
                                    Debug.Trace("WebEventRaiseDetails", 
                                            "Rule with a matching provider already fired.");
                                    continue;
                                }
 
                                matchingProviderArray[firingRuleInfo._indexOfFirstRuleInfoWithSameProvider] = true;
                            } 
 
                            if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null)
                                EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_DELIVER_START, 
                                               context.WorkerRequest,
                                               ruleInfo._ruleSettings.Provider,
                                               ruleInfo._ruleSettings.Name,
                                               ruleInfo._ruleSettings.EventName, 
                                               null);
 
                            // In retail build, ignore errors from provider 
                            try {
                                if (ictx == null) { 
                                    ictx = new ProcessImpersonationContext();
                                }

                                if (!inProgressSet) { 
                                    CallContext.SetData(WEBEVENT_RAISE_IN_PROGRESS, true);
                                    inProgressSet = true; 
                                } 

                                Debug.Trace("WebEventRaiseDetails", "Calling ProcessEvent under " + WindowsIdentity.GetCurrent().Name); 
                                ruleInfo._referencedProvider.ProcessEvent(eventRaised);
                            }
                            catch (Exception e) {
                                try { 
                                    ruleInfo._referencedProvider.LogException(e);
                                } 
                                catch { 
                                    // ignore all errors
                                } 
                            }
                            finally {
                                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null)
                                    EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_DELIVER_END, 
                                                   context.WorkerRequest);
                            } 
                        } 
                    }
                } 
                finally {
                    // Resume client impersonation
                    if (ictx != null) {
                        ictx.Undo(); 
                    }
 
                    if (inProgressSet) { 
                        CallContext.FreeNamedDataSlot(WEBEVENT_RAISE_IN_PROGRESS);
                    } 

                    if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null)
                        EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_RAISE_END,
                                       context.WorkerRequest); 
                }
            } 
            catch { throw; }    // Prevent Exception Filter Security Issue (ASURT 122835) 
        }
 
        internal static void RaiseSystemEvent(string message, object source, int eventCode, int eventDetailCode, Exception exception) {
            RaiseSystemEventInternal(message, source, eventCode, eventDetailCode, exception, null);
        }
 
        internal static void RaiseSystemEvent(object source, int eventCode) {
            RaiseSystemEventInternal(null, source, eventCode, WebEventCodes.UndefinedEventDetailCode, null, null); 
        } 

        internal static void RaiseSystemEvent(object source, int eventCode, int eventDetailCode) { 
            RaiseSystemEventInternal(null, source, eventCode, eventDetailCode, null, null);
        }

        internal static void RaiseSystemEvent(object source, int eventCode, int eventDetailCode, Exception exception) { 
            RaiseSystemEventInternal(null, source, eventCode, eventDetailCode, exception, null);
        } 
 
        internal static void RaiseSystemEvent(object source, int eventCode, string nameToAuthenticate) {
            RaiseSystemEventInternal(null, source, eventCode, WebEventCodes.UndefinedEventDetailCode, null, nameToAuthenticate); 
        }

        static void RaiseSystemEventInternal(string message, object source,
                        int eventCode, int eventDetailCode, Exception exception, 
                        string nameToAuthenticate) {
            HealthMonitoringManager manager; 
            ArrayList       firingRuleInfos; 
            SystemEventTypeInfo typeInfo;
            SystemEventType     systemEventType; 
            int                 index0, index1;

            Debug.Trace(
                "WebEventRaiseDetails", "RaiseSystemEventInternal called; eventCode=" + eventCode + "; eventDetailCode=" + eventDetailCode); 

            if (!HealthMonitoringManager.Enabled) { 
                Debug.Trace( 
                    "WebEventRaiseDetails", "Can't fire event because we are disabled or we can't configure HealthMonManager");
                return; 
            }

            WebEventCodes.GetEventArrayIndexsFromEventCode(eventCode, out index0, out index1);
 
            GetSystemEventTypeInfo(eventCode, index0, index1, out typeInfo, out systemEventType);
            if (typeInfo == null) { 
                Debug.Assert(false, "Unexpected system event code = " + eventCode); 
                return;
            } 

            manager = HealthMonitoringManager.Manager();

            // Figure out if there is any provider that subscribes to it 
            firingRuleInfos = manager._sectionHelper.FindFiringRuleInfos(typeInfo._type, eventCode);
            if (firingRuleInfos.Count == 0) { 
                // Even if we're not firing it, we still have to increment some global counters 
                typeInfo._dummyEvent.IncrementPerfCounters();
                typeInfo._dummyEvent.IncrementTotalCounters(index0, index1); 
            }
            else {
                // We will fire the event
                WebBaseEvent.RaiseInternal( 
                                NewEventFromSystemEventType(false, systemEventType, message, source, eventCode, eventDetailCode,
                                                        exception, nameToAuthenticate), 
                                firingRuleInfos, index0, index1); 
            }
        } 

        // An enum of all the types of web event we will fire
        enum SystemEventType {
            Unknown = -1, 
            WebApplicationLifetimeEvent,
            WebHeartbeatEvent, 
            WebRequestEvent, 
            WebRequestErrorEvent,
            WebErrorEvent, 
            WebAuthenticationSuccessAuditEvent,
            WebSuccessAuditEvent,
            WebAuthenticationFailureAuditEvent,
            WebFailureAuditEvent, 
            WebViewStateFailureAuditEvent,
            Last 
        }; 

        class SystemEventTypeInfo { 
            internal WebBaseEvent       _dummyEvent;    // For calling IncrementPerfCounters. See RaiseSystemEventInternal for details.
            internal Type               _type;

            internal SystemEventTypeInfo(WebBaseEvent dummyEvent) { 
                _dummyEvent = dummyEvent;
                _type = dummyEvent.GetType(); 
            } 
        };
 
        // An array to cache the event type info for each system event type
        static SystemEventTypeInfo[]    s_systemEventTypeInfos = new SystemEventTypeInfo[(int)SystemEventType.Last];

        static void GetSystemEventTypeInfo(int eventCode, int index0, int index1, 
                        out SystemEventTypeInfo info, out SystemEventType systemEventType) {
 
            // Figure out what SystemEventType this eventCode maps to. 
            // For each eventCode, we store the result in a cache.
            systemEventType = s_eventCodeToSystemEventTypeMappings[index0, index1]; 
            if (systemEventType == SystemEventType.Unknown) {
                systemEventType = SystemEventTypeFromEventCode(eventCode);
                s_eventCodeToSystemEventTypeMappings[index0, index1] = systemEventType;
            } 

            // Based on the systemEventType, we read the SystemEventTypeInfo.  For each 
            // event type, we also cache the info 
            info = s_systemEventTypeInfos[(int)systemEventType];
            if (info != null) { 
                return;
            }

            info = new SystemEventTypeInfo(CreateDummySystemEvent(systemEventType)); 
            s_systemEventTypeInfos[(int)systemEventType] = info;
        } 
 
        static SystemEventType SystemEventTypeFromEventCode(int eventCode) {
            if (eventCode >= WebEventCodes.ApplicationCodeBase && 
                eventCode <= WebEventCodes.ApplicationCodeBaseLast) {
                switch(eventCode) {
                    case WebEventCodes.ApplicationStart:
                    case WebEventCodes.ApplicationShutdown: 
                    case WebEventCodes.ApplicationCompilationStart:
                    case WebEventCodes.ApplicationCompilationEnd: 
                        return SystemEventType.WebApplicationLifetimeEvent; 

                    case WebEventCodes.ApplicationHeartbeat: 
                        return SystemEventType.WebHeartbeatEvent;
                }
            }
 
            if (eventCode >= WebEventCodes.RequestCodeBase &&
                eventCode <= WebEventCodes.RequestCodeBaseLast) { 
                switch(eventCode) { 

                    case WebEventCodes.RequestTransactionComplete: 
                    case WebEventCodes.RequestTransactionAbort:
                        return SystemEventType.WebRequestEvent;
                }
            } 

            if (eventCode >= WebEventCodes.ErrorCodeBase && 
                eventCode <= WebEventCodes.ErrorCodeBaseLast) { 
                switch(eventCode) {
                    case WebEventCodes.RuntimeErrorRequestAbort: 
                    case WebEventCodes.RuntimeErrorViewStateFailure:
                    case WebEventCodes.RuntimeErrorValidationFailure:
                    case WebEventCodes.RuntimeErrorPostTooLarge:
                    case WebEventCodes.RuntimeErrorUnhandledException: 
                        return SystemEventType.WebRequestErrorEvent;
 
                    case WebEventCodes.WebErrorParserError: 
                    case WebEventCodes.WebErrorCompilationError:
                    case WebEventCodes.WebErrorConfigurationError: 
                    case WebEventCodes.WebErrorOtherError:
                    case WebEventCodes.WebErrorPropertyDeserializationError:
                    case WebEventCodes.WebErrorObjectStateFormatterDeserializationError:
                        return SystemEventType.WebErrorEvent; 
                }
            } 
 
            if (eventCode >= WebEventCodes.AuditCodeBase &&
                eventCode <= WebEventCodes.AuditCodeBaseLast) { 
                switch(eventCode) {
                    case WebEventCodes.AuditFormsAuthenticationSuccess:
                    case WebEventCodes.AuditMembershipAuthenticationSuccess:
                        return SystemEventType.WebAuthenticationSuccessAuditEvent; 

                    case WebEventCodes.AuditUrlAuthorizationSuccess: 
                    case WebEventCodes.AuditFileAuthorizationSuccess: 
                        return SystemEventType.WebSuccessAuditEvent;
 
                    case WebEventCodes.AuditFormsAuthenticationFailure:
                    case WebEventCodes.AuditMembershipAuthenticationFailure:
                        return SystemEventType.WebAuthenticationFailureAuditEvent;
 
                    case WebEventCodes.AuditUrlAuthorizationFailure:
                    case WebEventCodes.AuditFileAuthorizationFailure: 
                    case WebEventCodes.AuditUnhandledSecurityException: 
                    case WebEventCodes.AuditUnhandledAccessException:
                        return SystemEventType.WebFailureAuditEvent; 

                    case WebEventCodes.AuditInvalidViewStateFailure:
                        return SystemEventType.WebViewStateFailureAuditEvent;
                } 
            }
 
            if (eventCode >= WebEventCodes.MiscCodeBase && 
                eventCode <= WebEventCodes.MiscCodeBaseLast) {
                switch(eventCode) { 
                    case WebEventCodes.WebEventProviderInformation:
                        Debug.Assert(false, "WebEventProviderInformation shouldn't be used to Raise an event");
                        return SystemEventType.Unknown;
                } 
            }
 
            return SystemEventType.Unknown; 
        }
 
        static WebBaseEvent CreateDummySystemEvent(SystemEventType systemEventType) {
            return NewEventFromSystemEventType(true, systemEventType, null,
                        null, 0, 0, null, null);
        } 

        static WebBaseEvent NewEventFromSystemEventType(bool createDummy, SystemEventType systemEventType, string message, 
                        object source,int eventCode, int eventDetailCode, Exception exception, 
                        string nameToAuthenticate) {
            // If createDummy == true, it means we're only creating a dummy event for the sake of using 
            // it to call IncrementPerfCounters()

            if (!createDummy && message == null) {
                message = WebEventCodes.MessageFromEventCode(eventCode, eventDetailCode); 
            }
 
            // Code view note for the future: 
            // If the number of systemEventType increases tremendoulsy, we may need to
            // avoid using switch, and change to use a "factory" to create new event. 

            switch(systemEventType) {
                case SystemEventType.WebApplicationLifetimeEvent:
                    return createDummy ? new WebApplicationLifetimeEvent() : new WebApplicationLifetimeEvent(message, source, eventCode, eventDetailCode); 

                case SystemEventType.WebHeartbeatEvent: 
                    return createDummy ? new WebHeartbeatEvent() : new WebHeartbeatEvent(message, eventCode); 

                case SystemEventType.WebRequestEvent: 
                    return createDummy ? new WebRequestEvent() : new WebRequestEvent(message, source, eventCode, eventDetailCode);

                case SystemEventType. WebRequestErrorEvent:
                    return createDummy ? new WebRequestErrorEvent() : new WebRequestErrorEvent(message, source, eventCode, eventDetailCode, exception); 

                case SystemEventType.WebErrorEvent: 
                    return createDummy ? new WebErrorEvent() : new WebErrorEvent(message, source, eventCode, eventDetailCode, exception); 

                case SystemEventType.WebAuthenticationSuccessAuditEvent: 
                    return createDummy ? new WebAuthenticationSuccessAuditEvent() : new WebAuthenticationSuccessAuditEvent(message, source, eventCode, eventDetailCode, nameToAuthenticate);

                case SystemEventType.WebSuccessAuditEvent:
                    return createDummy ? new WebSuccessAuditEvent() : new WebSuccessAuditEvent(message, source, eventCode, eventDetailCode); 

                case SystemEventType.WebAuthenticationFailureAuditEvent: 
                    return createDummy ? new WebAuthenticationFailureAuditEvent() : new WebAuthenticationFailureAuditEvent(message, source, eventCode, eventDetailCode, nameToAuthenticate); 

                case SystemEventType.WebFailureAuditEvent: 
                    return createDummy ? new WebFailureAuditEvent() : new WebFailureAuditEvent(message, source, eventCode, eventDetailCode);

                case SystemEventType.WebViewStateFailureAuditEvent:
                    return createDummy ? new WebViewStateFailureAuditEvent() : new WebViewStateFailureAuditEvent(message, source, eventCode, eventDetailCode, (System.Web.UI.ViewStateException)exception); 

                default: 
                    Debug.Assert(false, "Unexpected event type = " + systemEventType); 
                    return null;
            } 
        }

        static string CreateWebEventResourceCacheKey(String key) {
            return CacheInternal.PrefixWebEventResource + key; 
        }
 
        internal static String FormatResourceStringWithCache(String key) { 
            CacheInternal cacheInternal = HttpRuntime.CacheInternal;
            string s; 

            string cacheKey = CreateWebEventResourceCacheKey(key);

            s = (string) cacheInternal.Get(cacheKey); 
            if (s != null) {
                return s; 
            } 

            s = SR.Resources.GetString(key, CultureInfo.InstalledUICulture); 
            if (s != null) {
                cacheInternal.UtcInsert(cacheKey, s);
            }
 
            return s;
        } 
 
        internal static String FormatResourceStringWithCache(String key, String arg0) {
            string fmt = FormatResourceStringWithCache(key); 
            return(fmt != null) ? String.Format(fmt, arg0) : null;
        }

        internal static WebEventType WebEventTypeFromWebEvent(WebBaseEvent eventRaised) { 
            // Note:
            // eventRaised can belong to one of the following classes, or can inherit from one of them. 
            // In order to figure out precisely the WebEventType closest to the type of eventRaised, 
            // we will start our comparison from the leaf nodes in the class hierarchy and work our
            // way up. 

            // Webevent class hierarchy (with the info contained in each class):

            /* 

            - WebBaseEvent (basic) 
                - WebManagementEvent (+ WebProcessInformation) 
                    - WebHeartbeatEvent (+ WebProcessStatistics)
                    - WebApplicationLifetimeEvent 
                    - WebRequestEvent (+ WebRequestInformation)
                    - WebBaseErrorEvent (+ Exception)
                        - WebRequestErrorEvent (+ WebRequestInformation + WebThreadInformation)
                        - WebErrorEvent (+ WebRequestInformation + WebThreadInformation) 
                    - WebAuditEvent (+ WebRequestInformation)
                        - WebSuccessAuditEvent 
                            - WebAuthenticationSuccessAuditEvent (+ NameToAuthenticate) 
                        - WebFailureAuditEvent
                            - WebAuthenticationFailureAuditEvent (+ NameToAuthenticate) 
                            - WebViewStateFailureAuditEvent (+ ViewStateException)
            */

            // Hierarchy level 5 

            if (eventRaised is WebAuthenticationSuccessAuditEvent) { 
                return WebEventType.WEBEVENT_AUTHENTICATION_SUCCESS_AUDIT_EVENT; 
            }
 
            if (eventRaised is WebAuthenticationFailureAuditEvent) {
                return WebEventType.WEBEVENT_AUTHENTICATION_FAILURE_AUDIT_EVENT;
            }
 
            if (eventRaised is WebViewStateFailureAuditEvent) {
                return WebEventType.WEBEVENT_VIEWSTATE_FAILURE_AUDIT_EVENT; 
            } 

            // Hierarchy level 4 

            if (eventRaised is WebRequestErrorEvent) {
                return WebEventType.WEBEVENT_REQUEST_ERROR_EVENT;
            } 

            if (eventRaised is WebErrorEvent) { 
                return WebEventType.WEBEVENT_ERROR_EVENT; 
            }
 
            if (eventRaised is WebSuccessAuditEvent) {
                return WebEventType.WEBEVENT_SUCCESS_AUDIT_EVENT;
            }
 
            if (eventRaised is WebFailureAuditEvent) {
                return WebEventType.WEBEVENT_FAILURE_AUDIT_EVENT; 
            } 

            // Hierarchy level 3 

            if (eventRaised is WebHeartbeatEvent) {
                return WebEventType.WEBEVENT_HEARTBEAT_EVENT;
            } 

            if (eventRaised is WebApplicationLifetimeEvent) { 
                return WebEventType.WEBEVENT_APP_LIFETIME_EVENT; 
            }
 
            if (eventRaised is WebRequestEvent) {
                return WebEventType.WEBEVENT_REQUEST_EVENT;
            }
 
            if (eventRaised is WebBaseErrorEvent) {
                return WebEventType.WEBEVENT_BASE_ERROR_EVENT; 
            } 

            if (eventRaised is WebAuditEvent) { 
                return WebEventType.WEBEVENT_AUDIT_EVENT;
            }

            // Hierarchy level 2 

            if (eventRaised is WebManagementEvent) { 
                return WebEventType.WEBEVENT_MANAGEMENT_EVENT; 
            }
 
            // Hierarchy level 1

            return WebEventType.WEBEVENT_BASE_EVENT;
        } 

        static internal void RaisePropertyDeserializationWebErrorEvent(SettingsProperty property, object source, Exception exception) { 
            if (HttpContext.Current == null) { 
                return;
            } 

            WebBaseEvent.RaiseSystemEvent(
                SR.GetString(SR.Webevent_msg_Property_Deserialization,
                            property.Name, property.SerializeAs.ToString(), property.PropertyType.AssemblyQualifiedName ), 
                source,
                WebEventCodes.WebErrorPropertyDeserializationError, 
                WebEventCodes.UndefinedEventDetailCode, 
                exception);
        } 
    }


    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebEventFormatter { 
        int             _level; 
        StringBuilder   _sb;
        int             _tabSize; 

        void AddTab() {
            int level = _level;
 
            while (level > 0) {
                _sb.Append(' ', _tabSize); 
                level--; 
            }
        } 

        internal WebEventFormatter() {
            _level = 0;
            _sb = new StringBuilder(); 
            _tabSize = 4;
        } 
 
        public void AppendLine(string s) {
            AddTab(); 
            _sb.Append(s);
            _sb.Append('\n');
        }
 
        new public string ToString() {
            return _sb.ToString(); 
        } 

        public int IndentationLevel { 
            get { return _level; }
            set { _level = Math.Max(value, 0); }
        }
 
        public int TabSize {
            get { return _tabSize; } 
            set { _tabSize = Math.Max(value, 0); } 
        }
    } 

    // This class is a base class for all events that require application and process information.
    //
    // WebManagementEvent is the base class for all our webevent classes (except for WebBaseEvent) 
    // Please note that we allow customer to inherit from our webevent classes to make it easier to
    // create custom webevent that contains useful information. 
    // However, WebManagementEvent (and other child events) contains sensitive information (e.g. process id, process account name) 
    // that cannot be obtained unless in full-trust.
    // 
    // In non-fulltrust app, we still want code inside system.web.dll to create these webevents
    // even if there is user code on the stack (we either assert or call unmanaged code to get those info).
    // So to protect these full-trust information from non-fulltrust app, we InheritanceDemand FullTrust
    // if the customer wants to inherit from WebManagementEvent. 
    //
    // For details, see VSWhidbey 256684. 
    // 
    [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)]
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebManagementEvent : WebBaseEvent {
        static WebProcessInformation        s_processInfo = new WebProcessInformation();
 
        internal protected WebManagementEvent(string message, object eventSource, int eventCode)
            :base(message, eventSource, eventCode) { 
        } 

        internal protected WebManagementEvent(string message, object eventSource, int eventCode, int eventDetailCode) 
            :base(message, eventSource, eventCode, eventDetailCode) {
        }

        internal WebManagementEvent() { 
            // For creating dummy event.  See GetSystemDummyEvent()
        } 
 
        // properties
        public WebProcessInformation ProcessInformation { 
            get { return s_processInfo; }
        }

        internal override void GenerateFieldsForMarshal(List fields) { 
            base.GenerateFieldsForMarshal(fields);
            fields.Add(new WebEventFieldData("AccountName", ProcessInformation.AccountName, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("ProcessName", ProcessInformation.ProcessName, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("ProcessID", ProcessInformation.ProcessID.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Int));
        } 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) {
            base.FormatToString(formatter, includeAppInfo);
 
            formatter.AppendLine(String.Empty);
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_process_information)); 
 
            formatter.IndentationLevel += 1;
            ProcessInformation.FormatToString(formatter); 
            formatter.IndentationLevel -= 1;
        }

    } 

 
    // This event is raised at periodic intervals (default 30 seconds) and provides information 
    // relative to the state of the running appdomin.
 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebHeartbeatEvent : WebManagementEvent {
        static WebProcessStatistics    s_procStats = new WebProcessStatistics(); 

        internal protected WebHeartbeatEvent(string message, int eventCode) 
            :base(message, null, eventCode) 
        {
        } 

        internal WebHeartbeatEvent() {
            // For creating dummy event.  See GetSystemDummyEvent()
        } 

 
        public WebProcessStatistics ProcessStatistics {get {return s_procStats;}} 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) { 
            base.FormatToString(formatter, includeAppInfo);

            formatter.AppendLine(String.Empty);
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_process_statistics)); 

            formatter.IndentationLevel += 1; 
            s_procStats.FormatToString(formatter); 
            formatter.IndentationLevel -= 1;
        } 
    }


    // This event represents a notable event in the lifetime of an application (app domain) 
    // including startup and shutdown events.  When an app domain is terminated, the reason
    // will be expressed in the Message field (e.g. compilation threshold exceed, Shutdown 
    // called explicitly, etc.). 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebApplicationLifetimeEvent : WebManagementEvent {

        internal protected WebApplicationLifetimeEvent(string message, object eventSource, int eventCode) 
            :base(message, eventSource, eventCode)
        { 
        } 

 
        internal protected WebApplicationLifetimeEvent(string message, object eventSource, int eventCode, int eventDetailCode)
            :base(message, eventSource, eventCode, eventDetailCode)
        {
        } 

        internal WebApplicationLifetimeEvent() { 
            // For creating dummy event.  See GetSystemDummyEvent() 
        }
 
        static internal int DetailCodeFromShutdownReason(ApplicationShutdownReason reason) {
            switch (reason) {
            case ApplicationShutdownReason.HostingEnvironment:
                return WebEventCodes.ApplicationShutdownHostingEnvironment; 

            case ApplicationShutdownReason.ChangeInGlobalAsax: 
                return WebEventCodes.ApplicationShutdownChangeInGlobalAsax; 

            case ApplicationShutdownReason.ConfigurationChange: 
                return WebEventCodes.ApplicationShutdownConfigurationChange;

            case ApplicationShutdownReason.UnloadAppDomainCalled:
                return WebEventCodes.ApplicationShutdownUnloadAppDomainCalled; 

            case ApplicationShutdownReason.ChangeInSecurityPolicyFile: 
                return WebEventCodes.ApplicationShutdownChangeInSecurityPolicyFile; 

            case ApplicationShutdownReason.BinDirChangeOrDirectoryRename: 
                return WebEventCodes.ApplicationShutdownBinDirChangeOrDirectoryRename;

            case ApplicationShutdownReason.BrowsersDirChangeOrDirectoryRename:
                return WebEventCodes.ApplicationShutdownBrowsersDirChangeOrDirectoryRename; 

            case ApplicationShutdownReason.CodeDirChangeOrDirectoryRename: 
                return WebEventCodes.ApplicationShutdownCodeDirChangeOrDirectoryRename; 

            case ApplicationShutdownReason.ResourcesDirChangeOrDirectoryRename: 
                return WebEventCodes.ApplicationShutdownResourcesDirChangeOrDirectoryRename;

            case ApplicationShutdownReason.IdleTimeout:
                return WebEventCodes.ApplicationShutdownIdleTimeout; 

            case ApplicationShutdownReason.PhysicalApplicationPathChanged: 
                return WebEventCodes.ApplicationShutdownPhysicalApplicationPathChanged; 

            case ApplicationShutdownReason.HttpRuntimeClose: 
                return WebEventCodes.ApplicationShutdownHttpRuntimeClose;

            case ApplicationShutdownReason.InitializationError:
                return WebEventCodes.ApplicationShutdownInitializationError; 

            case ApplicationShutdownReason.MaxRecompilationsReached: 
                return WebEventCodes.ApplicationShutdownMaxRecompilationsReached; 

            case ApplicationShutdownReason.BuildManagerChange: 
                return WebEventCodes.ApplicationShutdownBuildManagerChange;

            default:
                return WebEventCodes.ApplicationShutdownUnknown; 
            }
        } 
 
        override internal protected void IncrementPerfCounters() {
            base.IncrementPerfCounters(); 
            PerfCounters.IncrementCounter(AppPerfCounter.EVENTS_APP);
        }
    }
 
    // This class serves as a base for non-error events that provide
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebRequestEvent : WebManagementEvent {
        WebRequestInformation   _requestInfo; 

        override internal void PreProcessEventInit() {
            base.PreProcessEventInit();
            InitRequestInformation(); 
        }
 
        internal protected WebRequestEvent(string message, object eventSource, int eventCode) 
        :base(message, eventSource, eventCode)
        { 
        }

        internal protected WebRequestEvent(string message, object eventSource, int eventCode, int eventDetailCode)
            :base(message, eventSource, eventCode, eventDetailCode) 
        {
        } 
 
        internal WebRequestEvent() {
            // For creating dummy event.  See GetSystemDummyEvent() 
        }

        void InitRequestInformation() {
            if (_requestInfo == null) { 
                _requestInfo = new WebRequestInformation();
            } 
        } 

        public WebRequestInformation RequestInformation { 
            get {
                InitRequestInformation();
                return _requestInfo;
            } 
        }
 
        internal override void GenerateFieldsForMarshal(List fields) { 
            base.GenerateFieldsForMarshal(fields);
            fields.Add(new WebEventFieldData("RequestUrl", RequestInformation.RequestUrl, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("RequestPath", RequestInformation.RequestPath, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserHostAddress", RequestInformation.UserHostAddress, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserName", RequestInformation.Principal.Identity.Name, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserAuthenticated", RequestInformation.Principal.Identity.IsAuthenticated.ToString(), WebEventFieldType.Bool)); 
            fields.Add(new WebEventFieldData("UserAuthenticationType", RequestInformation.Principal.Identity.AuthenticationType, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("RequestThreadAccountName", RequestInformation.ThreadAccountName, WebEventFieldType.String)); 
        } 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) { 
            base.FormatToString(formatter, includeAppInfo);

            formatter.AppendLine(String.Empty);
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_information)); 

            formatter.IndentationLevel += 1; 
            RequestInformation.FormatToString(formatter); 
            formatter.IndentationLevel -= 1;
        } 

        override internal protected void IncrementPerfCounters() {
            base.IncrementPerfCounters();
            PerfCounters.IncrementCounter(AppPerfCounter.EVENTS_WEB_REQ); 
        }
    } 
 
    // This is the base class for all error events.
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebBaseErrorEvent : WebManagementEvent {
        Exception               _exception;
 
        void Init(Exception e) {
            _exception = e; 
        } 

        internal protected WebBaseErrorEvent(string message, object eventSource, int eventCode, Exception e) 
            :base(message, eventSource, eventCode)
        {
            Init(e);
        } 

        internal protected WebBaseErrorEvent(string message, object eventSource, int eventCode, int eventDetailCode, Exception e) 
            :base(message, eventSource, eventCode, eventDetailCode) 
        {
            Init(e); 
        }

        internal WebBaseErrorEvent() {
            // For creating dummy event.  See GetSystemDummyEvent() 
        }
 
        public Exception ErrorException { 
            get { return _exception; }
        } 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) {
            base.FormatToString(formatter, includeAppInfo);
 
            if (_exception == null) {
                return; 
            } 

            Exception   ex = _exception; 

            // Please note we arbitrary pick a level limit per bug VSWhidbey 143859
            for (int level = 0;
                  ex != null && level <= 2; 
                  ex = ex.InnerException, level++)  {
 
                formatter.AppendLine(String.Empty); 

                if (level == 0) { 
                    formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_exception_information));
                }
                else {
                    formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_inner_exception_information, level.ToString(CultureInfo.InstalledUICulture))); 
                }
 
                formatter.IndentationLevel += 1; 
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_exception_type, ex.GetType().ToString()));
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_exception_message, ex.Message)); 
                formatter.IndentationLevel -= 1;
            }
        }
 
        internal override void GenerateFieldsForMarshal(List fields) {
            base.GenerateFieldsForMarshal(fields); 
            fields.Add(new WebEventFieldData("ExceptionType", ErrorException.GetType().ToString(), WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("ExceptionMessage", ErrorException.Message, WebEventFieldType.String));
        } 

        override internal protected void IncrementPerfCounters() {
            base.IncrementPerfCounters();
            PerfCounters.IncrementCounter(AppPerfCounter.EVENTS_ERROR); 
            PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.GLOBAL_EVENTS_ERROR);
        } 
    } 

    // This class contains information about systemic errors, e.g. things related to 
    // configuration or application code (parser errors, compilation errors).

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebErrorEvent : WebBaseErrorEvent {
        WebRequestInformation   _requestInfo; 
        WebThreadInformation    _threadInfo; 

        void Init(Exception e) { 
        }

        override internal void PreProcessEventInit() {
            base.PreProcessEventInit(); 
            InitRequestInformation();
            InitThreadInformation(); 
        } 

        internal protected WebErrorEvent(string message, object eventSource, int eventCode, Exception exception) 
            :base(message, eventSource, eventCode, exception)
        {
            Init(exception);
        } 

        internal protected WebErrorEvent(string message, object eventSource, int eventCode, int eventDetailCode, Exception exception) 
            :base(message, eventSource, eventCode, eventDetailCode, exception) 
        {
            Init(exception); 
        }

        internal WebErrorEvent() {
            // For creating dummy event.  See GetSystemDummyEvent() 
        }
 
        void InitRequestInformation() { 
            if (_requestInfo == null) {
                _requestInfo = new WebRequestInformation(); 
            }
        }

        public WebRequestInformation RequestInformation { 
            get {
                InitRequestInformation(); 
                return _requestInfo; 
            }
        } 

        void InitThreadInformation() {
            if (_threadInfo == null) {
                _threadInfo = new WebThreadInformation(base.ErrorException); 
            }
        } 
 
        public WebThreadInformation ThreadInformation {
            get { 
                InitThreadInformation();
                return _threadInfo;
            }
        } 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) { 
            base.FormatToString(formatter, includeAppInfo); 

            formatter.AppendLine(String.Empty); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_information));

            formatter.IndentationLevel += 1;
            RequestInformation.FormatToString(formatter); 
            formatter.IndentationLevel -= 1;
 
            formatter.AppendLine(String.Empty); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_thread_information));
 
            formatter.IndentationLevel += 1;
            ThreadInformation.FormatToString(formatter);
            formatter.IndentationLevel -= 1;
        } 

        internal override void GenerateFieldsForMarshal(List fields) { 
            base.GenerateFieldsForMarshal(fields); 
            fields.Add(new WebEventFieldData("RequestUrl", RequestInformation.RequestUrl, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("RequestPath", RequestInformation.RequestPath, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("UserHostAddress", RequestInformation.UserHostAddress, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserName", RequestInformation.Principal.Identity.Name, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserAuthenticated", RequestInformation.Principal.Identity.IsAuthenticated.ToString(), WebEventFieldType.Bool));
            fields.Add(new WebEventFieldData("UserAuthenticationType", RequestInformation.Principal.Identity.AuthenticationType, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("RequestThreadAccountName", RequestInformation.ThreadAccountName, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("ThreadID", ThreadInformation.ThreadID.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Int)); 
            fields.Add(new WebEventFieldData("ThreadAccountName", ThreadInformation.ThreadAccountName, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("StackTrace", ThreadInformation.StackTrace, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("IsImpersonating", ThreadInformation.IsImpersonating.ToString(), WebEventFieldType.Bool)); 
        }

        override internal protected void IncrementPerfCounters() {
            base.IncrementPerfCounters(); 
            PerfCounters.IncrementCounter(AppPerfCounter.EVENTS_HTTP_INFRA_ERROR);
            PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.GLOBAL_EVENTS_HTTP_INFRA_ERROR); 
        } 
    }
 
    // This class provides information about errors that occur while servicing a request.
    // This include unhandled exceptions, viewstate errors, input validation errors, etc.
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebRequestErrorEvent : WebBaseErrorEvent {
        WebRequestInformation   _requestInfo; 
        WebThreadInformation    _threadInfo; 

        void Init(Exception e) { 
        }

        override internal void PreProcessEventInit() {
            base.PreProcessEventInit(); 
            InitRequestInformation();
            InitThreadInformation(); 
        } 

        internal protected WebRequestErrorEvent(string message, object eventSource, int eventCode, Exception exception) 
            :base(message, eventSource, eventCode, exception)
        {
            Init(exception);
        } 

        internal protected WebRequestErrorEvent(string message, object eventSource, int eventCode, int eventDetailCode, Exception exception) 
            :base(message, eventSource, eventCode, eventDetailCode, exception) 
        {
            Init(exception); 
        }

        internal WebRequestErrorEvent() {
            // For creating dummy event.  See GetSystemDummyEvent() 
        }
 
        // properties 

        void InitRequestInformation() { 
            if (_requestInfo == null) {
                _requestInfo = new WebRequestInformation();
            }
        } 

        public WebRequestInformation RequestInformation { 
            get { 
                InitRequestInformation();
                return _requestInfo; 
            }
        }

        void InitThreadInformation() { 
            if (_threadInfo == null) {
                _threadInfo = new WebThreadInformation(base.ErrorException); 
            } 
        }
 
        public WebThreadInformation ThreadInformation {
            get {
                InitThreadInformation();
                return _threadInfo; 
            }
        } 
 
        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) {
            base.FormatToString(formatter, includeAppInfo); 

            formatter.AppendLine(String.Empty);
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_information));
 
            formatter.IndentationLevel += 1;
            RequestInformation.FormatToString(formatter); 
            formatter.IndentationLevel -= 1; 

            formatter.AppendLine(String.Empty); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_thread_information));

            formatter.IndentationLevel += 1;
            ThreadInformation.FormatToString(formatter); 
            formatter.IndentationLevel -= 1;
        } 
 
        internal override void GenerateFieldsForMarshal(List fields) {
            base.GenerateFieldsForMarshal(fields); 
            fields.Add(new WebEventFieldData("RequestUrl", RequestInformation.RequestUrl, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("RequestPath", RequestInformation.RequestPath, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserHostAddress", RequestInformation.UserHostAddress, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserName", RequestInformation.Principal.Identity.Name, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("UserAuthenticated", RequestInformation.Principal.Identity.IsAuthenticated.ToString(), WebEventFieldType.Bool));
            fields.Add(new WebEventFieldData("UserAuthenticationType", RequestInformation.Principal.Identity.AuthenticationType, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("RequestThreadAccountName", RequestInformation.ThreadAccountName, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("ThreadID", ThreadInformation.ThreadID.ToString(CultureInfo.InstalledUICulture), WebEventFieldType.Int));
            fields.Add(new WebEventFieldData("ThreadAccountName", ThreadInformation.ThreadAccountName, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("StackTrace", ThreadInformation.StackTrace, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("IsImpersonating", ThreadInformation.IsImpersonating.ToString(), WebEventFieldType.Bool));
        }
 
        override internal protected void IncrementPerfCounters() {
            base.IncrementPerfCounters(); 
            PerfCounters.IncrementCounter(AppPerfCounter.EVENTS_HTTP_REQ_ERROR); 
            PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.GLOBAL_EVENTS_HTTP_REQ_ERROR);
        } 
    }


    // The base class for all audit events. 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebAuditEvent : WebManagementEvent {
        WebRequestInformation   _requestInfo; 

        override internal void PreProcessEventInit() {
            base.PreProcessEventInit();
            InitRequestInformation(); 
        }
 
        internal protected WebAuditEvent(string message, object eventSource, int eventCode) 
            :base(message, eventSource, eventCode)
        { 
        }

        internal protected WebAuditEvent(string message, object eventSource, int eventCode, int eventDetailCode)
            :base(message, eventSource, eventCode, eventDetailCode) 
        {
        } 
 
        internal WebAuditEvent() {
            // For creating dummy event.  See GetSystemDummyEvent() 
        }

        void InitRequestInformation() {
            if (_requestInfo == null) { 
                _requestInfo = new WebRequestInformation();
            } 
        } 

        public WebRequestInformation RequestInformation { 
            get {
                InitRequestInformation();
                return _requestInfo;
            } 
        }
 
        internal override void GenerateFieldsForMarshal(List fields) { 
            base.GenerateFieldsForMarshal(fields);
            fields.Add(new WebEventFieldData("RequestUrl", RequestInformation.RequestUrl, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("RequestPath", RequestInformation.RequestPath, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserHostAddress", RequestInformation.UserHostAddress, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserName", RequestInformation.Principal.Identity.Name, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserAuthenticated", RequestInformation.Principal.Identity.IsAuthenticated.ToString(), WebEventFieldType.Bool)); 
            fields.Add(new WebEventFieldData("UserAuthenticationType", RequestInformation.Principal.Identity.AuthenticationType, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("RequestThreadAccountName", RequestInformation.ThreadAccountName, WebEventFieldType.String)); 
        } 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) { 
            base.FormatToString(formatter, includeAppInfo);

            formatter.AppendLine(String.Empty);
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_information)); 

            formatter.IndentationLevel += 1; 
            RequestInformation.FormatToString(formatter); 
            formatter.IndentationLevel -= 1;
        } 
    }


    // This class provides information about all failure audits.  In most cases, 
    // applications will only want to enable failure audits.
 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebFailureAuditEvent : WebAuditEvent { 
        internal protected WebFailureAuditEvent(string message, object eventSource, int eventCode)
            :base(message, eventSource, eventCode)
        {
        } 

        internal protected WebFailureAuditEvent(string message, object eventSource, int eventCode, int eventDetailCode) 
            :base(message, eventSource, eventCode, eventDetailCode) 
        {
        } 

        internal WebFailureAuditEvent() {
            // For creating dummy event.  See GetSystemDummyEvent()
        } 

        override internal protected void IncrementPerfCounters() { 
            base.IncrementPerfCounters(); 
            PerfCounters.IncrementCounter(AppPerfCounter.AUDIT_FAIL);
            PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.GLOBAL_AUDIT_FAIL); 
        }
    }

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebAuthenticationFailureAuditEvent : WebFailureAuditEvent { 
 
        string  _nameToAuthenticate;
 
        void Init(string name) {
            _nameToAuthenticate = name;
        }
 
        internal protected WebAuthenticationFailureAuditEvent(string message, object eventSource, int eventCode, string nameToAuthenticate)
            :base(message, eventSource, eventCode) 
        { 
            Init(nameToAuthenticate);
        } 


        internal protected WebAuthenticationFailureAuditEvent(string message, object eventSource, int eventCode, int eventDetailCode, string nameToAuthenticate)
            :base(message, eventSource, eventCode, eventDetailCode) 
        {
            Init(nameToAuthenticate); 
        } 

        internal WebAuthenticationFailureAuditEvent() { 
            // For creating dummy event.  See GetSystemDummyEvent()
        }

        public string NameToAuthenticate { 
            get { return _nameToAuthenticate; }
        } 
 
        internal override void GenerateFieldsForMarshal(List fields) {
            base.GenerateFieldsForMarshal(fields); 
            fields.Add(new WebEventFieldData("NameToAuthenticate", NameToAuthenticate, WebEventFieldType.String));
        }

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) { 
            base.FormatToString(formatter, includeAppInfo);
 
            formatter.AppendLine(String.Empty); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_name_to_authenticate, _nameToAuthenticate));
 
        }
    }

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebViewStateFailureAuditEvent : WebFailureAuditEvent { 
 
        ViewStateException  _viewStateException;
 
        internal protected WebViewStateFailureAuditEvent(string message, object eventSource, int eventCode, ViewStateException viewStateException)
            :base(message, eventSource, eventCode)
        {
            _viewStateException = viewStateException; 
        }
 
 
        internal protected WebViewStateFailureAuditEvent(string message, object eventSource, int eventCode, int eventDetailCode, ViewStateException viewStateException)
            :base(message, eventSource, eventCode, eventDetailCode) 
        {
            _viewStateException = viewStateException;
        }
 
        internal WebViewStateFailureAuditEvent() {
            // For creating dummy event.  See GetSystemDummyEvent() 
        } 

        public ViewStateException ViewStateException { 
            get { return _viewStateException; }
        }

        internal override void GenerateFieldsForMarshal(List fields) { 
            base.GenerateFieldsForMarshal(fields);
            fields.Add(new WebEventFieldData("ViewStateExceptionMessage", ViewStateException.Message, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("RemoteAddress", ViewStateException.RemoteAddress, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("RemotePort", ViewStateException.RemotePort, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("UserAgent", ViewStateException.UserAgent, WebEventFieldType.String)); 
            fields.Add(new WebEventFieldData("PersistedState", ViewStateException.PersistedState, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("Path", ViewStateException.Path, WebEventFieldType.String));
            fields.Add(new WebEventFieldData("Referer", ViewStateException.Referer, WebEventFieldType.String));
        } 

        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) { 
            base.FormatToString(formatter, includeAppInfo); 

            formatter.AppendLine(String.Empty); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_ViewStateException_information));
            formatter.IndentationLevel += 1;
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_exception_message, _viewStateException.Message));
 
            formatter.IndentationLevel -= 1;
        } 
 
    }
 

    // This class provides information about all success audits.  In most cases,
    // applications will only want to enable failure audits.
 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebSuccessAuditEvent : WebAuditEvent { 
        internal protected WebSuccessAuditEvent(string message, object eventSource, int eventCode)
            :base(message, eventSource, eventCode) 
        {
        }

        internal protected WebSuccessAuditEvent(string message, object eventSource, int eventCode, int eventDetailCode) 
            :base(message, eventSource, eventCode, eventDetailCode)
        { 
        } 

        internal WebSuccessAuditEvent() { 
            // For creating dummy event.  See GetSystemDummyEvent()
        }

        override internal protected void IncrementPerfCounters() { 
            base.IncrementPerfCounters();
            PerfCounters.IncrementCounter(AppPerfCounter.AUDIT_SUCCESS); 
            PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.GLOBAL_AUDIT_SUCCESS); 
        }
    } 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class WebAuthenticationSuccessAuditEvent : WebSuccessAuditEvent { 

        string  _nameToAuthenticate; 
 
        void Init(string name) {
            _nameToAuthenticate = name; 
        }

        internal protected WebAuthenticationSuccessAuditEvent(string message, object eventSource, int eventCode, string nameToAuthenticate)
            :base(message, eventSource, eventCode) 
        {
            Init(nameToAuthenticate); 
        } 

        internal protected WebAuthenticationSuccessAuditEvent(string message, object eventSource, int eventCode, int eventDetailCode, string nameToAuthenticate) 
            :base(message, eventSource, eventCode, eventDetailCode)
        {
            Init(nameToAuthenticate);
        } 

        internal WebAuthenticationSuccessAuditEvent() { 
            // For creating dummy event.  See GetSystemDummyEvent() 
        }
 
        public string NameToAuthenticate {
            get { return _nameToAuthenticate; }
        }
 
        internal override void GenerateFieldsForMarshal(List fields) {
            base.GenerateFieldsForMarshal(fields); 
            fields.Add(new WebEventFieldData("NameToAuthenticate", NameToAuthenticate, WebEventFieldType.String)); 
        }
 
        override internal void FormatToString(WebEventFormatter formatter, bool includeAppInfo) {
            base.FormatToString(formatter, includeAppInfo);

            formatter.AppendLine(String.Empty); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_name_to_authenticate, _nameToAuthenticate));
        } 
    } 

 
    ////////////////
    // Information
    ////////////////
 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public sealed class WebProcessInformation { 
        // The information is per worker process instance.
 
        int     _processId;
        string  _processName;
        string  _accountName;
 
        internal WebProcessInformation() {
            // Can't use Process.ProcessName because it requires the running 
            // account to be part of the Performance Monitor Users group. 
            StringBuilder buf = new StringBuilder(256);
            if (UnsafeNativeMethods.GetModuleFileName(IntPtr.Zero, buf, 256) == 0) { 
                _processName = String.Empty;
            }
            else {
                int lastIndex; 

                _processName = buf.ToString(); 
                lastIndex = _processName.LastIndexOf('\\'); 
                if (lastIndex != -1) {
                    _processName = _processName.Substring(lastIndex + 1); 
                }
            }

            _processId = SafeNativeMethods.GetCurrentProcessId() ; 
            _accountName = HttpRuntime.WpUserId;
        } 
 
        public int ProcessID { get { return _processId; } }
 
        public string ProcessName { get { return _processName; } }

        public string AccountName { get { return (_accountName != null ? _accountName : String.Empty); } }
 
        public void FormatToString(WebEventFormatter formatter) {
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_process_id, ProcessID.ToString(CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_process_name, ProcessName)); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_account_name, AccountName));
        } 
    }


    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public sealed class WebApplicationInformation {
        // The information is per appdomain. 
 
        string  _appDomain;
        string  _trustLevel; 
        string  _appUrl;
        string  _appPath;
        string  _machineName;
 
        internal WebApplicationInformation() {
            _appDomain = Thread.GetDomain().FriendlyName; 
            _trustLevel = HttpRuntime.TrustLevel; 
            _appUrl = HttpRuntime.AppDomainAppVirtualPath;
 
            try {
                // We will get an exception if it's a non-ASP.NET app.
                _appPath = HttpRuntime.AppDomainAppPath;
            } 
            catch {
                _appPath = null; 
            } 
#if FEATURE_PAL // FEATURE_PAL does not fully implement Environment.MachineName
            _machineName = "dummymachinename"; 
#else // FEATURE_PAL
            _machineName = GetMachineNameWithAssert();
#endif // FEATURE_PAL
        } 

        public string ApplicationDomain { get { return _appDomain; } } 
 
        public string TrustLevel { get { return _trustLevel; } }
 
        public string ApplicationVirtualPath { get { return _appUrl; } }

        public string ApplicationPath { get { return _appPath; } }
 
        public string MachineName { get { return _machineName; } }
 
        public void FormatToString(WebEventFormatter formatter) { 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_application_domain, ApplicationDomain));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_trust_level, TrustLevel)); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_application_virtual_path, ApplicationVirtualPath));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_application_path, ApplicationPath));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_machine_name, MachineName));
        } 

        [PermissionSet(SecurityAction.Assert, Unrestricted = true)] 
        private string GetMachineNameWithAssert() { 
            return Environment.MachineName;
        } 

        public override string ToString() {
            WebEventFormatter formatter = new WebEventFormatter();
 
            FormatToString(formatter);
            return formatter.ToString(); 
        } 
    }
 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public sealed class WebRequestInformation {
 
        string      _requestUrl;
        string      _requestPath; 
        IPrincipal  _iprincipal; 
        string      _userHostAddress = null;
        string      _accountName; 

        internal    WebRequestInformation() {
            // Need to Assert() in order to get request information regardless of trust level. See VSWhidbey 416733
            InternalSecurityPermissions.ControlPrincipal.Assert(); 

            HttpContext context = HttpContext.Current; 
            HttpRequest request = null; 

            if (context != null) 
            {
                bool hideRequestResponseOriginal = context.HideRequestResponse;
                context.HideRequestResponse = false;
                request = context.Request; 
                context.HideRequestResponse = hideRequestResponseOriginal;
 
                _iprincipal = context.User; 
            } else {
                _iprincipal = null; 
            }

            if (request == null) {
                _requestUrl = String.Empty; 
                _requestPath = String.Empty;
                _userHostAddress = String.Empty; 
            } 
            else {
                _requestUrl = request.UrlInternal; 
                _requestPath = request.Path;
                _userHostAddress = request.UserHostAddress;
            }
 
            _accountName = WindowsIdentity.GetCurrent().Name;
        } 
 
        // The information is per request.
 
        public string RequestUrl {get {return _requestUrl;}}

        public string RequestPath {get {return _requestPath;}}
 
        public IPrincipal Principal {get {return _iprincipal;}}
 
        public string UserHostAddress { get { return _userHostAddress;} } 

        public string ThreadAccountName {get {return _accountName;}} 

        public void FormatToString(WebEventFormatter formatter) {
            string      user;
            string      authType; 
            bool        authed;
 
            if (Principal == null) { 
                user = String.Empty;
                authType = String.Empty; 
                authed = false;
            }
            else {
                IIdentity    id = Principal.Identity; 

                user = id.Name; 
                authed = id.IsAuthenticated; 
                authType = id.AuthenticationType;
            } 

            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_url, RequestUrl));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_path, RequestPath));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_user_host_address, UserHostAddress)); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_user, user));
 
            if (authed) { 
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_is_authenticated));
            } 
            else {
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_is_not_authenticated));
            }
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_authentication_type, authType)); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_thread_account_name, ThreadAccountName));
 
        } 
    }
 

    // Note that even all the information contained in WebProcessStatistics is obtained from static variables,
    // but we still don't want this class to be static.
    // 
    // Currently, WebProcessStatistics can be obtained only thru WebHeartbeatEvent, which in turn can be
    // created only by Full-trust app thru class inheritance. (System.Web.dll will also internally create it 
    // and the object will be available to our provider.)  Thus, WebProcessStatistics is available only 
    // to Full-trust app or provider.
    // 
    // But if we make WebProcessStatistics static, then all its public methods have to be static, and
    // they'll be fully available to all users.  No good.
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class WebProcessStatistics {
        static DateTime     s_startTime = DateTime.MinValue; 
        static DateTime     s_lastUpdated = DateTime.MinValue; 
        static int          s_threadCount;
        static long         s_workingSet; 
        static long         s_peakWorkingSet;
        static long         s_managedHeapSize;
        static int          s_appdomainCount;
        static int          s_requestsExecuting; 
        static int          s_requestsQueued;
        static int          s_requestsRejected; 
        static bool         s_getCurrentProcFailed = false; 
        static object       s_lockObject = new object();
 
        static TimeSpan      TS_ONE_SECOND = new TimeSpan(0, 0, 1);

        static WebProcessStatistics() {
            try { 
#if !FEATURE_PAL // FEATURE_PAL does not support this.  Make into a noop.
                s_startTime = Process.GetCurrentProcess().StartTime; 
#endif // !FEATURE_PAL 
            }
            catch { 
                s_getCurrentProcFailed = true;
            }
        }
 
        void Update() {
            DateTime    now = DateTime.Now; 
 
            if (now - s_lastUpdated < TS_ONE_SECOND) {
                return; 
            }

            lock (s_lockObject) {
                if (now - s_lastUpdated < TS_ONE_SECOND) { 
                    return;
                } 
 
                if (!s_getCurrentProcFailed) {
                    Process process = Process.GetCurrentProcess(); 
#if !FEATURE_PAL // FEATURE_PAL does not support these Process properties

                    s_threadCount = process.Threads.Count;
                    s_workingSet = (long)process.WorkingSet64; 
                    s_peakWorkingSet = (long)process.PeakWorkingSet64;
#else 
                    throw new NotImplementedException ("ROTORTODO"); 
#endif
                } 

                s_managedHeapSize = GC.GetTotalMemory(false);

                s_appdomainCount = HostingEnvironment.AppDomainsCount; 

                s_requestsExecuting = PerfCounters.GetGlobalCounter(GlobalPerfCounter.REQUESTS_CURRENT); 
                s_requestsQueued = PerfCounters.GetGlobalCounter(GlobalPerfCounter.REQUESTS_QUEUED); 
                s_requestsRejected = PerfCounters.GetGlobalCounter(GlobalPerfCounter.REQUESTS_REJECTED);
 
                s_lastUpdated = now;
            }
        }
 

        public DateTime ProcessStartTime {get {Update(); return s_startTime;}} 
 
        public int ThreadCount {get {Update(); return s_threadCount;}}
 
        public long WorkingSet {get {Update(); return s_workingSet;}}

        public long PeakWorkingSet {get {Update(); return s_peakWorkingSet;}}
 
        public long ManagedHeapSize {get {Update(); return s_managedHeapSize;}}
 
        public int AppDomainCount {get {Update(); return s_appdomainCount;}} 

        public int RequestsExecuting {get {Update(); return s_requestsExecuting;}} 

        public int RequestsQueued {get {Update(); return s_requestsQueued;}}

        public int RequestsRejected {get {Update(); return s_requestsRejected;}} 

 
        virtual public void FormatToString(WebEventFormatter formatter) { 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_process_start_time, ProcessStartTime.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_thread_count, ThreadCount.ToString(CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_working_set, WorkingSet.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_peak_working_set, PeakWorkingSet.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_managed_heap_size, ManagedHeapSize.ToString(CultureInfo.InstalledUICulture)));
 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_application_domain_count, AppDomainCount.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_requests_executing, RequestsExecuting.ToString(CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_queued, RequestsQueued.ToString(CultureInfo.InstalledUICulture))); 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_request_rejected, RequestsRejected.ToString(CultureInfo.InstalledUICulture)));
        } 
    }


    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public sealed class WebThreadInformation {
        int     _threadId; 
        string  _accountName; 
        string  _stackTrace;
        bool    _isImpersonating; 
        internal const string IsImpersonatingKey = "ASPIMPERSONATING";

        internal WebThreadInformation(Exception exception) {
            _threadId = Thread.CurrentThread.ManagedThreadId; 
            _accountName = WindowsIdentity.GetCurrent().Name;
 
            if (exception != null) { 
                _stackTrace = new StackTrace(exception, true).ToString();
            } 
            else {
                _stackTrace = String.Empty;
            }
 
            _isImpersonating = exception.Data.Contains(IsImpersonatingKey);
        } 
 

        public int ThreadID {get {return _threadId;}} 

        public string ThreadAccountName {get {return _accountName;}}

        public string StackTrace {get {return _stackTrace;}} 

        public bool IsImpersonating {get {return _isImpersonating;}} 
 

        public void FormatToString(WebEventFormatter formatter) { 
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_thread_id, ThreadID.ToString(CultureInfo.InstalledUICulture)));
            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_thread_account_name, ThreadAccountName));

            if (IsImpersonating) { 
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_is_impersonating));
            } 
            else { 
                formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_is_not_impersonating));
            } 

            formatter.AppendLine(WebBaseEvent.FormatResourceStringWithCache(SR.Webevent_event_stack_trace, StackTrace));
        }
    } 

    // Class that represents the firing record (how many times, last firing time, etc) 
    // for each rule that inherits from WebBaseEvent. 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public sealed class RuleFiringRecord {
        internal DateTime   _lastFired;
        internal int        _timesRaised;
        internal int        _updatingLastFired; 

        static TimeSpan     TS_ONE_SECOND = new TimeSpan(0, 0, 1); 
 
        public DateTime LastFired { get { return _lastFired; } }
 

        public int TimesRaised { get { return _timesRaised; } }

        // Point to the ruleInfo that is used by this class 
        internal HealthMonitoringSectionHelper.RuleInfo    _ruleInfo;
 
        internal RuleFiringRecord(HealthMonitoringSectionHelper.RuleInfo ruleInfo) { 

            Debug.Assert(ruleInfo != null, "ruleInfo != null"); 

            _ruleInfo = ruleInfo;

            _lastFired = DateTime.MinValue; 
            _timesRaised = 0;
            _updatingLastFired = 0; 
        } 

        void UpdateLastFired(DateTime now, bool alreadyLocked) { 
            TimeSpan    tsDiff = now - _lastFired;

            if (tsDiff < TS_ONE_SECOND) {
                // If _lastFired was updated within one second, don't bother. 
                return;
            } 
 
            if (!alreadyLocked) {
                // If several threads are firing at the same time, only one thread will 
                // update record._lastFired.
                if (Interlocked.CompareExchange(ref _updatingLastFired, 1, 0) == 0) {
                    try {
                        _lastFired = now; 
                    }
                    finally { 
                        Interlocked.Exchange(ref _updatingLastFired, 0); 
                    }
                } 
            }
            else {
                _lastFired = now;
            } 
        }
 
        // Note: this method is thread safe 
        internal bool CheckAndUpdate(WebBaseEvent eventRaised) {
            DateTime    now = DateTime.Now; 
            int         timesRaised;
            HealthMonitoringManager manager = HealthMonitoringManager.Manager();

            timesRaised = Interlocked.Increment(ref _timesRaised); 

            if (manager == null) { 
                // Won't fire because we cannot configure healthmonitor 
                Debug.Trace("RuleFiringRecord", "Can't configure healthmonitor");
                return false; 
            }

            // Call custom evaluator first
            if (_ruleInfo._customEvaluatorType != null) { 

                IWebEventCustomEvaluator    icustom = (IWebEventCustomEvaluator) 
                        manager._sectionHelper._customEvaluatorInstances[_ruleInfo._customEvaluatorType]; 

#if (!DBG) 
                try {
#endif
                    // The event may need to do pre-ProcessEvent initialization
                    eventRaised.PreProcessEventInit(); 

                    if (!icustom.CanFire(eventRaised, this)) { 
                        Debug.Trace("RuleFiringRecord", "Custom evaluator returns false."); 
                        return false;
                    } 
#if (!DBG)
                }
                catch {
                    Debug.Trace("RuleFiringRecord", "Hit an exception when calling Custom evaluator"); 
                    // Return if we hit an error
                    return false; 
                } 
#endif
            } 

            if (timesRaised < _ruleInfo._minInstances) {
                Debug.Trace("RuleFiringRecord",
                        "MinInterval not met; timesRaised=" + timesRaised + 
                        "; _minInstances=" + _ruleInfo._minInstances);
                return false; 
            } 

            if (timesRaised > _ruleInfo._maxLimit) { 
                Debug.Trace("RuleFiringRecord",
                        "MaxLimit exceeded; timesRaised=" + timesRaised +
                        "; _maxLimit=" + _ruleInfo._maxLimit);
                return false; 
            }
 
            // Last step: Check MinInterval and update _lastFired 

            if (_ruleInfo._minInterval == TimeSpan.Zero) { 
                UpdateLastFired(now, false);
                return true;
            }
 
            if ((now - _lastFired) <= _ruleInfo._minInterval) {
                Debug.Trace("RuleFiringRecord", 
                        "MinInterval not met; now=" + now + 
                        "; _lastFired=" + _lastFired +
                        "; _ruleInfo._minInterval=" + _ruleInfo._minInterval); 
                return false;
            }

            // The lock is to prevent multiple threads from passing the 
            // same test simultaneously.
            lock (this) { 
                if ((now - _lastFired) <= _ruleInfo._minInterval) { 
                    Debug.Trace("RuleFiringRecord",
                            "MinInterval not met; now=" + now + 
                            "; _lastFired=" + _lastFired +
                            "; _ruleInfo._tsMinInterval=" + _ruleInfo._minInterval);
                    return false;
                } 

                UpdateLastFired(now, true); 
                return true; 
            }
        } 

    }

    internal class HealthMonitoringManager { 
        internal HealthMonitoringSectionHelper          _sectionHelper;
        internal bool           _enabled = false; 
 
        static Timer            s_heartbeatTimer = null;
        static HealthMonitoringManager s_manager = null; 
        static bool             s_inited = false;
        static bool             s_initing = false;
        static object           s_lockObject = new object();
 
        // If this method returns null, it means we failed during configuration.
        internal static HealthMonitoringManager Manager() { 
 
            if (s_initing) {
                Debug.Assert(!s_inited); 
                // If this is true, that means we are calling WebEventBase.Raise while
                // we are initializing.  That means Init() has caused a config exception.
                return null;
            } 

            if (s_inited) { 
                return s_manager; 
            }
 
            lock (s_lockObject) {
                if (s_inited) {
                    return s_manager;
                } 

                try { 
                    Debug.Assert(s_manager == null); 
                    s_initing = true;
                    s_manager = new HealthMonitoringManager();; 
                }
                finally {
                    s_initing = false;
                    s_inited = true; 
                }
            } 
 
            return s_manager;
        } 

        internal static bool Enabled {
            get {
                HealthMonitoringManager manager = HealthMonitoringManager.Manager(); 
                if (manager == null) {
                    return false; 
                } 

                return manager._enabled; 
            }
        }

        internal static void StartHealthMonitoringHeartbeat() { 
            HealthMonitoringManager manager = Manager();
            if (manager == null) { 
                Debug.Trace( 
                    "HealthMonitoringManager", "Can't fire heartbeat because we cannot configure HealthMon");
                return; 
            }

            if (!manager._enabled) {
                Debug.Trace( 
                    "WebEventRaiseDetails", "Can't fire heartbeat because we are disabled");
                return; 
            } 

            manager.StartHeartbeatTimer(); 
        }

        private HealthMonitoringManager() {
            _sectionHelper = HealthMonitoringSectionHelper.GetHelper(); 

            _enabled = _sectionHelper.Enabled; 
 
            if (!_enabled) {
                return; 
            }
        }

        internal static void Shutdown() { 
            WebEventManager.Shutdown();
            Dispose(); 
        } 

        internal static void Dispose() { 
            // Make sure this function won't throw
            try {
                if (s_heartbeatTimer != null) {
                    s_heartbeatTimer.Dispose(); 
                    s_heartbeatTimer = null;
                } 
            } 
            catch {
            } 
        }

        internal void HeartbeatCallback(object state) {
            Debug.Assert(HealthMonitoringManager.Enabled); 
            WebBaseEvent.RaiseSystemEvent(null, WebEventCodes.ApplicationHeartbeat);
        } 
 
        internal void StartHeartbeatTimer() {
            TimeSpan interval = _sectionHelper.HealthMonitoringSection.HeartbeatInterval; 

            if (interval == TimeSpan.Zero) {
                return;
            } 

#if DBG 
            if (!Debug.IsTagPresent("Timer") || Debug.IsTagEnabled("Timer")) 
#endif
            { 
                s_heartbeatTimer = new Timer(new TimerCallback(this.HeartbeatCallback), null,
                    TimeSpan.Zero, interval);
            }
        } 

        internal static HealthMonitoringSectionHelper.ProviderInstances ProviderInstances { 
            get { 
                HealthMonitoringManager manager = Manager();
 
                if (manager == null) {
                    return null;
                }
 
                if (!manager._enabled) {
                    return null; 
                } 

                return manager._sectionHelper._providerInstances; 
            }
        }
    }
 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public sealed class WebBaseEventCollection : ReadOnlyCollectionBase 
    {
        public WebBaseEventCollection(ICollection events) { 
            if (events == null) {
                throw new ArgumentNullException("events");
            }
 
            foreach (WebBaseEvent eventRaised in events) {
                InnerList.Add(eventRaised); 
            } 
        }
 
        internal WebBaseEventCollection(WebBaseEvent eventRaised) {
            if (eventRaised == null) {
                throw new ArgumentNullException("eventRaised");
            } 

            InnerList.Add(eventRaised); 
        } 

        // overloaded collection access methods 
        public WebBaseEvent this[int index] {
            get {
                return (WebBaseEvent) InnerList[index];
            } 
        }
 
        public int IndexOf(WebBaseEvent value) { 
            return InnerList.IndexOf(value);
        } 

        public bool Contains(WebBaseEvent value) {
            return InnerList.Contains(value);
        } 
    }
 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public static class WebEventManager
    { 

        [SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
        public static void Flush(string providerName) {
            HealthMonitoringSectionHelper.ProviderInstances   providers = HealthMonitoringManager.ProviderInstances; 

            if (providers == null) { 
                return; 
            }
 
            if (!providers.ContainsKey(providerName)) {
                throw new ArgumentException(SR.GetString(SR.Health_mon_provider_not_found, providerName));
            }
 
            using (new ApplicationImpersonationContext()) {
                providers[providerName].Flush(); 
            } 
        }
 
        [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        [SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
        public static void Flush() {
            HealthMonitoringSectionHelper.ProviderInstances providers = HealthMonitoringManager.ProviderInstances; 

            if (providers == null) { 
                return; 
            }
 
            using (new ApplicationImpersonationContext()) {
                foreach(DictionaryEntry de in providers) {
                    WebEventProvider    provider = (WebEventProvider)de.Value;
 
                    Debug.Trace("WebEventManager", "Flushing provider " + provider.Name);
                    provider.Flush(); 
                } 
            }
        } 

        internal static void Shutdown() {
            HealthMonitoringSectionHelper.ProviderInstances   providers = HealthMonitoringManager.ProviderInstances;
 
            if (providers == null) {
                return; 
            } 

            foreach(DictionaryEntry de in providers) { 
                WebEventProvider    provider = (WebEventProvider)de.Value;

                Debug.Trace("WebEventManager", "Shutting down provider " + provider.Name);
                provider.Shutdown(); 
            }
        } 
    } 

} 


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