code: def migrate_domain_format(
      domain_path: Union[Text, Path],
      out_path: Optional[Union[Text, Path]],
  ) -> None:
      """Converts 2.0 domain to 3.0 format."""
      domain_path = Path(domain_path)
      out_path = Path(out_path) if out_path else None
  
      domain_parent_dir = domain_path.parent
      migrate_file_only = domain_path.is_file()
  
      # Ensure the backup location does not exist yet
      # Note: We demand that file as well as folder with this name gets deleted before
      # the command is run to avoid confusion afterwards.
      suffix = (
          f"{ORIGINAL_DOMAIN}{YML_SUFFIX}"
          if migrate_file_only
          else ORIGINAL_DOMAIN
      )
      backup_location = domain_parent_dir / suffix
      if backup_location.exists():
          backup_location_str = (
              "directory" if backup_location.is_dir() else "file"
          )
          raise RasaException(
              f"The domain could not be migrated since the "
              f"{backup_location_str} '{backup_location}' already exists."
              f"Please make sure that there is no {backup_location_str} at "
              f"'{backup_location}'."
          )
  
      # Choose a default output location if nothing was specified
      if out_path is None:
          suffix = (
              f"{DEFAULT_NEW_DOMAIN}{YML_SUFFIX}"
              if migrate_file_only
              else DEFAULT_NEW_DOMAIN
          )
          out_path = domain_parent_dir / suffix
  
      # Ensure the output location is not already in-use
      if not migrate_file_only:
          if out_path.is_dir() and any(out_path.iterdir()):
              raise RasaException(
                  f"The domain could not be migrated to "
                  f"'{out_path}' because that folder is not empty."
                  "Please remove the contents of the folder and try again."
              )
      else:
          if out_path.is_file():
              raise RasaException(
                  f"The domain could not be migrated to "
                  f"'{out_path}' because that file already exists."
                  "Please remove the file and try again."
              )
  
      # Sanity Check: Assert the files to be migrated aren't in 3.0 format already
      # Note: we do not enforce that the version tag is 2.0 everywhere + validate that
      # migrate-able domain files are among these files later
      original_files = (
          {
              file: rasa.shared.utils.io.read_yaml_file(file)
              for file in domain_path.iterdir()
              if Domain.is_domain_file(file)
          }
          if domain_path.is_dir()
          else {
              domain_path: rasa.shared.utils.io.read_yaml_file(
                  domain_path
              )
          }
      )
      migrated_files = []
  
      for file, file_dict in original_files.items():
          if not isinstance(file_dict, dict):
              raise RasaException(
                  f"The file {file} could not be read "
                  f"as an eligible domain dictionary. "
                  f"Please make sure you have included "
                  f"only eligible domain files."
              )
  
          if (
              file_dict.get(KEY_TRAINING_DATA_FORMAT_VERSION)
              == LATEST_TRAINING_DATA_FORMAT_VERSION
          ):
              migrated_files.append(file)
  
      if migrated_files:
          raise RasaException(
              f"Some of the given files ({[file for file in migrated_files]}) "
              f"have already been migrated to Rasa 3.0 format. Please remove these "
              f"migrated files (or replace them with files in 2.0 format) and try again."
          )
  
      # Validate given domain file(s) and migrate them
      try:
          created_out_dir = False
          if not migrate_file_only:
              if not out_path.is_dir():
                  out_path.mkdir()
                  created_out_dir = True
              backup_location.mkdir()
              original_domain = _migrate_domain_files(
                  domain_path, backup_location, out_path
              )
          else:
              if not Domain.is_domain_file(domain_path):
                  raise RasaException(
                      f"The file '{domain_path.as_posix()}' could not be validated as a "
                      f"domain file. Only domain yaml files can be migrated. "
                  )
              original_domain = _create_back_up(
                  domain_path, backup_location
              )
  
          new_forms, updated_slots = _migrate_form_slots(
              original_domain
          )
          new_slots = _migrate_auto_fill_and_custom_slots(
              original_domain, updated_slots
          )
  
          _write_final_domain(
              domain_path, new_forms, new_slots, out_path
          )
  
          rasa.shared.utils.cli.print_success(
              f"Your domain file '{domain_path!s}' was successfully migrated! "
              f"The migrated version is now '{out_path!s}'. "
              f"The original domain file is backed-up at '{backup_location!s}'."
          )
  
      except Exception as e:
          # Remove the backups if migration couldn't be completed
          if backup_location.is_dir():
              shutil.rmtree(backup_location)
          if out_path.is_dir():
              if created_out_dir:
                  shutil.rmtree(out_path)
              else:  # just remove contained files so we do not mess with access rights
                  for f in out_path.glob("*"):
                      f.unlink()
          if backup_location.is_file():
              backup_location.unlink()
          raise e
  
imports: import copy
  import shutil
  from pathlib import Path
  from typing import List, Dict, Text, Any, Tuple, Optional, Union
  from ruamel.yaml.scalarstring import DoubleQuotedScalarString
  import rasa.shared.utils.io
  import rasa.shared.utils.cli
  from rasa.shared.constants import REQUIRED_SLOTS_KEY, IGNORED_INTENTS
  from rasa.shared.core.constants import ACTIVE_LOOP, REQUESTED_SLOT, SlotMappingType, MAPPING_TYPE, SLOT_MAPPINGS
  from rasa.shared.constants import LATEST_TRAINING_DATA_FORMAT_VERSION
  from rasa.shared.core.domain import KEY_ENTITIES, KEY_SLOTS, KEY_FORMS, Domain
  from rasa.shared.exceptions import RasaException
  from rasa.shared.utils.validation import KEY_TRAINING_DATA_FORMAT_VERSION
label_desc: Use image node_id 11 for calling a global function with example usage: migrate_domain_format(domain_path, out_path) without return types