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

    public CLangDebuggeeBreakpointError (CLangDebugger debugger, DebugBreakpointManager breakpointManager, DebuggeeBreakpointPending pendingBreakpoint, DebuggeeCodeContext codeContext, MiBreakpoint gdbBreakpoint, string error)
      : base (breakpointManager, pendingBreakpoint, codeContext, error)
    {
      m_debugger = debugger;

      GdbBreakpoint = gdbBreakpoint;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public CLangDebuggeeBreakpointBound (CLangDebugger debugger, DebugBreakpointManager breakpointManager, DebuggeeBreakpointPending pendingBreakpoint, DebuggeeCodeContext codeContext, MiBreakpoint gdbBreakpoint)
      : base (breakpointManager, pendingBreakpoint, codeContext)
    {
      m_debugger = debugger;

      GdbBreakpoint = gdbBreakpoint;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int SetCodeContext (DebuggeeCodeContext codeContext)
    {
      LoggingUtils.PrintFunction ();

      m_codeContext = codeContext;

      return Constants.S_OK;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public CLangDebuggeeDisassemblyStream (CLangDebugger debugger, enum_DISASSEMBLY_STREAM_SCOPE streamScope, IDebugCodeContext2 codeContext)
    {
      m_debugger = debugger;

      m_streamScope = streamScope;

      m_codeContext = codeContext as DebuggeeCodeContext;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public DebuggeeBreakpointResolution (DebuggeeCodeContext codeContext, string message)
    {
      if (codeContext == null)
      {
        throw new ArgumentNullException ("codeContext");
      }

      m_codeContext = codeContext;

      m_resolutionMessage = message;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public DebuggeeDocumentContext (DebugEngine engine, string fileName, TEXT_POSITION beginPosition, TEXT_POSITION endPosition)
    {
      m_engine = engine;

      m_fileName = PathUtils.ConvertPathCygwinToWindows (fileName);

      m_beginPosition = beginPosition;

      m_endPosition = endPosition;

      m_codeContext = null;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public override int EvaluateBreakpointLocation (out DebuggeeDocumentContext documentContext, out DebuggeeCodeContext codeContext, out string location)
    {
      LoggingUtils.PrintFunction ();

      try
      {
        LoggingUtils.RequireOk (base.EvaluateBreakpointLocation (out documentContext, out codeContext, out location));

        /*switch (m_breakpointRequestInfo.bpLocation.bpLocationType)
        {
          case (uint) enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE:
          {
            codeContext = CLangDebuggeeCodeContext.GetCodeContextForLocation (m_debugger, location);

            if (codeContext == null)
            {
              throw new InvalidOperationException ();
            }

            documentContext = codeContext.DocumentContext;

            if (documentContext == null)
            {
              throw new InvalidOperationException ();
            }

            break;
          }

          default:
          {
            break;
          }
        }*/

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

        documentContext = null;

        codeContext = null;

        location = string.Empty;

        return Constants.E_FAIL;
      }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int CreateBoundBreakpoint (MiBreakpoint breakpoint, DebuggeeDocumentContext documentContext, DebuggeeCodeContext codeContext)
    {
      LoggingUtils.PrintFunction ();

      try
      {
        if (breakpoint == null)
        {
          throw new ArgumentNullException ("breakpoint");
        }

        if (breakpoint.IsPending ())
        {
          // 
          // Address can't be satisfied. Unsatisfied likely indicates the modules or symbols associated with the context aren't loaded, yet.
          // 

          DebuggeeAddress pendingAddress = new DebuggeeAddress (MiBreakpoint.Pending);

          DebuggeeCodeContext pendingContext = new CLangDebuggeeCodeContext (m_debugger, pendingAddress, documentContext);

          LoggingUtils.RequireOk (CreateErrorBreakpoint ("Additional library symbols required.", breakpoint, documentContext, pendingContext));
        }
        else if (breakpoint.IsMultiple ())
        {
          // 
          // Breakpoint satisfied to multiple locations, no single memory address available.
          // 

          CLangDebuggeeBreakpointBound boundBreakpoint = new CLangDebuggeeBreakpointBound (m_debugger, m_breakpointManager, this, codeContext, breakpoint);

          lock (m_boundBreakpoints)
          {
            m_boundBreakpoints.Clear ();

            m_boundBreakpoints.Add (boundBreakpoint);
          }

          m_debugger.Engine.Broadcast (new DebugEngineEvent.BreakpointBound (this, boundBreakpoint), m_debugger.NativeProgram.DebugProgram, m_debugger.NativeProgram.GetThread (m_debugger.NativeProgram.CurrentThreadId));
        }
        else
        {
          // 
          // Address satisfied, and the breakpoint is legitimately bound.
          // 

          DebuggeeAddress boundAddress = new DebuggeeAddress (breakpoint.Address);

          DebuggeeCodeContext addressContext = new CLangDebuggeeCodeContext (m_debugger, boundAddress, documentContext);

          CLangDebuggeeBreakpointBound boundBreakpoint = new CLangDebuggeeBreakpointBound (m_debugger, m_breakpointManager, this, addressContext, breakpoint);

          lock (m_boundBreakpoints)
          {
            m_boundBreakpoints.Clear ();

            m_boundBreakpoints.Add (boundBreakpoint);
          }

          m_debugger.Engine.Broadcast (new DebugEngineEvent.BreakpointBound (this, boundBreakpoint), m_debugger.NativeProgram.DebugProgram, m_debugger.NativeProgram.GetThread (m_debugger.NativeProgram.CurrentThreadId));
        }

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

        return Constants.E_FAIL;
      }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int CreateErrorBreakpoint (string errorReason, MiBreakpoint gdbBreakpoint, DebuggeeDocumentContext documentContext, DebuggeeCodeContext codeContext)
    {
      // 
      // Create a C-language breakpoint. This is tied to a GDB/MI breakpoint object.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        CLangDebuggeeBreakpointError errorBreakpoint = new CLangDebuggeeBreakpointError (m_debugger, m_breakpointManager, this, codeContext, gdbBreakpoint, errorReason);

        lock (m_errorBreakpoints)
        {
          m_errorBreakpoints.Clear ();

          m_errorBreakpoints.Add (errorBreakpoint);
        }

        uint numDebugPrograms = 1;

        IEnumDebugPrograms2 debugPrograms;

        IDebugProgram2 [] debugProgramsArray = new IDebugProgram2 [numDebugPrograms];

        LoggingUtils.RequireOk (m_breakpointManager.Engine.EnumPrograms (out debugPrograms));

        LoggingUtils.RequireOk (debugPrograms.Next (numDebugPrograms, debugProgramsArray, ref numDebugPrograms));

        m_breakpointManager.Engine.Broadcast (new DebugEngineEvent.BreakpointError (errorBreakpoint), debugProgramsArray [0], null);

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

        return Constants.E_FAIL;
      }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public override int CreateBoundBreakpoint (string location, DebuggeeDocumentContext documentContext, DebuggeeCodeContext codeContext)
    {
      // 
      // Register a new GDB breakpoint.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        if (m_breakpointRequestInfo.bpLocation.bpLocationType == (uint)enum_BP_TYPE.BPT_DATA)
        {
          throw new NotImplementedException ();
        }

        m_debugger.RunInterruptOperation (delegate (CLangDebugger debugger)
        {
          string command = string.Format ("-break-insert -f {0} {1}", ((m_breakpointEnabled) ? "" : "-d"), PathUtils.SantiseWindowsPath (location));

          debugger.GdbClient.SendCommand (command, delegate (MiResultRecord resultRecord)
          {
            if (resultRecord != null)
            {
              if (resultRecord.IsError ())
              {
                string errorReason = "<unknown error>";

                if (resultRecord.HasField ("msg"))
                {
                  errorReason = resultRecord ["msg"] [0].GetString ();
                }

                LoggingUtils.RequireOk (CreateErrorBreakpoint (errorReason, documentContext, codeContext));
              }
              else
              {
                MiResultValue breakpointData = resultRecord ["bkpt"] [0];

                MiBreakpoint breakpoint = new MiBreakpoint (breakpointData.Values);

                LoggingUtils.RequireOk (CreateBoundBreakpoint (breakpoint, documentContext, codeContext));
              }
            }
          });
        });

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

        return Constants.E_FAIL;
      }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int EnumCodeContexts (IDebugDocumentPosition2 pDocPos, out IEnumDebugCodeContexts2 ppEnum)
    {
      // 
      // Enumerates the code contexts for a given position in a source file.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        string fileName;

        TEXT_POSITION [] startPos = new TEXT_POSITION [1];

        TEXT_POSITION [] endPos = new TEXT_POSITION [1];

        LoggingUtils.RequireOk (pDocPos.GetFileName (out fileName));

        LoggingUtils.RequireOk (pDocPos.GetRange (startPos, endPos));

        string location = string.Format ("\"{0}:{1}\"", fileName, startPos [0].dwLine + 1);

        DebuggeeCodeContext codeContext = m_debugger.GetCodeContextForLocation (location);

        if (codeContext == null)
        {
          throw new InvalidOperationException ("Failed evaluating code-context for location.");
        }

        DebuggeeCodeContext [] codeContexts = new DebuggeeCodeContext [] { codeContext };

        ppEnum = new DebuggeeCodeContext.Enumerator (codeContexts);

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

        ppEnum = null;

        return Constants.E_FAIL;
      }
    }