////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeExpression(DebugEngine engine, DebuggeeStackFrame stackFrame, string expression, uint radix)
        {
            m_debugEngine = engine;

            m_stackFrame = stackFrame;

            m_expression = expression;

            m_radix = radix;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeProperty(DebugEngine engine, DebuggeeStackFrame stackFrame, string expression, string value)
        {
            m_debugEngine = engine;

            m_stackFrame = stackFrame;

            if (string.IsNullOrEmpty(expression))
            {
                throw new ArgumentNullException(nameof(expression));
            }

            m_expression = expression;

            m_value = value;

            m_parent = null;

            m_children = new List <DebuggeeProperty> ();

            //
            // Compound parental expressions to evaluate this property's full identifier.
            //

            StringBuilder expressionBuilder = new StringBuilder(2048);

            DebuggeeProperty parent = m_parent;

            while (parent != null)
            {
                expressionBuilder.Append(parent.m_expression + ".");

                parent = parent.m_parent;
            }

            expressionBuilder.Append(m_expression);

            m_fullExpression = expressionBuilder.ToString();
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int GetThreadProperties(enum_THREADPROPERTY_FIELDS requestedFields, THREADPROPERTIES [] propertiesArray)
        {
            //
            // Gets properties that describe a thread.
            //

            LoggingUtils.PrintFunction();

            try
            {
                if ((requestedFields & enum_THREADPROPERTY_FIELDS.TPF_ID) != 0)
                {
                    propertiesArray [0].dwThreadId = m_threadId;

                    propertiesArray [0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_ID;
                }

                if ((requestedFields & enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT) != 0)
                {
                    propertiesArray [0].dwSuspendCount = m_threadSuspendCount;

                    propertiesArray [0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT;
                }

                if ((requestedFields & enum_THREADPROPERTY_FIELDS.TPF_STATE) != 0)
                {
                    if (m_threadRunning)
                    {
                        propertiesArray [0].dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_RUNNING;
                    }
                    else
                    {
                        propertiesArray [0].dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_STOPPED;
                    }

                    propertiesArray [0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_STATE;
                }

                if ((requestedFields & enum_THREADPROPERTY_FIELDS.TPF_PRIORITY) != 0)
                {
                    propertiesArray [0].bstrPriority = "<unknown priority>";

                    propertiesArray [0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_PRIORITY;
                }

                if ((requestedFields & enum_THREADPROPERTY_FIELDS.TPF_NAME) != 0)
                {
                    propertiesArray [0].bstrName = m_threadName;

                    propertiesArray [0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_NAME;
                }

                if ((requestedFields & enum_THREADPROPERTY_FIELDS.TPF_LOCATION) != 0)
                {
                    //
                    // The thread location (usually the topmost stack frame), typically expressed as the name of the method where execution is currently halted.
                    //

                    propertiesArray [0].bstrLocation = "[External Code]";

                    StackTrace(1); // single level depth

                    if (m_threadStackFrames.Count > 0)
                    {
                        DebuggeeStackFrame stackFrame = m_threadStackFrames [0];

                        FRAMEINFO frameInfo = new FRAMEINFO();

                        LoggingUtils.RequireOk(stackFrame.SetFrameInfo(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME, 0, ref frameInfo));

                        if (!string.IsNullOrEmpty(frameInfo.m_bstrFuncName))
                        {
                            propertiesArray [0].bstrLocation = frameInfo.m_bstrFuncName;
                        }
                    }

                    propertiesArray [0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_LOCATION;
                }

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int EnumCodePaths (string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety)
    {
      // 
      // Enumerates the code paths of this program.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        // 
        // Get the entire call-stack for the current thread, and enumerate.
        // 

        CLangDebuggeeStackFrame stackFrame = pFrame as CLangDebuggeeStackFrame;

        IDebugThread2 thread;

        LoggingUtils.RequireOk (stackFrame.GetThread (out thread));

        CLangDebuggeeThread stackFrameThread = thread as CLangDebuggeeThread;

        List<DebuggeeStackFrame> threadCallStack = stackFrameThread.StackTrace (uint.MaxValue);

        List <CODE_PATH> threadCodePaths = new List <CODE_PATH> ();

        for (int i = 0; i < threadCallStack.Count; ++i)
        {
          string frameName;

          IDebugCodeContext2 codeContext;

          DebuggeeStackFrame frame = threadCallStack [i] as DebuggeeStackFrame;

          LoggingUtils.RequireOk (frame.GetName (out frameName));

          LoggingUtils.RequireOk (frame.GetCodeContext (out codeContext));

          if (codeContext != null)
          {
            CODE_PATH codePath = new CODE_PATH ();

            codePath.bstrName = frameName;

            codePath.pCode = codeContext;

            threadCodePaths.Add (codePath);
          }
        }

        ppEnum = new DebuggeeProgram.EnumeratorCodePaths (threadCodePaths);

        ppSafety = null;

        return Constants.S_OK;
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);

        ppEnum = null;

        ppSafety = null;

        return Constants.E_FAIL;
      }
    }