class DownloadManager {

  static Download mergeRequest(
      Download download, DownloadRequest request, int stopReason, long nowMs) {
    @Download.State int state = download.state;
    // Treat the merge as creating a new download if we're currently removing the existing one, or
    // if the existing download is in a terminal state. Else treat the merge as updating the
    // existing download.
    long startTimeMs =
        state == STATE_REMOVING || download.isTerminalState() ? nowMs : download.startTimeMs;
    if (state == STATE_REMOVING || state == STATE_RESTARTING) {
      state = STATE_RESTARTING;
    } else if (stopReason != STOP_REASON_NONE) {
      state = STATE_STOPPED;
    } else {
      state = STATE_QUEUED;
    }
    return new Download(
        download.request.copyWithMergedRequest(request),
        state,
        startTimeMs,
        /* updateTimeMs= */ nowMs,
        /* contentLength= */ C.LENGTH_UNSET,
        stopReason,
        FAILURE_REASON_NONE);
  }

  public  DownloadManager(
      Context context, DatabaseProvider databaseProvider, Cache cache, Factory upstreamFactory);
  public  DownloadManager(
      Context context, WritableDownloadIndex downloadIndex, DownloaderFactory downloaderFactory);

}