/// <summary>
        /// Gets one frame.
        /// </summary>
        private EventFrame GetFrame(DateTime time, int core, IEnumerable<ContextSwitch> switches)
        {
            // We got some events, calculate the proportion
            var fileTime = time.ToFileTime();
            var process  = this.Process.ProcessID;
            var maxTime  = (double)(this.Interval.TotalMilliseconds * 10000);

            // Construct a new frame
            var frame = new EventFrame(time, this.Interval, core);
            var previous = 0L;

            foreach (var sw in switches)
            {
                // Old thread id & process id
                var oldThread = EventThread.FromTrace(sw.OldThreadId, sw.OldProcessId, this.Process);
                var newThread = EventThread.FromTrace(sw.NewThreadId, sw.NewProcessId, this.Process);
                var state = sw.State;

                // Set the time
                var current = sw.TimeStamp100ns - fileTime;
                var elapsed = current - previous;
                previous = current;

                // What's the current running thread?
                this.LookupLastSwitch[core] = sw;

                // How much time a thread switching in spent switched out?
                var lastSwitchOut = this.LookupSwitchByThread[sw.NewThreadId]
                    .Where(cs => cs.OldProcessId == sw.NewProcessId)
                    .Where(cs => cs.TimeStamp100ns >= fileTime && cs.TimeStamp100ns < sw.TimeStamp100ns)
                    .LastOrDefault();

                // We didn't find it in our interval, find the absolute last
                if(lastSwitchOut == null)
                {
                    lastSwitchOut = this.LookupSwitchByThread[sw.NewThreadId]
                        .Where(cs => cs.OldProcessId == sw.NewProcessId)
                        .Where(cs => cs.TimeStamp100ns < sw.TimeStamp100ns)
                        .LastOrDefault();
                }

                if (lastSwitchOut != null)
                {
                    var switchOutTime = Math.Min((double)(sw.TimeStamp100ns - lastSwitchOut.TimeStamp100ns), maxTime);
                    switch(lastSwitchOut.State)
                    {
                        case ThreadState.Wait:
                        case ThreadState.Ready:
                        case ThreadState.Standby:
                            frame.IncrementTime(newThread, lastSwitchOut.State, switchOutTime);
                            break;
                    }
                }

                // Add to our frame
                frame.IncrementTime(oldThread, ThreadState.Running, elapsed);

                // Increment on-core time
                frame.IncrementOnCoreTime(oldThread, elapsed);
            }

            // If there was no switches during this period of time, take the last running
            if (frame.Total == 0)
            {
                var sw = this.LookupLastSwitch[core];
                var thread = EventThread.FromTrace(sw.NewThreadId, sw.NewProcessId, this.Process);

                // Add to our frame
                frame.IncrementTime(thread, ThreadState.Running, maxTime);

                // Increment on-core time
                frame.IncrementOnCoreTime(thread, maxTime);
            }

            // Get corresponding hardware counters
            frame.HwCounters = this.GetCounters(core, time, time + this.Interval);

            // Get the page faults within this frame
            frame.PageFaults = this.GetPageFaults(core, time, time + this.Interval);

            return frame;
        }
 /// <summary>
 /// Adds a single event entry to the output.
 /// </summary>
 /// <param name="type">The type of the event.</param>
 /// <param name="frame">The frame of the event.</param>
 /// <param name="thread">The specific thread.</param>
 /// <param name="core">The processor number of the event.</param>
 /// <param name="value">The measured value of the event.</param>
 public void Add(string type, EventFrame frame, EventThread thread, double value)
 {
     this.Add(type, thread.Process, thread.User, frame.Time, value, thread.Tid, thread.Pid, frame.Core, thread.Uid);
 }
        /// <summary>
        /// Gets one frame.
        /// </summary>
        private EventFrame GetFrame(DateTime time, int core, IEnumerable <ContextSwitch> switches)
        {
            // We got some events, calculate the proportion
            var fileTime = time.ToFileTime();
            var process  = this.Process.ProcessID;
            var maxTime  = (double)(this.Interval.TotalMilliseconds * 10000);

            // Construct a new frame
            var frame    = new EventFrame(time, this.Interval, core);
            var previous = 0L;



            foreach (var sw in switches)
            {
                // Old thread id & process id
                var oldThread = EventThread.FromTrace(sw.OldThreadId, sw.OldProcessId, this.Process);
                var newThread = EventThread.FromTrace(sw.NewThreadId, sw.NewProcessId, this.Process);
                var state     = sw.State;

                // Set the time
                var current = sw.TimeStamp100ns - fileTime;
                var elapsed = current - previous;
                previous = current;

                // What's the current running thread?
                this.LookupLastSwitch[core] = sw;

                // How much time a thread switching in spent switched out?
                var lastSwitchOut = this.LookupSwitchByThread[sw.NewThreadId]
                                    .Where(cs => cs.OldProcessId == sw.NewProcessId)
                                    .Where(cs => cs.TimeStamp100ns >= fileTime && cs.TimeStamp100ns < sw.TimeStamp100ns)
                                    .LastOrDefault();

                // We didn't find it in our interval, find the absolute last
                if (lastSwitchOut == null)
                {
                    lastSwitchOut = this.LookupSwitchByThread[sw.NewThreadId]
                                    .Where(cs => cs.OldProcessId == sw.NewProcessId)
                                    .Where(cs => cs.TimeStamp100ns < sw.TimeStamp100ns)
                                    .LastOrDefault();
                }

                if (lastSwitchOut != null)
                {
                    var switchOutTime = Math.Min((double)(sw.TimeStamp100ns - lastSwitchOut.TimeStamp100ns), maxTime);
                    switch (lastSwitchOut.State)
                    {
                    case ThreadState.Wait:
                    case ThreadState.Ready:
                    case ThreadState.Standby:
                        frame.IncrementTime(newThread, lastSwitchOut.State, switchOutTime);
                        break;
                    }
                }

                // Add to our frame
                frame.IncrementTime(oldThread, ThreadState.Running, elapsed);

                // Increment on-core time
                frame.IncrementOnCoreTime(oldThread, elapsed);
            }

            // If there was no switches during this period of time, take the last running
            if (frame.Total == 0)
            {
                var sw     = this.LookupLastSwitch[core];
                var thread = EventThread.FromTrace(sw.NewThreadId, sw.NewProcessId, this.Process);

                // Add to our frame
                frame.IncrementTime(thread, ThreadState.Running, maxTime);

                // Increment on-core time
                frame.IncrementOnCoreTime(thread, maxTime);
            }


            // Get corresponding hardware counters
            frame.HwCounters = this.GetCounters(core, time, time + this.Interval);

            // Get the page faults within this frame
            frame.PageFaults = this.GetPageFaults(core, time, time + this.Interval);

            return(frame);
        }