private string GetCurrentFilePath(TraceEventCache eventCache)
        {
            var result = StringTemplate.Format(CultureInfo.CurrentCulture, FilePathTemplate,
                                               delegate(string name, out object value)
            {
                switch (name.ToUpperInvariant())
                {
                case "ACTIVITYID":
                    value = Trace.CorrelationManager.ActivityId;
                    break;

                case "APPDATA":
                    value = traceFormatter.HttpTraceContext.AppDataPath;
                    break;

                case "APPDOMAIN":
                    value = AppDomain.CurrentDomain.FriendlyName;
                    break;

                case "APPLICATIONNAME":
                    value = traceFormatter.FormatApplicationName();
                    break;

                case "DATETIME":
                case "UTCDATETIME":
                    value = TraceFormatter.FormatUniversalTime(eventCache);
                    break;

                case "LOCALDATETIME":
                    value = TraceFormatter.FormatLocalTime(eventCache);
                    break;

                case "MACHINENAME":
                    value = Environment.MachineName;
                    break;

                case "PROCESSID":
                    value = traceFormatter.FormatProcessId(eventCache);
                    break;

                case "PROCESSNAME":
                    value = traceFormatter.FormatProcessName();
                    break;

                case "USER":
                    value = Environment.UserDomainName + "-" + Environment.UserName;
                    break;

                default:
                    value = "{" + name + "}";
                    return(true);
                }
                return(true);
            });

            return(result);
        }
        protected override void WriteTrace(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message, Guid?relatedActivityId, object[] data)
        {
            var  traceTime  = TraceFormatter.FormatUniversalTime(eventCache);
            int  maxPerHour = MaxTracesPerHour;
            bool sendEmail  = false;

            if (maxPerHour > 0)
            {
                lock (floodLimitLock)
                {
                    if (traceTime > floodLimitReset)
                    {
                        // start a new flood limit
                        floodLimitReset     = traceTime.Add(floodLimitWindow);
                        floodNumberOfTraces = 0;
                    }
                    if (floodNumberOfTraces < maxPerHour)
                    {
                        floodNumberOfTraces++;
                        sendEmail = true;
                    }
                }
            }
            else
            {
                sendEmail = true;
            }

            if (sendEmail)
            {
                string subject = traceFormatter.Format(SubjectTemplate, this, eventCache, source,
                                                       eventType, id, message, relatedActivityId, data);

                string body = traceFormatter.Format(BodyTemplate, this, eventCache, source, eventType, id,
                                                    message, relatedActivityId, data);

                // Use hidden/undocumented attribute to switch versions (for testing)
                if (Attributes["poolVersion"] == "B")
                {
                    SmtpWorkerPoolB.BeginSend(FromAddress, ToAddress, subject, body, null, null);
                    return;
                }
                SmtpWorkerPoolC.BeginSend(FromAddress, ToAddress, subject, body, null, null);
            }
            else
            {
                Debug.WriteLine("Dropped message due to flood protection.");
            }
        }