/**
   * Prepare the search parameters and call the contactInfoService finder. Automatically called by
   * PrimeFaces component.
   */
  @Override
  public List<ContactInfo> load(
      int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
    SearchTemplate st = new SearchTemplate(getSearchTemplate());
    st.add(getBirthDateRange());
    st.add(getOtherDateRange());

    // total count so the paginator may display the total number of pages
    this.setRowCount(contactInfoService.findCount(getContactInfo(), st));

    // load one page of data
    populateSearchTemplate(st, first, pageSize, sortField, sortOrder, filters);
    return contactInfoService.find(getContactInfo(), st);
  }
  /**
   * Constructs a new search template and initializes it with the values of the passed search
   * template.
   */
  public SearchTemplate(SearchTemplate searchTemplate) {
    setSearchMode(searchTemplate.getSearchMode());
    setNamedQuery(searchTemplate.getNamedQuery());

    // copy parameters
    for (Entry<String, Object> entry : searchTemplate.getParameters().entrySet()) {
      addParameter(entry.getKey(), entry.getValue());
    }

    setSearchPattern(searchTemplate.getSearchPattern());
    setCaseSensitive(searchTemplate.isCaseSensitive());

    // copy order by
    for (OrderBy ob : searchTemplate.getOrderBys()) {
      addOrderBy(ob); // order by is read-only, we can use the same
    }

    setFirstResult(searchTemplate.getFirstResult());
    setMaxResults(searchTemplate.getMaxResults());

    // copy date ranges
    for (DateRange dr : searchTemplate.getDateRanges()) {
      add(new DateRange(dr)); // date range is not readonly, we must clone it
    }

    // copy criterions
    for (Criterion c : searchTemplate.getCriterions()) {
      addCriterion(c); // criterion is read-only, we can use the same
    }

    setCacheable(searchTemplate.isCacheable());
    setCacheRegion(searchTemplate.getCacheRegion());
  }