docs: def _vectorize_and_bind(self, local_path, dest):
          # type: (Uploader, blobxfer.models.upload.LocalPath,
          #        List[blobxfer.models.azure.StorageEntity]) ->
          #        Tuple[blobxfer.operations.upload.UploadAction,
          #        blobxfer.models.upload.LocalPath,
          #        blobxfer.models.azure.StorageEntity]
          """Vectorize local path to destinations, if necessary, and bind
          :param Uploader self: this
          :param blobxfer.models.LocalPath local_path: local path
          :param list dest: list of destination tuples (sa, ase)
          :rtype: tuple
          :return: action, LocalPath, ase
          """
          if (self._spec.options.vectored_io.distribution_mode ==
                  blobxfer.models.upload.VectoredIoDistributionMode.Stripe and
                  not local_path.use_stdin):
              # compute total number of slices
              slices = int(math.ceil(
                  local_path.total_size /
                  self._spec.options.vectored_io.stripe_chunk_size_bytes))
              # check if vectorization is possible
              if slices == 1:
                  sa, ase = dest[0]
                  if not sa.can_write_object:
                      raise RuntimeError(
                          'unable to write to remote path {} as credential '
                          'for storage account {} does not permit write '
                          'access'.format(ase.path, sa.name))
                  action = self._check_upload_conditions(local_path, ase)
                  yield action, local_path, ase
                  return
              num_dest = len(dest)
              logger.debug(
                  '{} slices for vectored out of {} to {} destinations'.format(
                      slices, local_path.absolute_path, num_dest))
              # pre-populate slice map for next pointers
              slice_map = {}
              for i in range(0, slices):
                  sa, ase = dest[i % num_dest]
                  if not sa.can_write_object:
                      raise RuntimeError(
                          'unable to write to remote path {} as credential '
                          'for storage account {} does not permit write '
                          'access'.format(ase.path, sa.name))
                  name = blobxfer.operations.upload.Uploader.\
                      append_slice_suffix_to_name(ase.name, i)
                  sase = self._check_for_existing_remote(sa, ase.container, name)
                  if sase is None:
                      # encryption metadata will be populated later, if required
                      sase = blobxfer.models.azure.StorageEntity(
                          ase.container, ed=None)
                      sase.populate_from_local(
                          sa, ase.container, name, self._spec.options.mode,
                          self._spec.options.store_file_properties.cache_control)
                      if sase.mode == blobxfer.models.azure.StorageModes.Block:
                          sase.access_tier = self._spec.options.access_tier
                  slice_map[i] = sase
              # create new local path to ase mappings
              curr = 0
              for i in range(0, slices):
                  start = curr
                  end = (
                      curr +
                      self._spec.options.vectored_io.stripe_chunk_size_bytes
                  )
                  if end > local_path.total_size:
                      end = local_path.total_size
                  ase = slice_map[i]
                  if i < slices - 1:
                      next_entry = blobxfer.models.metadata.\
                          create_vectored_io_next_entry(slice_map[i + 1])
                  else:
                      next_entry = None
                  lp_slice = blobxfer.models.upload.LocalPath(
                      parent_path=local_path.parent_path,
                      relative_path=local_path.relative_path,
                      use_stdin=False,
                      view=blobxfer.models.upload.LocalPathView(
                          fd_start=start,
                          fd_end=end,
                          slice_num=i,
                          mode=self._spec.options.vectored_io.distribution_mode,
                          total_slices=slices,
                          next=next_entry,
                      )
                  )
                  action = self._check_upload_conditions(lp_slice, ase)
                  yield action, lp_slice, ase
                  curr = end
          elif (self._spec.options.vectored_io.distribution_mode ==
                  blobxfer.models.upload.VectoredIoDistributionMode.Replica):
              action_map = {}
              for sa, ase in dest:
                  if not sa.can_write_object:
                      raise RuntimeError(
                          'unable to write to remote path {} as credential '
                          'for storage account {} does not permit write '
                          'access'.format(ase.path, sa.name))
                  action = self._check_upload_conditions(local_path, ase)
                  if action not in action_map:
                      action_map[action] = []
                  action_map[action].append(ase)
              for action in action_map:
                  dst = action_map[action]
                  if len(dst) == 1:
                      yield action, local_path, dst[0]
                  else:
                      if (action == UploadAction.CheckMd5 or
                              action == UploadAction.Skip):
                          for ase in dst:
                              yield action, local_path, ase
                      else:
                          primary_ase = dst[0]
                          if primary_ase.replica_targets is None:
                              primary_ase.replica_targets = []
                          primary_ase.replica_targets.extend(dst[1:])
                          # add replica targets to deletion exclusion set
                          if self._spec.options.delete_extraneous_destination:
                              for rt in primary_ase.replica_targets:
                                  self._delete_exclude.add(
                                      blobxfer.operations.upload.Uploader.
                                      create_destination_id(
                                          rt._client, rt.container, rt.name)
                                  )
                          yield action, local_path, primary_ase
          else:
              for sa, ase in dest:
                  if not sa.can_write_object:
                      raise RuntimeError(
                          'unable to write to remote path {} as credential '
                          'for storage account {} does not permit write '
                          'access'.format(ase.path, sa.name))
                  action = self._check_upload_conditions(local_path, ase)
                  yield action, local_path, ase