def do_wait_suspend(self, thread, frame, event, arg, suspend_type="trace", send_suspend_message=True): #@UnusedVariable
        """ busy waits until the thread state changes to RUN
        it expects thread's state as attributes of the thread.
        Upon running, processes any outstanding Stepping commands.
        """
        self.process_internal_commands()
        thread_stack_str = ''   # @UnusedVariable -- this is here so that `make_get_thread_stack_message`
                                # can retrieve it later.
        
        if send_suspend_message:
            message = thread.additional_info.pydev_message
            cmd = self.cmd_factory.make_thread_suspend_message(get_thread_id(thread), frame, thread.stop_reason, message, suspend_type)
            thread_stack_str = cmd.thread_stack_str
            self.writer.add_command(cmd)

        with CustomFramesContainer.custom_frames_lock:  # @UndefinedVariable
            from_this_thread = []

            for frame_id, custom_frame in dict_iter_items(CustomFramesContainer.custom_frames):
                if custom_frame.thread_id == thread.ident:
                    # print >> sys.stderr, 'Frame created: ', frame_id
                    self.writer.add_command(self.cmd_factory.make_custom_frame_created_message(frame_id, custom_frame.name))
                    self.writer.add_command(self.cmd_factory.make_thread_suspend_message(frame_id, custom_frame.frame, CMD_THREAD_SUSPEND, "", suspend_type))

                from_this_thread.append(frame_id)

        info = thread.additional_info

        if info.pydev_state == STATE_SUSPEND and not self._finish_debugging_session:
            # before every stop check if matplotlib modules were imported inside script code
            self._activate_mpl_if_needed()

        while info.pydev_state == STATE_SUSPEND and not self._finish_debugging_session:
            if self.mpl_in_use:
                # call input hooks if only matplotlib is in use
                self._call_mpl_hook()

            self.process_internal_commands()
            time.sleep(0.01)

        self.cancel_async_evaluation(get_thread_id(thread), str(id(frame)))

        # process any stepping instructions
        if info.pydev_step_cmd == CMD_STEP_INTO or info.pydev_step_cmd == CMD_STEP_INTO_MY_CODE:
            info.pydev_step_stop = None
            info.pydev_smart_step_stop = None

        elif info.pydev_step_cmd == CMD_STEP_OVER:
            info.pydev_step_stop = frame
            info.pydev_smart_step_stop = None
            self.set_trace_for_frame_and_parents(frame)

        elif info.pydev_step_cmd == CMD_SMART_STEP_INTO:
            self.set_trace_for_frame_and_parents(frame)
            info.pydev_step_stop = None
            info.pydev_smart_step_stop = frame

        elif info.pydev_step_cmd == CMD_RUN_TO_LINE or info.pydev_step_cmd == CMD_SET_NEXT_STATEMENT:
            self.set_trace_for_frame_and_parents(frame)
            stop = False
            response_msg = ""
            try:
                stop, old_line, response_msg = self.set_next_statement(frame, event, info.pydev_func_name, info.pydev_next_line)
            except ValueError as e:
                response_msg = "%s" % e
            finally:
                if IS_PYCHARM:
                    seq = info.pydev_message
                    cmd = self.cmd_factory.make_set_next_stmnt_status_message(seq, stop, response_msg)
                    self.writer.add_command(cmd)
                    info.pydev_message = ''

            if stop:
                cmd = self.cmd_factory.make_thread_run_message(get_thread_id(thread), info.pydev_step_cmd)
                self.writer.add_command(cmd)
                if suspend_type == "trace":
                    info.pydev_state = STATE_SUSPEND
                    thread.stop_reason= CMD_SET_NEXT_STATEMENT
                    self.do_wait_suspend(thread, frame, event, arg, "trace")
                else:
                    info.pydev_step_stop = frame
                return
            else:
                info.pydev_step_cmd = -1
                info.pydev_state = STATE_SUSPEND
                thread.stop_reason = CMD_THREAD_SUSPEND
                # return to the suspend state and wait for other command
                self.do_wait_suspend(thread, frame, event, arg, suspend_type, send_suspend_message=False)
                return

        elif info.pydev_step_cmd == CMD_STEP_RETURN:
            back_frame = frame.f_back
            if back_frame is not None:
                # steps back to the same frame (in a return call it will stop in the 'back frame' for the user)
                info.pydev_step_stop = frame
                self.set_trace_for_frame_and_parents(frame)
            else:
                # No back frame?!? -- this happens in jython when we have some frame created from an awt event
                # (the previous frame would be the awt event, but this doesn't make part of 'jython', only 'java')
                # so, if we're doing a step return in this situation, it's the same as just making it run
                info.pydev_step_stop = None
                info.pydev_step_cmd = -1
                info.pydev_state = STATE_RUN

        if self.frame_eval_func is not None and info.pydev_state == STATE_RUN:
            if info.pydev_step_cmd == -1:
                if not self.do_not_use_frame_eval:
                    self.SetTrace(self.dummy_trace_dispatch)
                    self.set_trace_for_frame_and_parents(frame, overwrite_prev_trace=True, dispatch_func=dummy_trace_dispatch)
            else:
                self.set_trace_for_frame_and_parents(frame, overwrite_prev_trace=True)
                # enable old tracing function for stepping
                self.SetTrace(self.trace_dispatch)

        del frame
        cmd = self.cmd_factory.make_thread_run_message(get_thread_id(thread), info.pydev_step_cmd)
        self.writer.add_command(cmd)

        CustomFramesContainer.custom_frames_lock.acquire()  # @UndefinedVariable
        try:
            # The ones that remained on last_running must now be removed.
            for frame_id in from_this_thread:
                # print >> sys.stderr, 'Removing created frame: ', frame_id
                self.writer.add_command(self.cmd_factory.make_thread_killed_message(frame_id))

        finally:
            CustomFramesContainer.custom_frames_lock.release()  # @UndefinedVariable
 busy waits until the thread state changes to RUN
        it expects thread's state as attributes of the thread.
        Upon running, processes any outstanding Stepping commands.
        
debugger/src/pydevd.py