<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def stop(self, actor, exc=None, exit_code=None):
 """Gracefully stop the ``actor``. """

        if actor.state <= ACTOR_STATES.RUN:
            # The actor has not started the stopping process. Starts it now.
            actor.state = ACTOR_STATES.STOPPING
            actor.event('start').clear()
            if exc:
                if not exit_code:
                    exit_code = getattr(exc, 'exit_code', 1)
                if exit_code == 1:
                    exc_info = sys.exc_info()
                    if exc_info[0] is not None:
                        actor.logger.critical('Stopping', exc_info=exc_info)
                    else:
                        actor.logger.critical('Stopping: %s', exc)
                elif exit_code == 2:
                    actor.logger.error(str(exc))
                elif exit_code:
                    actor.stream.writeln(str(exc))
            else:
                if not exit_code:
                    exit_code = getattr(actor._loop, 'exit_code', 0)
            #
            # Fire stopping event
            actor.exit_code = exit_code
            actor.stopping_waiters = []
            actor.event('stopping').fire()

            if actor.stopping_waiters and actor._loop.is_running():
                actor.logger.info('asynchronous stopping')
                # make sure to return the future (used by arbiter for waiting)
                return actor._loop.create_task(self._async_stopping(actor))
            else:
                if actor.logger:
                    actor.logger.info('stopping')
                self._stop_actor(actor)

        elif actor.stopped():
            return self._stop_actor(actor, True)