docs: def save_state_machine(delete_old_state_machine=False, recent_opened_notification=False, as_copy=False, copy_path=None):
      """ Save selected state machine
  
       The function checks if states of the state machine has not stored script data abd triggers dialog windows to
       take user input how to continue (ignoring or storing this script changes).
       If the state machine file_system_path is None function save_state_machine_as is used to collect respective path and
       to store the state machine.
       The delete flag will remove all data in existing state machine folder (if plugins or feature use non-standard
       RAFCON files this data will be removed)
  
      :param bool delete_old_state_machine: Flag to delete existing state machine folder before storing current version
      :param bool recent_opened_notification: Flag to insert path of state machine into recent opened state machine paths
      :param bool as_copy: Store state machine as copy flag e.g. without assigning path to state_machine.file_system_path
      :return: True if the storing was successful, False if the storing process was canceled or stopped by condition fail
      :rtype bool:
      """
  
      state_machine_manager_model = rafcon.gui.singleton.state_machine_manager_model
      states_editor_ctrl = rafcon.gui.singleton.main_window_controller.get_controller('states_editor_ctrl')
  
      state_machine_m = state_machine_manager_model.get_selected_state_machine_model()
      if state_machine_m is None:
          logger.warning("Can not 'save state machine' because no state machine is selected.")
          return False
  
      previous_path = state_machine_m.state_machine.file_system_path
      previous_marked_dirty = state_machine_m.state_machine.marked_dirty
      all_tabs = list(states_editor_ctrl.tabs.values())
      all_tabs.extend(states_editor_ctrl.closed_tabs.values())
      dirty_source_editor_ctrls = [tab_dict['controller'].get_controller('source_ctrl') for tab_dict in all_tabs if
                                   tab_dict['source_code_view_is_dirty'] is True and
                                   tab_dict['state_m'].state.get_state_machine().state_machine_id ==
                                   state_machine_m.state_machine.state_machine_id]
  
      for dirty_source_editor_ctrl in dirty_source_editor_ctrls:
          state = dirty_source_editor_ctrl.model.state
          message_string = "The source code of the state '{}' (path: {}) has not been applied yet and would " \
                           "therefore not be saved.\n\nDo you want to apply the changes now?" \
                           "".format(state.name, state.get_path())
          if global_gui_config.get_config_value("AUTO_APPLY_SOURCE_CODE_CHANGES", False):
              dirty_source_editor_ctrl.apply_clicked(None)
          else:
              dialog = RAFCONButtonDialog(message_string, ["Apply", "Ignore changes"],
                                          message_type=Gtk.MessageType.WARNING, parent=states_editor_ctrl.get_root_window())
              response_id = dialog.run()
              state = dirty_source_editor_ctrl.model.state
              if response_id == 1:  # Apply changes
                  logger.debug("Applying source code changes of state '{}'".format(state.name))
                  dirty_source_editor_ctrl.apply_clicked(None)
  
              elif response_id == 2:  # Ignore changes
                  logger.debug("Ignoring source code changes of state '{}'".format(state.name))
              else:
                  logger.warning("Response id: {} is not considered".format(response_id))
                  return False
              dialog.destroy()
  
      save_path = state_machine_m.state_machine.file_system_path
      if not as_copy and save_path is None or as_copy and copy_path is None:
          if not save_state_machine_as(as_copy=as_copy):
              return False
          return True
  
      logger.debug("Saving state machine to {0}".format(save_path))
  
      state_machine_m = state_machine_manager_model.get_selected_state_machine_model()
      sm_path = state_machine_m.state_machine.file_system_path
  
      storage.save_state_machine_to_path(state_machine_m.state_machine, copy_path if as_copy else sm_path,
                                         delete_old_state_machine=delete_old_state_machine, as_copy=as_copy)
      if recent_opened_notification:
          global_runtime_config.update_recently_opened_state_machines_with(state_machine_m.state_machine)
      state_machine_m.store_meta_data(copy_path=copy_path if as_copy else None)
      logger.debug("Saved state machine and its meta data.")
      library_manager_model.state_machine_was_stored(state_machine_m, previous_path)
      return True