/** Combine all the data and create a book or display an error. */
  private void sendResults() {
    // This list will be the actual order of the result we apply, based on the
    // actual results and the default order.
    ArrayList<Integer> results = new ArrayList<Integer>();

    if (mHasIsbn) {
      // If ISBN was passed, ignore entries with the wrong ISBN, and put entries with no ISBN at the
      // end
      ArrayList<Integer> uncertain = new ArrayList<Integer>();
      for (int i : mDefaultReliabilityOrder) {
        if (mSearchResults.containsKey(i)) {
          Bundle bookData = mSearchResults.get(i);
          if (bookData.containsKey(CatalogueDBAdapter.KEY_ISBN)) {
            String isbn = bookData.getString(CatalogueDBAdapter.KEY_ISBN);
            if (IsbnUtils.matches(mIsbn, isbn)) {
              results.add(i);
            }
          } else {
            uncertain.add(i);
          }
        }
      }
      for (Integer i : uncertain) {
        results.add(i);
      }
      // Add the passed ISBN first; avoid overwriting
      mBookData.putString(CatalogueDBAdapter.KEY_ISBN, mIsbn);
    } else {
      // If ISBN was not passed, then just used the default order
      for (int i : mDefaultReliabilityOrder) results.add(i);
    }

    // Merge the data we have. We do this in a fixed order rather than as the threads finish.
    for (int i : results) accumulateData(i);

    // If there are thumbnails present, pick the biggest, delete others and rename.
    Utils.cleanupThumbnails(mBookData);

    // Try to use/construct authors
    String authors = null;
    try {
      authors = mBookData.getString(CatalogueDBAdapter.KEY_AUTHOR_DETAILS);
    } catch (Exception e) {
    }

    if (authors == null || authors.equals("")) {
      authors = mAuthor;
    }

    if (authors != null && !authors.equals("")) {
      // Decode the collected author names and convert to an ArrayList
      ArrayList<Author> aa = Utils.getAuthorUtils().decodeList(authors, '|', false);
      mBookData.putSerializable(CatalogueDBAdapter.KEY_AUTHOR_ARRAY, aa);
    }

    // Try to use/construct title
    String title = null;
    try {
      title = mBookData.getString(CatalogueDBAdapter.KEY_TITLE);
    } catch (Exception e) {
    }

    if (title == null || title.equals("")) title = mTitle;

    if (title != null && !title.equals("")) {
      mBookData.putString(CatalogueDBAdapter.KEY_TITLE, title);
    }

    // Try to use/construct isbn
    String isbn = null;
    try {
      isbn = mBookData.getString(CatalogueDBAdapter.KEY_ISBN);
    } catch (Exception e) {
    }

    if (isbn == null || isbn.equals("")) isbn = mIsbn;

    if (isbn != null && !isbn.equals("")) {
      mBookData.putString(CatalogueDBAdapter.KEY_ISBN, isbn);
    }

    // Try to use/construct series
    String series = null;
    try {
      series = mBookData.getString(CatalogueDBAdapter.KEY_SERIES_DETAILS);
    } catch (Exception e) {
    }

    if (series != null && !series.equals("")) {
      // Decode the collected series names and convert to an ArrayList
      try {
        ArrayList<Series> sa = Utils.getSeriesUtils().decodeList(series, '|', false);
        mBookData.putSerializable(CatalogueDBAdapter.KEY_SERIES_ARRAY, sa);
      } catch (Exception e) {
        Logger.logError(e);
      }
    } else {
      // add series to stop crashing
      mBookData.putSerializable(CatalogueDBAdapter.KEY_SERIES_ARRAY, new ArrayList<Series>());
    }

    //
    // TODO: this needs to be locale-specific. Currently we probably get good-enough data without
    // forcing a cleanup.
    //
    // Removed 20-Jan-2016 PJW; see Issue 717.
    //
    // Cleanup other fields
    // Utils.doProperCase(mBookData, CatalogueDBAdapter.KEY_TITLE);
    // Utils.doProperCase(mBookData, CatalogueDBAdapter.KEY_PUBLISHER);
    // Utils.doProperCase(mBookData, CatalogueDBAdapter.KEY_DATE_PUBLISHED);
    // Utils.doProperCase(mBookData, CatalogueDBAdapter.KEY_SERIES_NAME);

    // If book is not found or missing required data, warn the user
    if (authors == null || authors.length() == 0 || title == null || title.length() == 0) {
      mTaskManager.doToast(BookCatalogueApp.getResourceString(R.string.book_not_found));
    }
    // Pass the data back
    sendSearchFinished();
  }