docs: def extract_child_models_of_state(state_m, new_state_class):
      """Retrieve child models of state model
  
      The function extracts the child state and state element models of the given state model into a dict. It only
      extracts those properties that are required for a state of type `new_state_class`. Transitions are always left out.
  
      :param state_m: state model of which children are to be extracted from
      :param new_state_class: The type of the new class
      :return:
      """
      # check if root state and which type of state
      assert isinstance(state_m, StateModel)
      assert issubclass(new_state_class, State)
      orig_state = state_m.state  # only here to get the input parameter of the Core-function
  
      current_state_is_container = isinstance(orig_state, ContainerState)
      new_state_is_container = issubclass(new_state_class, ContainerState)
  
      # define which model references to hold for new state
      required_model_properties = ['input_data_ports', 'output_data_ports', 'outcomes', 'income']
      obsolete_model_properties = []
      if current_state_is_container and new_state_is_container:  # hold some additional references
          # transition are removed when changing the state type, thus do not copy them
          required_model_properties.extend(['states', 'data_flows', 'scoped_variables'])
          obsolete_model_properties.append('transitions')
      elif current_state_is_container:
          obsolete_model_properties.extend(['states', 'transitions', 'data_flows', 'scoped_variables'])
  
      def get_element_list(state_m, prop_name):
          if prop_name == 'income':
              return [state_m.income]
          wrapper = getattr(state_m, prop_name)
          # ._obj is needed as gaphas wraps observable lists and dicts into a gaphas.support.ObsWrapper
          list_or_dict = wrapper._obj
          if isinstance(list_or_dict, list):
              return list_or_dict[:]  # copy list
          return list(list_or_dict.values())  # dict
  
      required_child_models = {}
      for prop_name in required_model_properties:
          required_child_models[prop_name] = get_element_list(state_m, prop_name)
      obsolete_child_models = {}
      for prop_name in obsolete_model_properties:
          obsolete_child_models[prop_name] = get_element_list(state_m, prop_name)
  
      # Special handling of BarrierState, which includes the DeciderState that always becomes obsolete
      if isinstance(state_m, ContainerStateModel):
          decider_state_m = state_m.states.get(UNIQUE_DECIDER_STATE_ID, None)
          if decider_state_m:
              if new_state_is_container:
                  required_child_models['states'].remove(decider_state_m)
                  obsolete_child_models['states'] = [decider_state_m]
  
      return required_child_models, obsolete_child_models