// Download the entire chapter private Observable<Download> downloadChapter(Download download) { try { DiskUtils.createDirectory(download.directory); } catch (IOException e) { return Observable.error(e); } Observable<List<Page>> pageListObservable = download.pages == null ? // Pull page list from network and add them to download object download .source .pullPageListFromNetwork(download.chapter.url) .doOnNext(pages -> download.pages = pages) .doOnNext(pages -> savePageList(download)) : // Or if the page list already exists, start from the file Observable.just(download.pages); return pageListObservable .subscribeOn(Schedulers.io()) .doOnNext( pages -> { download.downloadedImages = 0; download.setStatus(Download.DOWNLOADING); }) // Get all the URLs to the source images, fetch pages if necessary .flatMap(download.source::getAllImageUrlsFromPageList) // Start downloading images, consider we can have downloaded images already .concatMap(page -> getOrDownloadImage(page, download)) // Do after download completes .doOnCompleted(() -> onDownloadCompleted(download)) .toList() .map(pages -> download) // If the page list threw, it will resume here .onErrorResumeNext( error -> { download.setStatus(Download.ERROR); return Observable.just(download); }); }