code: def get_paths_by_ds(
      refds, dataset_arg, paths, subdsroot_mode="rsync"
  ):
      """Resolve and sort any paths into their containing datasets
  
      Any path will be associated (sorted into) its nearest containing dataset.
      It is irrelevant whether or not a path presently exists on the file system.
      However, only datasets that exist on the file system are used for
      sorting/association -- known, but non-existent subdatasets are not
      considered.
  
      Parameters
      ----------
      refds: Dataset
      dataset_arg: Dataset or str or Path or None
        Any supported value given to a command's `dataset` argument. Given
        to `resolve_path()`.
      paths: list
        Any number of absolute or relative paths, in str-form or as
        Path instances, to be sorted into their respective datasets. See also
        the `subdsroot_mode` parameter.
      subdsroot_mode: {'rsync', 'super', 'sub'}
        Switch behavior for paths that are the root of a subdataset. By default
        ('rsync'), such a path is associated with its parent/superdataset,
        unless the path ends with a trailing directory separator, in which case
        it is sorted into the subdataset record (this resembles the path
        semantics of rsync, hence the label). In 'super' mode, the path is always
        placed with the superdataset record. Likewise, in 'sub' mode the path
        is always placed into the subdataset record.
  
      Returns
      -------
      dict, list
        The first return value is the main result, a dictionary with root
        directories of all discovered datasets as keys and a list of the
        associated paths inside these datasets as values.  Keys and values are
        normalized to be Path instances of absolute paths.
        The second return value is a list of all paths (again Path instances)
        that are not located underneath the reference dataset.
      """
      ds_path = refds.path
      paths_by_ds = dict()
      errors = []
  
      if not paths:
          # that was quick
          paths_by_ds[refds.pathobj] = None
          return paths_by_ds, errors
  
      # in order to guarantee proper path sorting, we first need to resolve all
      # of them (some may be str, some Path, some relative, some absolute)
      # step 1: normalize to unicode
      paths = map(ensure_unicode, paths)
      # step 2: resolve
      # for later comparison, we need to preserve the original value too
      paths = [(resolve_path(p, dataset_arg), str(p)) for p in paths]
      # OPT: store cache for dataset roots for each directory directly
      #      listed in paths, or containing the path (if file)
      roots_cache = {}
      # sort any path argument into the respective subdatasets
      # sort by comparing the resolved Path instances, this puts top-level
      # paths first, leading to their datasets to be injected into the result
      # dict first
      for p, orig_path in sorted(paths, key=lambda x: x[0]):
          # TODO (left from implementing caching OPT):
          # Logic here sounds duplicated with discover_dataset_trace_to_targets
          # and even get_tree_roots of save.
          str_p = str(p)
  
          # query get_dataset_root caching for repeated queries within the same
          # directory
          if p.is_dir():
              p_dir = str(p)
          else:  # symlink, file, whatnot - seems to match logic in get_dataset_root
              p_dir = str(p.parent)
  
          try:
              root = roots_cache[p_dir]
          except KeyError:
              root = roots_cache[p_dir] = get_dataset_root(p_dir)
  
          # to become the root of the dataset that contains the path in question
          # in the context of (same basepath) as the reference dataset
          qds_inrefds = None
          if root is not None:
              qds_inrefds = path_under_rev_dataset(refds, root)
          if root is None or qds_inrefds is None:
              # no root, not possibly underneath the refds
              # or root that is not underneath/equal the reference dataset root
              errors.append(p)
              continue
  
          if root != qds_inrefds:
              # try to recode the dataset path wrt to the reference
              # dataset
              # the path that it might have been located by could
              # have been a resolved path or another funky thing
              # the path this dataset was located by is not how it would
              # be referenced underneath the refds (possibly resolved
              # realpath) -> recode all paths to be underneath the refds
              p = qds_inrefds / p.relative_to(root)
              root = qds_inrefds
  
          # Note: Compare to Dataset(root).path rather
          # than root to get same path normalization.
          if (
              root == str_p
              and not Dataset(root).path == ds_path
              and (
                  subdsroot_mode == "super"
                  or (
                      subdsroot_mode == "rsync"
                      and dataset_arg
                      and not orig_path.endswith(op.sep)
                  )
              )
          ):
              # the given path is pointing to a subdataset
              # and we are either in 'super' mode, or in 'rsync' and found
              # rsync-link syntax to identify the dataset as whole
              # (e.g. 'ds') vs its content (e.g. 'ds/')
              root_dir = op.dirname(root)
              try:
                  super_root = roots_cache[root_dir]
              except KeyError:
                  super_root = roots_cache[root_dir] = get_dataset_root(
                      root_dir
                  )
              if super_root:
                  # the dataset identified by the path argument
                  # is contained in a superdataset, and no
                  # trailing path separator was found in the
                  # argument -> user wants to address the dataset
                  # as a whole (in the superdataset)
                  root = super_root
  
          root = ut.Path(root)
          ps = paths_by_ds.get(root, [])
          ps.append(p)
          paths_by_ds[root] = ps
      return paths_by_ds, errors
  
imports: import logging
  import os
  import os.path
  from collections import OrderedDict
  import warnings
  from datalad.utils import bytes2human, ensure_list, ensure_unicode, get_dataset_root
  from datalad.interface.base import Interface, build_doc, eval_results
  from datalad.interface.common_opts import recursion_limit, recursion_flag
  from datalad.interface.utils import generic_result_renderer
  import datalad.support.ansi_colors
  from datalad.support.param import Parameter
  from datalad.support.constraints import EnsureChoice, EnsureNone, EnsureStr
  from datalad.distribution.dataset import Dataset, EnsureDataset, datasetmethod, require_dataset, resolve_path, path_under_rev_dataset
  import datalad.utils
  from datalad.dochelpers import single_or_plural
label_desc: Use image node_id 2 for calling a global function with example usage: get_paths_by_ds(refds, dataset_arg, paths, subdsroot_mode) and returns: paths_by_ds,  errors, paths_by_ds,  errors