@Test
  public void shouldReturnTokensFromSearch() throws CoreTokenException {
    // Given
    final Collection<Entry> entries = new LinkedList<Entry>();
    entries.add(new LinkedHashMapEntry());
    entries.add(new LinkedHashMapEntry());

    // Slightly more fiddly mocking to provide behaviour when the mock is called.
    given(
            searchHandler.performSearch(
                any(Connection.class), any(SearchRequest.class), any(Collection.class)))
        .will(
            new Answer() {
              public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
                Collection<Entry> list = (Collection<Entry>) invocationOnMock.getArguments()[2];
                list.addAll(entries);
                return null;
              }
            });

    // Ensure that the Token Conversion returns a Token
    given(tokenEntryConverter.convert(any(Entry.class), any(String[].class)))
        .willReturn(new Token(Long.toString(System.currentTimeMillis()), TokenType.SESSION));

    // When
    Iterator<Collection<Token>> results = builder.execute(mockConnection);

    // Then
    verifyZeroInteractions(tokenEntryConverter);
    assertThat(results.next().size()).isEqualTo(entries.size());
    verify(tokenEntryConverter, times(2)).convert(any(Entry.class), any(String[].class));
  }
  @Test
  public void shouldUseHandlerToPerformSearch() throws CoreTokenException, IOException {
    // Given
    Result mockResult = mock(Result.class);
    given(
            searchHandler.performSearch(
                any(Connection.class), any(SearchRequest.class), any(Collection.class)))
        .willReturn(mockResult);

    // When
    Iterator iterator = builder.executeRawResults(mockConnection, PartialToken.class);

    // Then
    verifyZeroInteractions(searchHandler);
    iterator.next();
    verify(searchHandler)
        .performSearch(eq(mockConnection), any(SearchRequest.class), any(Collection.class));
  }
  /**
   * Unit test for OPENDJ-1247: a locally timed out request which is not a bind or startTLS should
   * result in a client side timeout error, but the connection should remain valid. In addition, no
   * abandon request should be sent.
   */
  @Test
  public void testClientSideTimeoutForSearchRequest() throws Exception {
    resetState();
    registerSearchEvent();
    registerAbandonEvent();

    for (int i = 0; i < ITERATIONS; i++) {
      final Connection connection = factory.getConnection();
      try {
        waitForConnect();
        final ConnectionEventListener listener = mock(ConnectionEventListener.class);
        connection.addConnectionEventListener(listener);
        final PromiseImpl<LdapException, NeverThrowsException> promise = PromiseImpl.create();
        final LdapPromise<SearchResultEntry> connectionPromise =
            connection.readEntryAsync(DN.valueOf("cn=test"), null);
        connectionPromise.onFailure(getFailureHandler(promise));
        waitForSearch();

        LdapException e = promise.getOrThrow(TEST_TIMEOUT, TimeUnit.SECONDS);
        verifyResultCodeIsClientSideTimeout(e);
        // Wait for the request to timeout.
        try {
          connectionPromise.getOrThrow(TEST_TIMEOUT, TimeUnit.SECONDS);
          fail("The search request succeeded unexpectedly");
        } catch (TimeoutResultException te) {
          verifyResultCodeIsClientSideTimeout(te);
        }

        // The connection should still be valid.
        assertThat(connection.isValid()).isTrue();
        verifyZeroInteractions(listener);
        /*
         * FIXME: The search should have been abandoned (see comment in
         * LDAPConnection for explanation).
         */
        // waitForAbandon();
      } finally {
        connection.close();
      }
    }
  }