public void search(
      String searchTerm, Set<Integer> categories, Set<String> languages, String sortBy) {
    if (searcher == null) {
      System.err.println("Searching before searcher was initialized.");
      return;
    }

    // fetch from cache if searchterm is null
    if (searchTerm == null) searchTerm = lastSearchTerm;
    lastCategories = categories;
    lastLanguages = languages;
    lastSearchTerm = searchTerm;
    lastSortBy = sortBy;

    try {
      lastResults = searcher.search(searchTerm, categories, languages);
      lastResults = sortResults(lastResults, sortBy);

      for (SearcherListener listener : listListeners) {
        listener.onSearch(lastResults);
      }
    } catch (ParseException e) {
      Alert.alert(MessageType.WARNING, "The search string is not valid.", window);
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }