docs: def save(self, processes=1, manifests=False):
          """
          save will persist any changes that have been made to the bag
          metadata (self.info).
  
          If you have modified the payload of the bag (added, modified,
          removed files in the data directory) and want to regenerate manifests
          set the manifests parameter to True. The default is False since you
          wouldn't want a save to accidentally create a new manifest for
          a corrupted bag.
  
          If you want to control the number of processes that are used when
          recalculating checksums use the processes parameter.
          """
          # Error checking
          if not self.path:
              raise BagError(_('Bag.save() called before setting the path!'))
  
          if not os.access(self.path, os.R_OK | os.W_OK | os.X_OK):
              raise BagError(_('Cannot save bag to non-existent or inaccessible directory %s') % self.path)
  
          unbaggable = _can_bag(self.path)
          if unbaggable:
              LOGGER.error(_("Missing write permissions for the following directories and files:\n%s"),
                           unbaggable)
              raise BagError(_("Missing permissions to move all files and directories"))
  
          unreadable_dirs, unreadable_files = _can_read(self.path)
          if unreadable_dirs or unreadable_files:
              if unreadable_dirs:
                  LOGGER.error(_("The following directories do not have read permissions:\n%s"),
                               unreadable_dirs)
              if unreadable_files:
                  LOGGER.error(_("The following files do not have read permissions:\n%s"),
                               unreadable_files)
              raise BagError(_("Read permissions are required to calculate file fixities"))
  
          # Change working directory to bag directory so helper functions work
          old_dir = os.path.abspath(os.path.curdir)
          try:
              os.chdir(self.path)
  
              # Generate new manifest files
              if manifests:
                  strict = True if self.version_info >= (1, 0) else False
                  self._sync_remote_entries_with_existing_fetch()
                  validate_remote_entries(self.remote_entries, self.path)
                  total_bytes, total_files = make_manifests('data', processes,
                                                            algorithms=self.algorithms,
                                                            encoding=self.encoding,
                                                            remote=self.remote_entries,
                                                            strict=strict)
  
                  # Update fetch.txt
                  _make_fetch_file(self.path, self.remote_entries)
  
                  # Update Payload-Oxum
                  LOGGER.info(_('Updating Payload-Oxum in %s'), self.tag_file_name)
                  self.info['Payload-Oxum'] = '%s.%s' % (total_bytes, total_files)
  
              _make_tag_file(self.tag_file_name, self.info)
  
              # Update tag-manifest for changes to manifest & bag-info files
              for alg in self.algorithms:
                  _make_tagmanifest_file(alg, self.path, encoding=self.encoding)
  
              # Reload the manifests
              self._load_manifests()
  
          except Exception:
              LOGGER.error(_("An error occurred updating bag in %s"), self.path)
              raise
  
          finally:
              os.chdir(old_dir)