docs: def run(self):
          """ This defines the sequence of actions that are taken when the barrier concurrency state is executed
  
          :return:
          """
          logger.debug("Starting execution of {0}{1}".format(self, " (backwards)" if self.backward_execution else ""))
          self.setup_run()
  
          # data to be accessed by the decider state
          child_errors = {}
          final_outcomes_dict = {}
          decider_state = self.states[UNIQUE_DECIDER_STATE_ID]
  
          try:
              concurrency_history_item = self.setup_forward_or_backward_execution()
              self.start_child_states(concurrency_history_item, decider_state)
  
              # print("bcs1")
  
              #######################################################
              # wait for all child threads to finish
              #######################################################
              for history_index, state in enumerate(self.states.values()):
                  # skip the decider state
                  if state is not decider_state:
                      self.join_state(state, history_index, concurrency_history_item)
                      self.add_state_execution_output_to_scoped_data(state.output_data, state)
                      self.update_scoped_variables_with_output_dictionary(state.output_data, state)
                      # save the errors of the child state executions for the decider state
                      if 'error' in state.output_data:
                          child_errors[state.state_id] = (state.name, state.output_data['error'])
                      final_outcomes_dict[state.state_id] = (state.name, state.final_outcome)
  
              # print("bcs2")
  
              #######################################################
              # handle backward execution case
              #######################################################
              if self.backward_execution:
                  # print("bcs2.1.")
                  return self.finalize_backward_execution()
              else:
                  # print("bcs2.2.")
                  self.backward_execution = False
  
              # print("bcs3")
  
              #######################################################
              # execute decider state
              #######################################################
              decider_state_error = self.run_decider_state(decider_state, child_errors, final_outcomes_dict)
  
              # print("bcs4")
  
              #######################################################
              # handle no transition
              #######################################################
              transition = self.get_transition_for_outcome(decider_state, decider_state.final_outcome)
              if transition is None:
                  # final outcome is set here
                  transition = self.handle_no_transition(decider_state)
              # if the transition is still None, then the child_state was preempted or aborted, in this case return
              decider_state.state_execution_status = StateExecutionStatus.INACTIVE
  
              # print("bcs5")
  
              if transition is None:
                  self.output_data["error"] = RuntimeError("state aborted")
              else:
                  if decider_state_error:
                      self.output_data["error"] = decider_state_error
                  self.final_outcome = self.outcomes[transition.to_outcome]
  
              # print("bcs6")
  
              return self.finalize_concurrency_state(self.final_outcome)
  
          except Exception as e:
              logger.error("{0} had an internal error: {1}\n{2}".format(self, str(e), str(traceback.format_exc())))
              self.output_data["error"] = e
              self.state_execution_status = StateExecutionStatus.WAIT_FOR_NEXT_STATE
              return self.finalize(Outcome(-1, "aborted"))