/** {@inheritDoc} */
  @Override
  public Collection<Response<SearchResult>> search(
      final PooledConnectionFactory[] factories,
      final SearchFilter[] filters,
      final String[] attrs,
      final SearchEntryHandler... handlers)
      throws LdapException {
    final CompletionService<Response<SearchResult>> searches =
        new ExecutorCompletionService<Response<SearchResult>>(getExecutorService());
    final List<Future<Response<SearchResult>>> futures =
        new ArrayList<Future<Response<SearchResult>>>(factories.length * filters.length);
    for (ConnectionFactory factory : factories) {
      for (SearchFilter filter : filters) {
        final SearchRequest sr = newSearchRequest(this);
        if (filter != null) {
          sr.setSearchFilter(filter);
        }
        if (attrs != null) {
          sr.setReturnAttributes(attrs);
        }
        if (handlers != null) {
          sr.setSearchEntryHandlers(handlers);
        }

        final Connection conn = factory.getConnection();
        final SearchOperation op = createSearchOperation(conn);
        futures.add(searches.submit(createCallable(conn, op, sr)));
      }
    }

    final List<Response<SearchResult>> responses =
        new ArrayList<Response<SearchResult>>(factories.length * filters.length);
    for (Future<Response<SearchResult>> future : futures) {
      try {
        responses.add(future.get());
      } catch (ExecutionException e) {
        logger.debug("ExecutionException thrown, ignoring", e);
      } catch (InterruptedException e) {
        logger.warn("InterruptedException thrown, ignoring", e);
      }
    }
    return responses;
  }
 /** {@inheritDoc} */
 @Override
 protected Connection getConnection() throws LdapException {
   final Connection conn = factory.getConnection();
   conn.open();
   return conn;
 }