/** Gets the completions at the passed offset. */
    public ICompletionProposal[] getCompletions(String text, String actTok, int offset)
        throws Exception {
      this.text = text;
      this.actTok = actTok;
      this.offset = offset;
      PyStackFrame stackFrame = getCurrentSuspendedPyStackFrame(null);

      if (stackFrame != null) {
        AbstractDebugTarget target =
            (AbstractDebugTarget) stackFrame.getAdapter(IDebugTarget.class);
        if (target != null) {
          GetCompletionsCommand cmd =
              new GetCompletionsCommand(
                  target, actTok, stackFrame.getLocalsLocator().getPyDBLocation());
          cmd.setCompletionListener(this);
          target.postCommand(cmd);
        }
        return waitForCommand();
      }
      return EMPTY_COMPLETION_PROPOSALS;
    }
  /**
   * @return the currently selected / suspended frame. If the console is passed, it will only return
   *     a frame that matches the passed console. If no selected / suspended frame is found or the
   *     console doesn't match, null is returned.
   */
  protected static PyStackFrame getCurrentSuspendedPyStackFrame(IConsole console) {
    IAdaptable context = DebugUITools.getDebugContext();

    if (context instanceof PyStackFrame) {
      PyStackFrame stackFrame = (PyStackFrame) context;
      if (!stackFrame.isTerminated() && stackFrame.isSuspended()) {
        if (console != null) {
          // If a console is passed, we must check if it matches the console from the selected
          // frame.
          AbstractDebugTarget target =
              (AbstractDebugTarget) stackFrame.getAdapter(IDebugTarget.class);
          if (DebugUITools.getConsole(target.getProcess()) != console) {
            return null;
          }
        }

        return stackFrame;
      }
    }
    return null;
  }