static async assignSegmentsToManifest(
      storage, manifestId, manifestDB, manifestUpdates, dataSizeUpdate,
      throwIfAbortedFn) {
    let manifestUpdated = false;

    try {
      // Assign the stored data to the manifest.
      let complete = true;
      for (const stream of manifestDB.streams) {
        for (const segment of stream.segments) {
          let dataKey = segment.pendingSegmentRefId ?
              manifestUpdates[segment.pendingSegmentRefId] : null;
          if (dataKey != null) {
            segment.dataKey = dataKey;
            // Now that the segment has been associated with the appropriate
            // dataKey, the pendingSegmentRefId is no longer necessary.
            segment.pendingSegmentRefId = undefined;
          }

          dataKey = segment.pendingInitSegmentRefId ?
              manifestUpdates[segment.pendingInitSegmentRefId] : null;
          if (dataKey != null) {
            segment.initSegmentKey = dataKey;
            // Now that the init segment has been associated with the
            // appropriate initSegmentKey, the pendingInitSegmentRefId is no
            // longer necessary.
            segment.pendingInitSegmentRefId = undefined;
          }

          if (segment.pendingSegmentRefId) {
            complete = false;
          }
          if (segment.pendingInitSegmentRefId) {
            complete = false;
          }
        }
      }

      // Update the size of the manifest.
      manifestDB.size += dataSizeUpdate;

      // Mark the manifest as complete, if all segments are downloaded.
      if (complete) {
        manifestDB.isIncomplete = false;
      }

      // Update the manifest.
      await storage.updateManifest(manifestId, manifestDB);
      manifestUpdated = true;
      throwIfAbortedFn();
    } catch (e) {
      await shaka.offline.Storage.cleanStoredManifest(manifestId);

      if (!manifestUpdated) {
        const dataKeys = Object.values(manifestUpdates);
        // The cleanStoredManifest method will not "see" any segments that have
        // been downloaded but not assigned to the manifest yet. So un-store
        // them separately.
        await storage.removeSegments(dataKeys, (key) => {});
      }

      throw e;
    }
  }
Updates the given manifest, assigns database keys to segments, then stores
the updated manifest.

It is up to the caller to ensure that this method is not called
concurrently on the same manifest.

@param {shaka.extern.StorageCell} storage
@param {number} manifestId
@param {!shaka.extern.ManifestDB} manifestDB
@param {!Object<string, number>} manifestUpdates
@param {number} dataSizeUpdate
@param {function()} throwIfAbortedFn  A function that should throw if the
  download has been aborted.
@return {!Promise}