@Override
 public List<String> getSearchComponentNames() {
   final List<String> result = new ArrayList<String>();
   for (final SearchServiceComponent cs : searchServiceComponentRegistry.getAll()) {
     result.add(cs.getClass().getName());
   }
   return result;
 }
 @Override
 public void run() {
   try {
     threadResult.set(searchServiceComponent.search(sessionIdentifier, query, maxResults));
   } catch (final Exception e) {
     logger.error(e.getClass().getSimpleName(), e);
   }
 }
  @Test
  public void testSearchSpecial() throws Exception {
    final Logger logger = EasyMock.createNiceMock(Logger.class);
    EasyMock.replay(logger);

    final SessionIdentifier sessionIdentifier = new SessionIdentifier("sessionId");
    final int maxResults = 1337;

    final SearchQueryHistoryDao searchQueryHistoryDao = null;
    final IdGeneratorUUID idGeneratorUUID = null;

    final List<SearchResult> list = Arrays.asList();
    final SearchServiceComponent searchServiceComponent =
        EasyMock.createMock(SearchServiceComponent.class);
    EasyMock.expect(searchServiceComponent.search(sessionIdentifier, "bar", maxResults))
        .andReturn(list);
    EasyMock.replay(searchServiceComponent);

    final SearchServiceComponentRegistry searchServiceComponentRegistry =
        EasyMock.createNiceMock(SearchServiceComponentRegistry.class);
    EasyMock.expect(searchServiceComponentRegistry.get("foo")).andReturn(searchServiceComponent);
    EasyMock.replay(searchServiceComponentRegistry);

    final ThreadRunner threadRunner = new ThreadRunnerMock();

    final SearchServiceSearchResultComparator searchServiceComponentComparator = null;

    final AuthenticationService authenticationService =
        EasyMock.createNiceMock(AuthenticationService.class);
    EasyMock.expect(authenticationService.getCurrentUser(sessionIdentifier)).andReturn(null);
    EasyMock.replay(authenticationService);

    final SearchService searchService =
        new SearchServiceImpl(
            logger,
            authenticationService,
            searchQueryHistoryDao,
            idGeneratorUUID,
            searchServiceComponentRegistry,
            threadRunner,
            searchServiceComponentComparator);
    searchService.search(sessionIdentifier, "foo: bar", maxResults);

    EasyMock.verify(searchServiceComponentRegistry, searchServiceComponent);
  }
  private List<SearchResult> search(
      final List<SearchServiceComponent> searchServiceComponents,
      final String query,
      final SessionIdentifier sessionIdentifier,
      final int maxResults) {

    final List<Thread> threads = new ArrayList<Thread>();
    final List<ThreadResult<List<SearchResult>>> threadResults =
        new ArrayList<ThreadResult<List<SearchResult>>>();

    for (final SearchServiceComponent searchServiceComponent : searchServiceComponents) {
      logger.trace(
          "search in searchServiceComponent: " + searchServiceComponent.getClass().getSimpleName());

      final ThreadResult<List<SearchResult>> threadResult = new ThreadResult<List<SearchResult>>();
      threadResults.add(threadResult);
      threads.add(
          threadRunner.run(
              "search",
              new SearchThreadRunner(
                  searchServiceComponent, threadResult, sessionIdentifier, query, maxResults)));
    }

    for (final Thread thread : threads) {
      try {
        thread.join();
      } catch (final InterruptedException e) {
        // nop
      }
    }

    final List<SearchResult> result = new ArrayList<SearchResult>();
    for (final ThreadResult<List<SearchResult>> threadResult : threadResults) {
      final List<SearchResult> list = threadResult.get();
      if (list != null) {
        result.addAll(list);
      }
    }
    Collections.sort(result, searchServiceComponentComparator);
    logger.trace("found " + result.size() + " results");
    return result;
  }