/** Initiates a download of the specified visual search result to the specified save file. */
  @Override
  public void download(final VisualSearchResult vsr, File saveFile) {
    try {
      // Add download to manager.  If save file is specified, then set
      // overwrite to true because the user has already confirmed it.
      DownloadItem di =
          (saveFile == null)
              ? downloadListManager.addDownload(search, vsr.getCoreSearchResults())
              : downloadListManager.addDownload(search, vsr.getCoreSearchResults(), saveFile, true);

      // Add listener, and initialize download state.
      di.addPropertyChangeListener(new DownloadItemPropertyListener(vsr));
      vsr.setDownloadState(BasicDownloadState.DOWNLOADING);

    } catch (final SaveLocationException sle) {
      if (sle.getErrorCode() == SaveLocationException.LocationCode.FILE_ALREADY_DOWNLOADING) {
        DownloadItem downloadItem = downloadListManager.getDownloadItem(vsr.getUrn());
        if (downloadItem != null) {
          downloadItem.addPropertyChangeListener(new DownloadItemPropertyListener(vsr));
          vsr.setDownloadState(BasicDownloadState.DOWNLOADING);
          if (saveFile != null) {
            try {
              // Update save file in DownloadItem.
              downloadItem.setSaveFile(saveFile, true);
            } catch (SaveLocationException ex) {
              LOG.infof(ex, "Unable to relocate downloading file {0}", ex.getMessage());
            }
          }
        }
      } else {
        saveLocationExceptionHandler.handleSaveLocationException(
            new DownloadAction() {
              @Override
              public void download(File saveFile, boolean overwrite) throws SaveLocationException {
                DownloadItem di =
                    downloadListManager.addDownload(
                        search, vsr.getCoreSearchResults(), saveFile, overwrite);
                di.addPropertyChangeListener(new DownloadItemPropertyListener(vsr));
                vsr.setDownloadState(BasicDownloadState.DOWNLOADING);
              }
            },
            sle,
            true);
      }
    }
  }