// This method is called after the WaitForEvent is seen (usually the QueryEnd event)
        // This is where you can do any processing of the events before displaying them to the UI
        protected override void ProcessResults()
        {
            //if (IsPaused) return; // exit here if we are paused

            if (Events != null)
            {
                foreach (var traceEvent in Events)
                {
                    var newEvent = new QueryEvent()
                    {
                        QueryType         = traceEvent.EventSubclassName.Substring(0, 3).ToUpper(),
                        StartTime         = traceEvent.StartTime,
                        Username          = traceEvent.NTUserName,
                        Query             = traceEvent.TextData,
                        Duration          = traceEvent.Duration,
                        DatabaseName      = traceEvent.DatabaseFriendlyName,
                        RequestID         = traceEvent.RequestID,
                        RequestParameters = traceEvent.RequestParameters,
                        RequestProperties = traceEvent.RequestProperties
                    };

                    switch (traceEvent.EventClass)
                    {
                    case DaxStudioTraceEventClass.QueryEnd:

                        // if this is the blank query after a "clear cache and run" then skip it
                        if (newEvent.Query == Constants.RefreshSessionQuery)
                        {
                            continue;
                        }

                        // look for any cached rewrite events
                        if (traceEvent.RequestID != null && _rewriteEventCache.ContainsKey(traceEvent.RequestID))
                        {
                            var summary = _rewriteEventCache[traceEvent.RequestID];
                            newEvent.AggregationMatchCount = summary.MatchCount;
                            newEvent.AggregationMissCount  = summary.MissCount;
                            _rewriteEventCache.Remove(traceEvent.RequestID);
                        }

                        // TODO - update newEvent with queryBegin
                        QueryBeginEvent beginEvent = null;

                        _queryBeginCache.TryGetValue(traceEvent.RequestID ?? "", out beginEvent);
                        if (beginEvent != null)
                        {
                            // Add the parameters XML after the query text
                            if (beginEvent.RequestParameters != null)
                            {
                                newEvent.Query += Environment.NewLine +
                                                  Environment.NewLine +
                                                  beginEvent.RequestParameters +
                                                  Environment.NewLine;
                            }

                            // overwrite the username with the effective user if it's present
                            var effectiveUser = beginEvent.ParseEffectiveUsername();
                            if (!string.IsNullOrEmpty(effectiveUser))
                            {
                                newEvent.Username = effectiveUser;
                            }

                            _queryBeginCache.Remove(traceEvent.RequestID);
                        }



                        QueryEvents.Insert(0, newEvent);
                        break;

                    case DaxStudioTraceEventClass.AggregateTableRewriteQuery:
                        // cache rewrite events
                        var rewriteSummary = new AggregateRewriteSummary(traceEvent.RequestID, traceEvent.TextData);
                        if (_rewriteEventCache.ContainsKey(traceEvent.RequestID))
                        {
                            var summary = _rewriteEventCache[key : traceEvent.RequestID];
                            summary.MatchCount += rewriteSummary.MatchCount;
                            summary.MissCount  += rewriteSummary.MissCount;
                            _rewriteEventCache[key : traceEvent.RequestID] = summary;
                        }
                        else
                        {
                            _rewriteEventCache.Add(traceEvent.RequestID, rewriteSummary);
                        }

                        break;

                    case DaxStudioTraceEventClass.QueryBegin:

                        // if the requestID is null we are running against PowerPivot which does
                        // not seem to expose the RequestID property
                        if (traceEvent.RequestID == null)
                        {
                            break;
                        }

                        // cache rewrite events
                        if (_queryBeginCache.ContainsKey(traceEvent.RequestID))
                        {
                            // TODO - this should not happen
                            // we should not get 2 begin events for the same request
                        }
                        else
                        {
                            var newBeginEvent = new QueryBeginEvent()
                            {
                                RequestID         = traceEvent.RequestID,
                                Query             = traceEvent.TextData,
                                RequestProperties = traceEvent.RequestProperties,
                                RequestParameters = traceEvent.RequestParameters
                            };
                            _queryBeginCache.Add(traceEvent.RequestID, newBeginEvent);
                        }

                        break;
                    }
                }

                Events.Clear();

                // Clear out any cached rewrite events older than 10 minutes
                var toRemoveFromCache = _rewriteEventCache.Where((kvp) => kvp.Value.UtcCurrentTime > DateTime.UtcNow.AddMinutes(10)).Select(c => c.Key).ToList();
                foreach (var requestId in toRemoveFromCache)
                {
                    _rewriteEventCache.Remove(requestId);
                }

                NotifyOfPropertyChange(() => QueryEvents);
                NotifyOfPropertyChange(() => CanClearAll);
                NotifyOfPropertyChange(() => CanCopyAll);
                NotifyOfPropertyChange(() => CanExport);
            }
        }
        // This method is called after the WaitForEvent is seen (usually the QueryEnd event)
        // This is where you can do any processing of the events before displaying them to the UI
        protected override void ProcessResults()
        {
            //if (IsPaused) return; // exit here if we are paused

            if (Events != null)
            {
                foreach (var traceEvent in Events)
                {
                    var newEvent = new QueryEvent()
                    {
                        QueryType    = traceEvent.EventSubclassName.Substring(0, 3).ToUpper(),
                        StartTime    = traceEvent.StartTime,
                        Username     = traceEvent.NTUserName,
                        Query        = traceEvent.TextData,
                        Duration     = traceEvent.Duration,
                        DatabaseName = traceEvent.DatabaseFriendlyName,
                        RequestID    = traceEvent.RequestID
                    };

                    switch (traceEvent.EventClass)
                    {
                    case DaxStudioTraceEventClass.QueryEnd:
                        // look for any cached rewrite events
                        if (_rewriteEventCache.ContainsKey(traceEvent.RequestID))
                        {
                            var summary = _rewriteEventCache[traceEvent.RequestID];
                            newEvent.AggregationMatchCount = summary.MatchCount;
                            newEvent.AggregationMissCount  = summary.MissCount;
                            _rewriteEventCache.Remove(traceEvent.RequestID);
                        }
                        QueryEvents.Insert(0, newEvent);
                        break;

                    case DaxStudioTraceEventClass.AggregateTableRewriteQuery:
                        // cache rewrite events
                        var rewriteSummary = new AggregateRewriteSummary(traceEvent.RequestID, traceEvent.TextData);
                        if (_rewriteEventCache.ContainsKey(traceEvent.RequestID))
                        {
                            var summary = _rewriteEventCache[key : traceEvent.RequestID];
                            summary.MatchCount += rewriteSummary.MatchCount;
                            summary.MissCount  += rewriteSummary.MissCount;
                            _rewriteEventCache[key : traceEvent.RequestID] = summary;
                        }
                        else
                        {
                            _rewriteEventCache.Add(traceEvent.RequestID, rewriteSummary);
                        }

                        break;
                    }
                }

                Events.Clear();

                // Clear out any cached rewrite events older than 10 minutes
                var toRemoveFromCache = _rewriteEventCache.Where((kvp) => kvp.Value.UtcCurrentTime > DateTime.UtcNow.AddMinutes(10)).Select(c => c.Key).ToList();
                foreach (var requestId in toRemoveFromCache)
                {
                    _rewriteEventCache.Remove(requestId);
                }

                NotifyOfPropertyChange(() => QueryEvents);
                NotifyOfPropertyChange(() => CanClearAll);
                NotifyOfPropertyChange(() => CanCopyAll);
            }
        }