docs: def ungroup_state(self, state_id):
          """ Ungroup state with state id state_id into its parent and remain internal linkage in parent.
              Interconnecting transitions and data flows to parent and other child states are preserved except:
              - a transition that is going from income to outcome directly and
              - a data-flow that is linking input and output directly.
  
          :param state_id: State that is to be ungrouped.
          :return:
          """
          state = self.states[state_id]
          assert isinstance(state, ContainerState)
          from rafcon.core.states.barrier_concurrency_state import BarrierConcurrencyState, UNIQUE_DECIDER_STATE_ID
          if isinstance(state, BarrierConcurrencyState):
              state.remove_state(state_id=UNIQUE_DECIDER_STATE_ID, force=True)
          [related_transitions, related_data_flows] = self.related_linkage_state(state_id)
  
          # ingoing logical linkage to rebuild -> related_transitions['external']['ingoing']
          # outgoing logical linkage to rebuild -> related_transitions['external']['outgoing']
          # ingoing data linkage to rebuild
          ingoing_data_linkage_for_port = {}
          for df in related_data_flows['internal']['ingoing']:
              if (df.from_state, df.from_key) in ingoing_data_linkage_for_port:
                  ingoing_data_linkage_for_port[(df.from_state, df.from_key)]['internal'].append(df)
              else:
                  ingoing_data_linkage_for_port[(df.from_state, df.from_key)] = {'external': [], 'internal': [df]}
              if not ingoing_data_linkage_for_port[(df.from_state, df.from_key)]['external']:
                  for ext_df in self.data_flows.values():
                      if (ext_df.to_state, ext_df.to_key) == (df.from_state, df.from_key):
                          ingoing_data_linkage_for_port[(df.from_state, df.from_key)]['external'].append(ext_df)
          # outgoing data linkage to rebuild
          outgoing_data_linkage_for_port = {}
          for df in related_data_flows['internal']['outgoing']:
              if (df.to_state, df.to_key) in outgoing_data_linkage_for_port:
                  outgoing_data_linkage_for_port[(df.to_state, df.to_key)]['internal'].append(df)
              else:
                  outgoing_data_linkage_for_port[(df.to_state, df.to_key)] = {'external': [], 'internal': [df]}
              if not outgoing_data_linkage_for_port[(df.to_state, df.to_key)]['external']:
                  for ext_df in self.data_flows.values():
                      if (ext_df.from_state, ext_df.from_key) == (df.to_state, df.to_key):
                          outgoing_data_linkage_for_port[(df.to_state, df.to_key)]['external'].append(ext_df)
          # hold states and scoped variables to rebuild
          child_states = [state.remove_state(s_id, recursive=False, destroy=False) for s_id in list(state.states.keys())]
          child_scoped_variables = [sv for sv_id, sv in list(state.scoped_variables.items())]
  
          # remove state that should be ungrouped
          old_state = self.remove_state(state_id, recursive=False, destroy=False)
  
          # fill elements into parent state and remember id mapping from child to parent state to map other properties
          state_id_dict = {}
          sv_id_dict = {}
          enclosed_df_id_dict = {}
          enclosed_t_id_dict = {}
  
          # re-create states
          old_state_ids = [state.state_id for state in child_states]
          for child_state in child_states:
              old_state_id = child_state.state_id
              # needed to change state id here because not handled in add state and to avoid old state ids
              new_id = None
              if child_state.state_id in list(self.states.keys()):
                  new_id = state_id_generator(used_state_ids=list(self.states.keys()) + old_state_ids + [self.state_id])
                  child_state.change_state_id(new_id)
              new_state_id = self.add_state(child_state)
              if new_id is not None and not new_id == new_state_id:
                  logger.error("In ungroup state the changed state id should not be changed again by add_state because it"
                               " could become a old_state_id again and screw data flows and transitions.")
              # remember new and old state id relations
              state_id_dict[old_state_id] = new_state_id
          # re-create scoped variables
          for sv in child_scoped_variables:
              name = sv.name
              if name in [parent_sv.name for parent_sv in self.scoped_variables.values()]:
                  name = state_id + name
              new_sv_id = self.add_scoped_variable(name, sv.data_type, sv.default_value)
              sv_id_dict[sv.data_port_id] = new_sv_id
  
          # re-create transitions
          for t in related_transitions['internal']['enclosed']:
              new_t_id = self.add_transition(state_id_dict[t.from_state], t.from_outcome,
                                             state_id_dict[t.to_state], t.to_outcome)
              enclosed_t_id_dict[t.transition_id] = new_t_id
          assert len(related_transitions['internal']['ingoing']) <= 1
          if related_transitions['internal']['ingoing']:
              ingoing_t = related_transitions['internal']['ingoing'][0]
              for t in related_transitions['external']['ingoing']:
                  self.add_transition(t.from_state, t.from_outcome, state_id_dict[ingoing_t.to_state],
                                      ingoing_t.to_outcome)
          for ext_t in related_transitions['external']['outgoing']:
              for t in related_transitions['internal']['outgoing']:
                  if (t.to_state, t.to_outcome) == (ext_t.from_state, ext_t.from_outcome):
                      try:
                          self.add_transition(state_id_dict[t.from_state], t.from_outcome,
                                              ext_t.to_state, ext_t.to_outcome)
                      except ValueError:
                          from rafcon.core.states.barrier_concurrency_state import BarrierConcurrencyState
                          if not isinstance(self, BarrierConcurrencyState):
                              logger.exception("Error while recreation of logical linkage.")
  
          # re-create data flow linkage
          for df in related_data_flows['internal']['enclosed']:
              # print("enclosed: ", df)
              new_df_id = self.add_data_flow(self.state_id if state_id == df.from_state else state_id_dict[df.from_state],
                                             sv_id_dict[df.from_key] if state_id == df.from_state else df.from_key,
                                             self.state_id if state_id == df.to_state else state_id_dict[df.to_state],
                                             sv_id_dict[df.to_key] if state_id == df.to_state else df.to_key)
              enclosed_df_id_dict[df.data_flow_id] = new_df_id
          for data_port_linkage in ingoing_data_linkage_for_port.values():
              for ext_df in data_port_linkage['external']:
                  for df in data_port_linkage['internal']:
                      # print("ingoing: ", ext_df, df)
                      if df.to_state not in state_id_dict and df.to_state == state_id:
                          self.add_data_flow(ext_df.from_state, ext_df.from_key, self.state_id, sv_id_dict[df.to_key])
                      else:
                          self.add_data_flow(ext_df.from_state, ext_df.from_key, state_id_dict[df.to_state], df.to_key)
          for data_port_linkage in outgoing_data_linkage_for_port.values():
              for ext_df in data_port_linkage['external']:
                  for df in data_port_linkage['internal']:
                      # print("outgoing: ", ext_df, df)
                      if df.from_state not in state_id_dict and df.from_state == state_id:
                          self.add_data_flow(self.state_id, sv_id_dict[df.from_key], ext_df.to_state, ext_df.to_key)
                      else:
                          self.add_data_flow(state_id_dict[df.from_state], df.from_key, ext_df.to_state, ext_df.to_key)
  
          self.ungroup_state.__func__.state_id_dict = state_id_dict
          self.ungroup_state.__func__.sv_id_dict = sv_id_dict
          self.ungroup_state.__func__.enclosed_df_id_dict = enclosed_df_id_dict
          self.ungroup_state.__func__.enclosed_t_id_dict = enclosed_t_id_dict
  
          old_state.destroy(recursive=True)
          return old_state