protected void selectResult(SearchResult selectedResult) {
    searchResultDAO.save(
        selectedResult.getUrl(),
        selectedResult.getProviderName(),
        selectedResult.getProviderClass(),
        selectedResult.getReferer(),
        selectedResult.getSizeInMegs(),
        selectedResult.getTitle(),
        selectedResult.getType(),
        getDownloadable().getId(),
        selectedResult.getClientId());

    BackLogProcessor.getInstance()
        .schedule(new DownloadSearchResultTask(selectedResult, getDownloadable()), false);
  }
  @Override
  public void execute() throws IOException, URISyntaxException {

    Collection<String> blackList = getWordsBlackList(getDownloadable());

    SearchResult selectedResult = null;

    Set<String> blackListedUrls = new HashSet<>();
    List<SearchResult> existingResults =
        searchResultDAO.getSearchResults(getDownloadable().getId());
    for (SearchResult searchResult : existingResults) {
      if (searchResult.isBlackListed()) {
        blackListedUrls.add(searchResult.getUrl());
      } else {
        if (searchResult.getType() != SearchResultType.HTTP) {
          // TODO : implement HTTP downloads
          selectedResult = searchResult; // auto download this one
        }
        break;
      }
    }

    if (selectedResult == null) {

      String baseLabel = getCurrentLabel();

      int currentScore = -1;

      List<DownloadFinder> providers = (List<DownloadFinder>) getProviders();
      if (providers != null) {

        totalItems = providers.size();

        for (DownloadFinder provider : providers) {
          if (!provider.isEnabled()) {
            continue;
          }

          if (cancelled) {
            break;
          }

          setCurrentLabel(String.format("%s - Searching from %s", baseLabel, provider.toString()));

          while (!provider.isReady()) {
            try {
              Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
          }

          List<SearchResult> resultsForProvider = getResults(provider, getDownloadable());
          if (resultsForProvider != null && resultsForProvider.size() > 0) {
            for (Iterator<SearchResult> iterator = resultsForProvider.iterator();
                iterator.hasNext(); ) {
              SearchResult searchResult = iterator.next();
              // remove blacklisted results

              if (blackListedUrls != null && blackListedUrls.contains(searchResult.getUrl())) {
                iterator.remove();
                continue;
              }

              if (blackList != null) {
                for (String word : blackList) {
                  if (StringUtils.isNoneBlank(word)
                      && StringUtils.containsIgnoreCase(searchResult.getTitle(), word)) {
                    iterator.remove();
                    break;
                  }
                }
              }
            }

            if (resultsForProvider.size() > 0) {
              filterResults(resultsForProvider);
              for (SearchResult searchResult : resultsForProvider) {
                int score = evaluateResult(searchResult);
                if (score > currentScore) {
                  selectedResult = searchResult;
                  currentScore = score;
                }
              }

              if (currentScore >= SCORE_THRESHOLD) {
                break;
              }
            }
          }
          itemsDone++;
        }
      }
    }

    if (!cancelled) {

      if (selectedResult != null) {
        selectResult(selectedResult);
      } else {
        mustReschedule = true;
      }
    }
  }