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)