internal override void Process(ProfilerSession sess)
        {
            Tracing.PacketTrace("CALLS: Function returned on thread {0}", sess.m_currentThreadPID);

            if (sess.m_threadCallStacks.ContainsKey(sess.m_currentThreadPID))
            {
                Debug.Assert(sess.m_threadCallStacks[sess.m_currentThreadPID].Count > 0);
                sess.m_threadCallStacks[sess.m_currentThreadPID].Pop();
            }

            FunctionReturn f = new FunctionReturn();
            f.m_thread = sess.m_currentThreadPID;
            f.duration = m_duration;
            sess.AddEvent(f);
        }
        private void ProcessEvent(_PRF.ProfilerSession ps, _PRF.ProfilerEvent pe)
        {
            switch (pe.Type)
            {
            case _PRF.ProfilerEvent.EventType.Call:
            {
                _PRF.FunctionCall f = (_PRF.FunctionCall)pe;
                m_currentThread = f.m_thread;

                ThreadState ts;
                if (m_htThreads.ContainsKey(m_currentThread))
                {
                    ts = m_htThreads[m_currentThread];
                }
                else
                {
                    ts                      = new ThreadState();
                    ts.m_threadID           = f.m_thread;
                    m_htThreads[f.m_thread] = ts;
                }

                Call c = new Call();
                c.Function = f.m_callStack[f.m_callStack.Length - 1];

                try
                {
                    m_sess.m_engine.GetMethodName(c.Function, true);
                }
                catch { }

                ts.m_call.AddChild(c);
                ts.m_call = c;
                break;
            }

            case _PRF.ProfilerEvent.EventType.Return:
            {
                _PRF.FunctionReturn f = (_PRF.FunctionReturn)pe;
                ThreadState         ts;
                if (m_htThreads.ContainsKey(m_currentThread))
                {
                    ts = m_htThreads[m_currentThread];
                }
                else
                {
                    ts                      = new ThreadState();
                    ts.m_threadID           = f.m_thread;
                    m_htThreads[f.m_thread] = ts;
                }

                if ((f.duration & 0x80000000) == 0)
                {
                    //OffView really really doesn't like negative times.
                    ts.m_call.Duration += f.duration;
                }

                if (ts.m_call.Parent != null)
                {
                    //Make timing inclusive.
                    ts.m_call.Parent.Duration += ts.m_call.Duration;
                }
                ts.m_call = ts.m_call.Parent;
                break;
            }

            case _PRF.ProfilerEvent.EventType.ContextSwitch:
            {
                _PRF.ContextSwitch c = (_PRF.ContextSwitch)pe;
                m_currentThread = c.m_thread;
                break;
            }
            }
        }