'Constructor for the Flow Runner.
Args:
flow_obj: The flow object this runner will run states for.
parent_runner: The parent runner of this runner.
runner_args: A FlowRunnerArgs() instance containing initial values. If not
specified, we use the runner_args from the flow_obj.
token: An instance of access_control.ACLToken security token.'

def __init__(self, flow_obj, parent_runner=None, runner_args=None, token=None):

    self.token = (token or flow_obj.token)
    self.parent_runner = parent_runner
    if (parent_runner is not None):
        self.queue_manager = parent_runner.queue_manager
    else:
        self.queue_manager = queue_manager.QueueManager(token=self.token)
    self.queued_replies = []
    self.outbound_lock = threading.Lock()
    self.flow_obj = flow_obj
    if (runner_args is not None):
        self.runner_args = runner_args
        self.session_id = self.GetNewSessionID()
        self.flow_obj.urn = self.session_id
        self.context = self.InitializeContext(runner_args)
        self.flow_obj.context = self.context
        self.context.session_id = self.session_id
    else:
        self.context = self.flow_obj.context
        self.runner_args = self.flow_obj.runner_args
    self.flow_obj.urn = self.session_id = self.context.session_id
    self.sent_replies = []
