From 32034d853f3a284424ccfa87b6de210f1ca814e1 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 29 Nov 2011 00:31:21 +0000
Subject: [PATCH] Fix OPENDJ-43 (Synchronous Connection decorator implementations should not use AsynchronousConnections) and OPENDJ-328 (Make it easier to implement connection decorators).

---
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ResultHandler.java                            |    3 
 opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/Main.java                 |   47 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/IntermediateResponseHandler.java              |   17 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java                     |   25 
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPExtendedFutureResultImpl.java             |    3 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java                    |   12 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java                    |   15 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connection.java                               |  581 +++++-
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionPool.java                           |   11 
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java                |   70 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactoryAdapter.java             |  139 
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPCompareFutureResultImpl.java              |    5 
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java                           |  102 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LoadBalancer.java                             |   23 
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ConnectionDecorator.java                      |  766 ++++++++
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandler.java                           |   83 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RootDSE.java                                  |   14 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java                            |   22 
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/InternalConnection.java                       |   53 
 opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/Main.java                  |  202 +-
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionFactory.java                        |   17 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/InternalConnectionFactory.java                |   29 
 opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionFactoryTestCase.java                |   63 
 opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java                     |   16 
 opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java                               |   87 
 opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/modify/Main.java                 |    4 
 opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ModRate.java                        |   12 
 opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java              |   52 
 opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthenticatedConnectionFactory.java |  209 -
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPFutureResultImpl.java                     |    5 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AuthenticatedConnectionFactory.java           |  113 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java                      |  610 +++---
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPSearchFutureResultImpl.java               |    5 
 opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnectionTestCase.java   |  605 ++++++
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java           |  491 +---
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java               |   94 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java           |   58 
 /dev/null                                                                                                     |  186 --
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/SearchResultHandler.java                      |    3 
 opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/searchasync/Main.java            |   17 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java                              |   12 
 opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java                     |   61 
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/AbstractLDAPFutureResultImpl.java             |    7 
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPBindFutureResultImpl.java                 |    5 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java                       |  334 +++
 opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthRate.java                       |   28 
 46 files changed, 3,539 insertions(+), 1,777 deletions(-)

diff --git a/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/modify/Main.java b/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/modify/Main.java
index d235076..8c9f116 100644
--- a/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/modify/Main.java
+++ b/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/modify/Main.java
@@ -109,8 +109,8 @@
       connection.bind(userName, password.toCharArray());
 
       // Write the changes.
-      final ConnectionChangeRecordWriter writer = new ConnectionChangeRecordWriter(
-          connection);
+      final ConnectionChangeRecordWriter writer =
+          new ConnectionChangeRecordWriter(connection);
       while (reader.hasNext())
       {
         ChangeRecord changeRecord = reader.readChangeRecord();
diff --git a/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/Main.java b/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/Main.java
index ae2d8f7..c3d435e 100644
--- a/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/Main.java
+++ b/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/Main.java
@@ -84,12 +84,11 @@
         implements ResultHandler<R>
     {
       final H resultHandler;
-      final AsynchronousConnection connection;
+      final Connection connection;
 
 
 
-      AbstractRequestCompletionHandler(
-          final AsynchronousConnection connection,
+      AbstractRequestCompletionHandler(final Connection connection,
           final H resultHandler)
       {
         this.connection = connection;
@@ -99,8 +98,7 @@
 
 
       @Override
-      public final void handleErrorResult(
-          final ErrorResultException error)
+      public final void handleErrorResult(final ErrorResultException error)
       {
         connection.close();
         resultHandler.handleErrorResult(error);
@@ -120,14 +118,13 @@
 
 
     private abstract class ConnectionCompletionHandler<R extends Result>
-        implements ResultHandler<AsynchronousConnection>
+        implements ResultHandler<Connection>
     {
       private final ResultHandler<? super R> resultHandler;
 
 
 
-      ConnectionCompletionHandler(
-          final ResultHandler<? super R> resultHandler)
+      ConnectionCompletionHandler(final ResultHandler<? super R> resultHandler)
       {
         this.resultHandler = resultHandler;
       }
@@ -135,8 +132,7 @@
 
 
       @Override
-      public final void handleErrorResult(
-          final ErrorResultException error)
+      public final void handleErrorResult(final ErrorResultException error)
       {
         resultHandler.handleErrorResult(error);
       }
@@ -144,19 +140,16 @@
 
 
       @Override
-      public abstract void handleResult(
-          AsynchronousConnection connection);
+      public abstract void handleResult(Connection connection);
 
     }
 
 
 
-    private final class RequestCompletionHandler<R extends Result>
-        extends
+    private final class RequestCompletionHandler<R extends Result> extends
         AbstractRequestCompletionHandler<R, ResultHandler<? super R>>
     {
-      RequestCompletionHandler(
-          final AsynchronousConnection connection,
+      RequestCompletionHandler(final Connection connection,
           final ResultHandler<? super R> resultHandler)
       {
         super(connection, resultHandler);
@@ -166,12 +159,11 @@
 
 
     private final class SearchRequestCompletionHandler extends
-        AbstractRequestCompletionHandler<Result, SearchResultHandler>
-        implements SearchResultHandler
+        AbstractRequestCompletionHandler<Result, SearchResultHandler> implements
+        SearchResultHandler
     {
 
-      SearchRequestCompletionHandler(
-          final AsynchronousConnection connection,
+      SearchRequestCompletionHandler(final Connection connection,
           final SearchResultHandler resultHandler)
       {
         super(connection, resultHandler);
@@ -214,28 +206,27 @@
     @Override
     public void handleAdd(final RequestContext requestContext,
         final AddRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       addProxiedAuthControl(request);
       final ConnectionCompletionHandler<Result> outerHandler =
-        new ConnectionCompletionHandler<Result>(resultHandler)
+          new ConnectionCompletionHandler<Result>(resultHandler)
       {
 
         @Override
-        public void handleResult(
-            final AsynchronousConnection connection)
+        public void handleResult(final Connection connection)
         {
           final RequestCompletionHandler<Result> innerHandler =
-            new RequestCompletionHandler<Result>(connection, resultHandler);
-          connection.add(request, innerHandler,
-              intermediateResponseHandler);
+              new RequestCompletionHandler<Result>(connection, resultHandler);
+          connection.addAsync(request, intermediateResponseHandler,
+              innerHandler);
         }
 
       };
 
-      factory.getAsynchronousConnection(outerHandler);
+      factory.getConnectionAsync(outerHandler);
     }
 
 
@@ -246,8 +237,8 @@
     @Override
     public void handleBind(final RequestContext requestContext,
         final int version, final BindRequest request,
-        final ResultHandler<? super BindResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super BindResult> resultHandler)
         throws UnsupportedOperationException
     {
 
@@ -264,14 +255,14 @@
         // Authenticate using a separate bind connection pool, because we
         // don't want to change the state of the pooled connection.
         final ConnectionCompletionHandler<BindResult> outerHandler =
-          new ConnectionCompletionHandler<BindResult>(resultHandler)
+            new ConnectionCompletionHandler<BindResult>(resultHandler)
         {
 
           @Override
-          public void handleResult(
-              final AsynchronousConnection connection)
+          public void handleResult(final Connection connection)
           {
-            final ResultHandler<BindResult> innerHandler = new ResultHandler<BindResult>()
+            final ResultHandler<BindResult> innerHandler =
+                new ResultHandler<BindResult>()
             {
 
               @Override
@@ -293,14 +284,14 @@
                 resultHandler.handleResult(result);
               }
             };
-            connection.bind(request, innerHandler,
-                intermediateResponseHandler);
+            connection.bindAsync(request, intermediateResponseHandler,
+                innerHandler);
           }
 
         };
 
         proxiedAuthControl = null;
-        bindFactory.getAsynchronousConnection(outerHandler);
+        bindFactory.getConnectionAsync(outerHandler);
       }
     }
 
@@ -312,28 +303,28 @@
     @Override
     public void handleCompare(final RequestContext requestContext,
         final CompareRequest request,
-        final ResultHandler<? super CompareResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super CompareResult> resultHandler)
         throws UnsupportedOperationException
     {
       addProxiedAuthControl(request);
       final ConnectionCompletionHandler<CompareResult> outerHandler =
-        new ConnectionCompletionHandler<CompareResult>(resultHandler)
+          new ConnectionCompletionHandler<CompareResult>(resultHandler)
       {
 
         @Override
-        public void handleResult(
-            final AsynchronousConnection connection)
+        public void handleResult(final Connection connection)
         {
           final RequestCompletionHandler<CompareResult> innerHandler =
-            new RequestCompletionHandler<CompareResult>(connection, resultHandler);
-          connection.compare(request, innerHandler,
-              intermediateResponseHandler);
+              new RequestCompletionHandler<CompareResult>(connection,
+                  resultHandler);
+          connection.compareAsync(request, intermediateResponseHandler,
+              innerHandler);
         }
 
       };
 
-      factory.getAsynchronousConnection(outerHandler);
+      factory.getConnectionAsync(outerHandler);
     }
 
 
@@ -344,28 +335,27 @@
     @Override
     public void handleDelete(final RequestContext requestContext,
         final DeleteRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       addProxiedAuthControl(request);
       final ConnectionCompletionHandler<Result> outerHandler =
-        new ConnectionCompletionHandler<Result>(resultHandler)
+          new ConnectionCompletionHandler<Result>(resultHandler)
       {
 
         @Override
-        public void handleResult(
-            final AsynchronousConnection connection)
+        public void handleResult(final Connection connection)
         {
           final RequestCompletionHandler<Result> innerHandler =
-            new RequestCompletionHandler<Result>(connection, resultHandler);
-          connection.delete(request, innerHandler,
-              intermediateResponseHandler);
+              new RequestCompletionHandler<Result>(connection, resultHandler);
+          connection.deleteAsync(request, intermediateResponseHandler,
+              innerHandler);
         }
 
       };
 
-      factory.getAsynchronousConnection(outerHandler);
+      factory.getConnectionAsync(outerHandler);
     }
 
 
@@ -375,10 +365,9 @@
      */
     @Override
     public <R extends ExtendedResult> void handleExtendedRequest(
-        final RequestContext requestContext,
-        final ExtendedRequest<R> request,
-        final ResultHandler<? super R> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final RequestContext requestContext, final ExtendedRequest<R> request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super R> resultHandler)
         throws UnsupportedOperationException
     {
       if (request.getOID().equals(CancelExtendedRequest.OID))
@@ -401,22 +390,21 @@
         addProxiedAuthControl(request);
 
         final ConnectionCompletionHandler<R> outerHandler =
-          new ConnectionCompletionHandler<R>(resultHandler)
+            new ConnectionCompletionHandler<R>(resultHandler)
         {
 
           @Override
-          public void handleResult(
-              final AsynchronousConnection connection)
+          public void handleResult(final Connection connection)
           {
             final RequestCompletionHandler<R> innerHandler =
-              new RequestCompletionHandler<R>(connection, resultHandler);
-            connection.extendedRequest(request, innerHandler,
-                intermediateResponseHandler);
+                new RequestCompletionHandler<R>(connection, resultHandler);
+            connection.extendedRequestAsync(request,
+                intermediateResponseHandler, innerHandler);
           }
 
         };
 
-        factory.getAsynchronousConnection(outerHandler);
+        factory.getConnectionAsync(outerHandler);
       }
     }
 
@@ -428,28 +416,27 @@
     @Override
     public void handleModify(final RequestContext requestContext,
         final ModifyRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       addProxiedAuthControl(request);
       final ConnectionCompletionHandler<Result> outerHandler =
-        new ConnectionCompletionHandler<Result>(resultHandler)
+          new ConnectionCompletionHandler<Result>(resultHandler)
       {
 
         @Override
-        public void handleResult(
-            final AsynchronousConnection connection)
+        public void handleResult(final Connection connection)
         {
           final RequestCompletionHandler<Result> innerHandler =
-            new RequestCompletionHandler<Result>(connection, resultHandler);
-          connection.modify(request, innerHandler,
-              intermediateResponseHandler);
+              new RequestCompletionHandler<Result>(connection, resultHandler);
+          connection.modifyAsync(request, intermediateResponseHandler,
+              innerHandler);
         }
 
       };
 
-      factory.getAsynchronousConnection(outerHandler);
+      factory.getConnectionAsync(outerHandler);
     }
 
 
@@ -460,28 +447,27 @@
     @Override
     public void handleModifyDN(final RequestContext requestContext,
         final ModifyDNRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       addProxiedAuthControl(request);
       final ConnectionCompletionHandler<Result> outerHandler =
-        new ConnectionCompletionHandler<Result>(resultHandler)
+          new ConnectionCompletionHandler<Result>(resultHandler)
       {
 
         @Override
-        public void handleResult(
-            final AsynchronousConnection connection)
+        public void handleResult(final Connection connection)
         {
           final RequestCompletionHandler<Result> innerHandler =
-            new RequestCompletionHandler<Result>(connection, resultHandler);
-          connection.modifyDN(request, innerHandler,
-              intermediateResponseHandler);
+              new RequestCompletionHandler<Result>(connection, resultHandler);
+          connection.modifyDNAsync(request, intermediateResponseHandler,
+              innerHandler);
         }
 
       };
 
-      factory.getAsynchronousConnection(outerHandler);
+      factory.getConnectionAsync(outerHandler);
     }
 
 
@@ -492,28 +478,27 @@
     @Override
     public void handleSearch(final RequestContext requestContext,
         final SearchRequest request,
-        final SearchResultHandler resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final SearchResultHandler resultHandler)
         throws UnsupportedOperationException
     {
       addProxiedAuthControl(request);
       final ConnectionCompletionHandler<Result> outerHandler =
-        new ConnectionCompletionHandler<Result>(resultHandler)
+          new ConnectionCompletionHandler<Result>(resultHandler)
       {
 
         @Override
-        public void handleResult(
-            final AsynchronousConnection connection)
+        public void handleResult(final Connection connection)
         {
           final SearchRequestCompletionHandler innerHandler =
-            new SearchRequestCompletionHandler(connection, resultHandler);
-          connection.search(request, innerHandler,
-              intermediateResponseHandler);
+              new SearchRequestCompletionHandler(connection, resultHandler);
+          connection.searchAsync(request, intermediateResponseHandler,
+              innerHandler);
         }
 
       };
 
-      factory.getAsynchronousConnection(outerHandler);
+      factory.getConnectionAsync(outerHandler);
     }
 
 
@@ -552,8 +537,10 @@
     final int localPort = Integer.parseInt(args[1]);
 
     // Create load balancer.
-    final List<ConnectionFactory> factories = new LinkedList<ConnectionFactory>();
-    final List<ConnectionFactory> bindFactories = new LinkedList<ConnectionFactory>();
+    final List<ConnectionFactory> factories =
+        new LinkedList<ConnectionFactory>();
+    final List<ConnectionFactory> bindFactories =
+        new LinkedList<ConnectionFactory>();
     for (int i = 2; i < args.length; i += 2)
     {
       final String remoteAddress = args[i];
@@ -566,19 +553,18 @@
           new LDAPConnectionFactory(remoteAddress, remotePort),
           Integer.MAX_VALUE));
     }
-    final RoundRobinLoadBalancingAlgorithm algorithm = new RoundRobinLoadBalancingAlgorithm(
-        factories);
-    final RoundRobinLoadBalancingAlgorithm bindAlgorithm = new RoundRobinLoadBalancingAlgorithm(
-        bindFactories);
-    final ConnectionFactory factory = Connections
-        .newLoadBalancer(algorithm);
+    final RoundRobinLoadBalancingAlgorithm algorithm =
+        new RoundRobinLoadBalancingAlgorithm(factories);
+    final RoundRobinLoadBalancingAlgorithm bindAlgorithm =
+        new RoundRobinLoadBalancingAlgorithm(bindFactories);
+    final ConnectionFactory factory = Connections.newLoadBalancer(algorithm);
     final ConnectionFactory bindFactory = Connections
         .newLoadBalancer(bindAlgorithm);
 
     // Create a server connection adapter.
     final ProxyBackend backend = new ProxyBackend(factory, bindFactory);
-    final ServerConnectionFactory<LDAPClientContext, Integer> connectionHandler =
-      Connections.newServerConnectionFactory(backend);
+    final ServerConnectionFactory<LDAPClientContext, Integer> connectionHandler
+      = Connections.newServerConnectionFactory(backend);
 
     // Create listener.
     final LDAPListenerOptions options = new LDAPListenerOptions()
@@ -586,15 +572,15 @@
     LDAPListener listener = null;
     try
     {
-      listener = new LDAPListener(localAddress, localPort,
-          connectionHandler, options);
+      listener = new LDAPListener(localAddress, localPort, connectionHandler,
+          options);
       System.out.println("Press any key to stop the server...");
       System.in.read();
     }
     catch (final IOException e)
     {
-      System.out.println("Error listening on " + localAddress + ":"
-          + localPort);
+      System.out
+          .println("Error listening on " + localAddress + ":" + localPort);
       e.printStackTrace();
     }
     finally
diff --git a/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/searchasync/Main.java b/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/searchasync/Main.java
index a5cb073..95ff441 100644
--- a/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/searchasync/Main.java
+++ b/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/searchasync/Main.java
@@ -78,7 +78,7 @@
       // Bind succeeded: initiate search.
       final SearchRequest request = Requests.newSearchRequest(baseDN,
           scope, filter, attributes);
-      connection.search(request, new SearchResultHandlerImpl());
+      connection.searchAsync(request, null, new SearchResultHandlerImpl());
     }
 
   }
@@ -86,7 +86,7 @@
 
 
   private static final class ConnectResultHandlerImpl implements
-      ResultHandler<AsynchronousConnection>
+      ResultHandler<Connection>
   {
 
     /**
@@ -106,14 +106,14 @@
      * {@inheritDoc}
      */
     @Override
-    public void handleResult(final AsynchronousConnection connection)
+    public void handleResult(final Connection connection)
     {
       // Connect succeeded: save connection and initiate bind.
       Main.connection = connection;
 
       final BindRequest request = Requests.newSimpleBindRequest(
           userName, password.toCharArray());
-      connection.bind(request, new BindResultHandlerImpl());
+      connection.bindAsync(request, null, new BindResultHandlerImpl());
     }
 
   }
@@ -207,15 +207,10 @@
   private static String userName;
   private static String password;
   private static String baseDN;
-
   private static SearchScope scope;
-
   private static String filter;
-
   private static String[] attributes;
-
-  private static AsynchronousConnection connection = null;
-
+  private static Connection connection = null;
   private static int resultCode = 0;
 
 
@@ -280,7 +275,7 @@
     // Initiate the asynchronous connect, bind, and search.
     final LDAPConnectionFactory factory = new LDAPConnectionFactory(
         hostName, port);
-    factory.getAsynchronousConnection(new ConnectResultHandlerImpl());
+    factory.getConnectionAsync(new ConnectResultHandlerImpl());
 
     // Await completion.
     try
diff --git a/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/Main.java b/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/Main.java
index a1bd415..bc6ee6c 100644
--- a/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/Main.java
+++ b/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/Main.java
@@ -68,8 +68,8 @@
       RequestHandler<RequestContext>
   {
     private final ConcurrentSkipListMap<DN, Entry> entries;
-
-    private final ReentrantReadWriteLock entryLock = new ReentrantReadWriteLock();
+    private final ReentrantReadWriteLock entryLock =
+        new ReentrantReadWriteLock();
 
 
 
@@ -87,8 +87,8 @@
     @Override
     public void handleAdd(final RequestContext requestContext,
         final AddRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       // TODO: controls.
@@ -132,8 +132,8 @@
     @Override
     public void handleBind(final RequestContext requestContext,
         final int version, final BindRequest request,
-        final ResultHandler<? super BindResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super BindResult> resultHandler)
         throws UnsupportedOperationException
     {
       if (request.getAuthenticationType() != ((byte) 0x80))
@@ -160,8 +160,8 @@
     @Override
     public void handleCompare(final RequestContext requestContext,
         final CompareRequest request,
-        final ResultHandler<? super CompareResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super CompareResult> resultHandler)
         throws UnsupportedOperationException
     {
       // TODO:
@@ -175,8 +175,8 @@
     @Override
     public void handleDelete(final RequestContext requestContext,
         final DeleteRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       // TODO: controls.
@@ -213,8 +213,8 @@
     public <R extends ExtendedResult> void handleExtendedRequest(
         final RequestContext requestContext,
         final ExtendedRequest<R> request,
-        final ResultHandler<? super R> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super R> resultHandler)
         throws UnsupportedOperationException
     {
       // TODO: not implemented.
@@ -231,8 +231,8 @@
     @Override
     public void handleModify(final RequestContext requestContext,
         final ModifyRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       // TODO: controls.
@@ -272,8 +272,8 @@
           {
             resultHandler
                 .handleErrorResult(newErrorResult(
-                    ResultCode.PROTOCOL_ERROR,
-                    "Modify request contains an unsupported modification type"));
+                  ResultCode.PROTOCOL_ERROR,
+                  "Modify request contains an unsupported modification type"));
             return;
           }
         }
@@ -296,8 +296,8 @@
     @Override
     public void handleModifyDN(final RequestContext requestContext,
         final ModifyDNRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       // TODO: not implemented.
@@ -314,8 +314,8 @@
     @Override
     public void handleSearch(final RequestContext requestContext,
         final SearchRequest request,
-        final SearchResultHandler resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final SearchResultHandler resultHandler)
         throws UnsupportedOperationException
     {
       // TODO: controls, limits, etc.
@@ -458,12 +458,13 @@
     final String ldifFileName = args[2];
 
     // Create the memory backend.
-    final ConcurrentSkipListMap<DN, Entry> entries = readEntriesFromLDIF(ldifFileName);
+    final ConcurrentSkipListMap<DN, Entry> entries =
+        readEntriesFromLDIF(ldifFileName);
     final MemoryBackend backend = new MemoryBackend(entries);
 
     // Create a server connection adapter.
-    final ServerConnectionFactory<LDAPClientContext, Integer> connectionHandler =
-      Connections.newServerConnectionFactory(backend);
+    final ServerConnectionFactory<LDAPClientContext, Integer> connectionHandler
+      = Connections.newServerConnectionFactory(backend);
 
     // Create listener.
     final LDAPListenerOptions options = new LDAPListenerOptions()
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/AbstractLDAPFutureResultImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/AbstractLDAPFutureResultImpl.java
index 9ba5157..a46aabe 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/AbstractLDAPFutureResultImpl.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/AbstractLDAPFutureResultImpl.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package com.forgerock.opendj.ldap;
@@ -47,7 +48,7 @@
 abstract class AbstractLDAPFutureResultImpl<S extends Result> extends
     AsynchronousFutureResult<S> implements IntermediateResponseHandler
 {
-  private final AsynchronousConnection connection;
+  private final Connection connection;
 
   private final int requestID;
 
@@ -60,7 +61,7 @@
   AbstractLDAPFutureResultImpl(final int requestID,
       final ResultHandler<? super S> resultHandler,
       final IntermediateResponseHandler intermediateResponseHandler,
-      final AsynchronousConnection connection)
+      final Connection connection)
   {
     super(resultHandler);
     this.requestID = requestID;
@@ -113,7 +114,7 @@
   protected final ErrorResultException handleCancelRequest(
       final boolean mayInterruptIfRunning)
   {
-    connection.abandon(Requests.newAbandonRequest(requestID));
+    connection.abandonAsync(Requests.newAbandonRequest(requestID));
     return null;
   }
 
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/InternalConnection.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/InternalConnection.java
index f528b74..a4637fc 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/InternalConnection.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/InternalConnection.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package com.forgerock.opendj.ldap;
@@ -60,7 +61,7 @@
         final BindRequest bindRequest,
         final ResultHandler<? super BindResult> resultHandler,
         final IntermediateResponseHandler intermediateResponseHandler,
-        final AsynchronousConnection connection)
+        final Connection connection)
     {
       super(messageID, resultHandler, intermediateResponseHandler, connection);
       this.bindRequest = bindRequest;
@@ -120,7 +121,7 @@
    * {@inheritDoc}
    */
   @Override
-  public FutureResult<Void> abandon(final AbandonRequest request)
+  public FutureResult<Void> abandonAsync(final AbandonRequest request)
       throws UnsupportedOperationException, IllegalStateException,
       NullPointerException
   {
@@ -135,9 +136,9 @@
    * {@inheritDoc}
    */
   @Override
-  public FutureResult<Result> add(final AddRequest request,
-      final ResultHandler<? super Result> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<Result> addAsync(final AddRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super Result> resultHandler)
       throws UnsupportedOperationException, IllegalStateException,
       NullPointerException
   {
@@ -167,9 +168,9 @@
    * {@inheritDoc}
    */
   @Override
-  public FutureResult<BindResult> bind(final BindRequest request,
-      final ResultHandler<? super BindResult> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<BindResult> bindAsync(final BindRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super BindResult> resultHandler)
       throws UnsupportedOperationException, IllegalStateException,
       NullPointerException
   {
@@ -198,9 +199,9 @@
    * {@inheritDoc}
    */
   @Override
-  public FutureResult<CompareResult> compare(final CompareRequest request,
-      final ResultHandler<? super CompareResult> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<CompareResult> compareAsync(final CompareRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super CompareResult> resultHandler)
       throws UnsupportedOperationException, IllegalStateException,
       NullPointerException
   {
@@ -217,9 +218,9 @@
    * {@inheritDoc}
    */
   @Override
-  public FutureResult<Result> delete(final DeleteRequest request,
-      final ResultHandler<? super Result> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<Result> deleteAsync(final DeleteRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super Result> resultHandler)
       throws UnsupportedOperationException, IllegalStateException,
       NullPointerException
   {
@@ -236,10 +237,10 @@
    * {@inheritDoc}
    */
   @Override
-  public <R extends ExtendedResult> FutureResult<R> extendedRequest(
+  public <R extends ExtendedResult> FutureResult<R> extendedRequestAsync(
       final ExtendedRequest<R> request,
-      final ResultHandler<? super R> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super R> resultHandler)
       throws UnsupportedOperationException, IllegalStateException,
       NullPointerException
   {
@@ -280,9 +281,9 @@
    * {@inheritDoc}
    */
   @Override
-  public FutureResult<Result> modify(final ModifyRequest request,
-      final ResultHandler<? super Result> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<Result> modifyAsync(final ModifyRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super Result> resultHandler)
       throws UnsupportedOperationException, IllegalStateException,
       NullPointerException
   {
@@ -299,9 +300,9 @@
    * {@inheritDoc}
    */
   @Override
-  public FutureResult<Result> modifyDN(final ModifyDNRequest request,
-      final ResultHandler<? super Result> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<Result> modifyDNAsync(final ModifyDNRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super Result> resultHandler)
       throws UnsupportedOperationException, IllegalStateException,
       NullPointerException
   {
@@ -331,9 +332,9 @@
    * {@inheritDoc}
    */
   @Override
-  public FutureResult<Result> search(final SearchRequest request,
-      final SearchResultHandler resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<Result> searchAsync(final SearchRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final SearchResultHandler resultHandler)
       throws UnsupportedOperationException, IllegalStateException,
       NullPointerException
   {
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPBindFutureResultImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPBindFutureResultImpl.java
index 8dd04b7..c790b86 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPBindFutureResultImpl.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPBindFutureResultImpl.java
@@ -23,13 +23,14 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package com.forgerock.opendj.ldap;
 
 
 
-import org.forgerock.opendj.ldap.AsynchronousConnection;
+import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.IntermediateResponseHandler;
 import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.opendj.ldap.ResultHandler;
@@ -52,7 +53,7 @@
   LDAPBindFutureResultImpl(final int requestID, final BindClient bindClient,
       final ResultHandler<? super BindResult> resultHandler,
       final IntermediateResponseHandler intermediateResponseHandler,
-      final AsynchronousConnection connection)
+      final Connection connection)
   {
     super(requestID, resultHandler, intermediateResponseHandler, connection);
     this.bindClient = bindClient;
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPCompareFutureResultImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPCompareFutureResultImpl.java
index dcf562c..326d8e3 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPCompareFutureResultImpl.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPCompareFutureResultImpl.java
@@ -23,13 +23,14 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package com.forgerock.opendj.ldap;
 
 
 
-import org.forgerock.opendj.ldap.AsynchronousConnection;
+import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.IntermediateResponseHandler;
 import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.opendj.ldap.ResultHandler;
@@ -53,7 +54,7 @@
       final CompareRequest request,
       final ResultHandler<? super CompareResult> resultHandler,
       final IntermediateResponseHandler intermediateResponseHandler,
-      final AsynchronousConnection connection)
+      final Connection connection)
   {
     super(requestID, resultHandler, intermediateResponseHandler, connection);
     this.request = request;
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java
index 705c271..5ad6c39 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java
@@ -66,31 +66,21 @@
  * TODO: handle illegal state exceptions.
  */
 final class LDAPConnection extends AbstractAsynchronousConnection implements
-    AsynchronousConnection
+    Connection
 {
   private final org.glassfish.grizzly.Connection<?> connection;
-
   private Result connectionInvalidReason;
-
   private FilterChain customFilterChain;
-
   private boolean isClosed = false;
-
   private final List<ConnectionEventListener> listeners =
-    new CopyOnWriteArrayList<ConnectionEventListener>();
-
+      new CopyOnWriteArrayList<ConnectionEventListener>();
   private final AtomicInteger nextMsgID = new AtomicInteger(1);
-
-  private final AtomicBoolean bindOrStartTLSInProgress =
-      new AtomicBoolean(false);
-
+  private final AtomicBoolean bindOrStartTLSInProgress = new AtomicBoolean(
+      false);
   private final ConcurrentHashMap<Integer, AbstractLDAPFutureResultImpl<?>> pendingRequests =
-    new ConcurrentHashMap<Integer, AbstractLDAPFutureResultImpl<?>>();
-
+      new ConcurrentHashMap<Integer, AbstractLDAPFutureResultImpl<?>>();
   private final Object stateLock = new Object();
-
   private final LDAPWriter ldapWriter = new LDAPWriter();
-
   private final LDAPOptions options;
 
 
@@ -115,7 +105,7 @@
   /**
    * {@inheritDoc}
    */
-  public FutureResult<Void> abandon(final AbandonRequest request)
+  public FutureResult<Void> abandonAsync(final AbandonRequest request)
   {
     final AbstractLDAPFutureResultImpl<?> pendingRequest;
     final int messageID = nextMsgID.getAndIncrement();
@@ -132,8 +122,8 @@
         final Result errorResult = Responses.newResult(
             ResultCode.OPERATIONS_ERROR).setDiagnosticMessage(
             "Bind or Start TLS operation in progress");
-        return new CompletedFutureResult<Void>(
-            newErrorResult(errorResult), messageID);
+        return new CompletedFutureResult<Void>(newErrorResult(errorResult),
+            messageID);
       }
 
       // First remove the future associated with the request to be abandoned.
@@ -173,8 +163,8 @@
       final Result errorResult = Responses.newResult(
           ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e);
       connectionErrorOccurred(errorResult);
-      return new CompletedFutureResult<Void>(
-          newErrorResult(errorResult), messageID);
+      return new CompletedFutureResult<Void>(newErrorResult(errorResult),
+          messageID);
     }
   }
 
@@ -183,9 +173,9 @@
   /**
    * {@inheritDoc}
    */
-  public FutureResult<Result> add(final AddRequest request,
-      final ResultHandler<? super Result> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<Result> addAsync(final AddRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super Result> resultHandler)
   {
     final int messageID = nextMsgID.getAndIncrement();
     final LDAPFutureResultImpl future = new LDAPFutureResultImpl(messageID,
@@ -253,9 +243,9 @@
   /**
    * {@inheritDoc}
    */
-  public FutureResult<BindResult> bind(final BindRequest request,
-      final ResultHandler<? super BindResult> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<BindResult> bindAsync(final BindRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super BindResult> resultHandler)
   {
     final int messageID = nextMsgID.getAndIncrement();
 
@@ -276,7 +266,8 @@
           .newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR)
           .setDiagnosticMessage(
               "An error occurred while creating a bind context").setCause(e);
-      final ErrorResultException error = ErrorResultException.newErrorResult(errorResult);
+      final ErrorResultException error = ErrorResultException
+          .newErrorResult(errorResult);
       if (resultHandler != null)
       {
         resultHandler.handleErrorResult(error);
@@ -371,9 +362,9 @@
   /**
    * {@inheritDoc}
    */
-  public FutureResult<CompareResult> compare(final CompareRequest request,
-      final ResultHandler<? super CompareResult> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<CompareResult> compareAsync(final CompareRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super CompareResult> resultHandler)
   {
     final int messageID = nextMsgID.getAndIncrement();
     final LDAPCompareFutureResultImpl future = new LDAPCompareFutureResultImpl(
@@ -429,9 +420,9 @@
   /**
    * {@inheritDoc}
    */
-  public FutureResult<Result> delete(final DeleteRequest request,
-      final ResultHandler<? super Result> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<Result> deleteAsync(final DeleteRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super Result> resultHandler)
   {
     final int messageID = nextMsgID.getAndIncrement();
     final LDAPFutureResultImpl future = new LDAPFutureResultImpl(messageID,
@@ -487,10 +478,10 @@
   /**
    * {@inheritDoc}
    */
-  public <R extends ExtendedResult> FutureResult<R> extendedRequest(
+  public <R extends ExtendedResult> FutureResult<R> extendedRequestAsync(
       final ExtendedRequest<R> request,
-      final ResultHandler<? super R> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super R> resultHandler)
   {
     final int messageID = nextMsgID.getAndIncrement();
     final LDAPExtendedFutureResultImpl<R> future = new LDAPExtendedFutureResultImpl<R>(
@@ -522,8 +513,8 @@
         if (!bindOrStartTLSInProgress.compareAndSet(false, true))
         {
           future.setResultOrError(request.getResultDecoder()
-                .newExtendedErrorResult(ResultCode.OPERATIONS_ERROR, "",
-                    "Bind or Start TLS operation in progress"));
+              .newExtendedErrorResult(ResultCode.OPERATIONS_ERROR, "",
+                  "Bind or Start TLS operation in progress"));
           return future;
         }
       }
@@ -532,8 +523,8 @@
         if (bindOrStartTLSInProgress.get())
         {
           future.setResultOrError(request.getResultDecoder()
-                .newExtendedErrorResult(ResultCode.OPERATIONS_ERROR, "",
-                    "Bind or Start TLS operation in progress"));
+              .newExtendedErrorResult(ResultCode.OPERATIONS_ERROR, "",
+                  "Bind or Start TLS operation in progress"));
           return future;
         }
       }
@@ -594,9 +585,9 @@
   /**
    * {@inheritDoc}
    */
-  public FutureResult<Result> modify(final ModifyRequest request,
-      final ResultHandler<? super Result> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<Result> modifyAsync(final ModifyRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super Result> resultHandler)
   {
     final int messageID = nextMsgID.getAndIncrement();
     final LDAPFutureResultImpl future = new LDAPFutureResultImpl(messageID,
@@ -652,9 +643,9 @@
   /**
    * {@inheritDoc}
    */
-  public FutureResult<Result> modifyDN(final ModifyDNRequest request,
-      final ResultHandler<? super Result> resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<Result> modifyDNAsync(final ModifyDNRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super Result> resultHandler)
   {
     final int messageID = nextMsgID.getAndIncrement();
     final LDAPFutureResultImpl future = new LDAPFutureResultImpl(messageID,
@@ -722,9 +713,9 @@
   /**
    * {@inheritDoc}
    */
-  public FutureResult<Result> search(final SearchRequest request,
-      final SearchResultHandler resultHandler,
-      final IntermediateResponseHandler intermediateResponseHandler)
+  public FutureResult<Result> searchAsync(final SearchRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final SearchResultHandler resultHandler)
   {
     final int messageID = nextMsgID.getAndIncrement();
     final LDAPSearchFutureResultImpl future = new LDAPSearchFutureResultImpl(
@@ -831,7 +822,7 @@
                 .newResult(ResultCode.CLIENT_SIDE_TIMEOUT);
             future.adaptErrorResult(result);
 
-            abandon(Requests.newAbandonRequest(future.getRequestID()));
+            abandonAsync(Requests.newAbandonRequest(future.getRequestID()));
           }
           else
           {
@@ -853,7 +844,8 @@
 
     synchronized (stateLock)
     {
-      if (isClosed) {
+      if (isClosed)
+      {
         // Already closed.
         return;
       }
@@ -1051,10 +1043,10 @@
 
     sslEngineConfigurator = new SSLEngineConfigurator(sslContext, true, false,
         false);
-    sslEngineConfigurator.setEnabledProtocols(protocols.isEmpty() ?
-        null : protocols.toArray(new String[protocols.size()]));
-    sslEngineConfigurator.setEnabledCipherSuites(cipherSuites.isEmpty() ?
-        null : cipherSuites.toArray(new String[cipherSuites.size()]));
+    sslEngineConfigurator.setEnabledProtocols(protocols.isEmpty() ? null
+        : protocols.toArray(new String[protocols.size()]));
+    sslEngineConfigurator.setEnabledCipherSuites(cipherSuites.isEmpty() ? null
+        : cipherSuites.toArray(new String[cipherSuites.size()]));
     sslFilter = new SSLFilter(null, sslEngineConfigurator);
     installFilter(sslFilter);
     sslFilter.handshake(connection, completionHandler);
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java
index 2674205..c7a6829 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java
@@ -44,14 +44,12 @@
 import org.forgerock.opendj.ldap.responses.ExtendedResult;
 import org.forgerock.opendj.ldap.responses.Result;
 import org.glassfish.grizzly.CompletionHandler;
-import org.glassfish.grizzly.Connection;
 import org.glassfish.grizzly.EmptyCompletionHandler;
 import org.glassfish.grizzly.filterchain.DefaultFilterChain;
 import org.glassfish.grizzly.filterchain.FilterChain;
 import org.glassfish.grizzly.filterchain.TransportFilter;
 import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
 
-import com.forgerock.opendj.util.AbstractConnectionFactory;
 import com.forgerock.opendj.util.CompletedFutureResult;
 import com.forgerock.opendj.util.FutureResultTransformer;
 import com.forgerock.opendj.util.RecursiveFutureResult;
@@ -61,25 +59,22 @@
 /**
  * LDAP connection factory implementation.
  */
-public final class LDAPConnectionFactoryImpl extends AbstractConnectionFactory
-    implements ConnectionFactory
+public final class LDAPConnectionFactoryImpl implements ConnectionFactory
 {
 
   @SuppressWarnings("rawtypes")
-  private final class FutureResultImpl implements CompletionHandler<Connection>
+  private final class FutureResultImpl implements
+      CompletionHandler<org.glassfish.grizzly.Connection>
   {
-    private final FutureResultTransformer<Result, AsynchronousConnection> futureStartTLSResult;
-
+    private final FutureResultTransformer<Result, Connection> futureStartTLSResult;
     private final RecursiveFutureResult<LDAPConnection, ExtendedResult> futureConnectionResult;
-
     private LDAPConnection connection;
 
 
 
-    private FutureResultImpl(
-        final ResultHandler<? super AsynchronousConnection> handler)
+    private FutureResultImpl(final ResultHandler<? super Connection> handler)
     {
-      this.futureStartTLSResult = new FutureResultTransformer<Result, AsynchronousConnection>(
+      this.futureStartTLSResult = new FutureResultTransformer<Result, Connection>(
           handler)
       {
 
@@ -129,13 +124,11 @@
           {
             final StartTLSExtendedRequest startTLS = Requests
                 .newStartTLSExtendedRequest(options.getSSLContext());
-            startTLS.addEnabledCipherSuite(
-                options.getEnabledCipherSuites().toArray(
-                    new String[options.getEnabledCipherSuites().size()]));
-            startTLS.addEnabledProtocol(
-                options.getEnabledProtocols().toArray(
-                    new String[options.getEnabledProtocols().size()]));
-            return connection.extendedRequest(startTLS, handler);
+            startTLS.addEnabledCipherSuite(options.getEnabledCipherSuites()
+                .toArray(new String[options.getEnabledCipherSuites().size()]));
+            startTLS.addEnabledProtocol(options.getEnabledProtocols().toArray(
+                new String[options.getEnabledProtocols().size()]));
+            return connection.extendedRequestAsync(startTLS, null, handler);
           }
 
           if (options.getSSLContext() != null)
@@ -167,8 +160,7 @@
             }
             catch (final IOException ioe)
             {
-              throw newErrorResult(
-                  ResultCode.CLIENT_SIDE_CONNECT_ERROR,
+              throw newErrorResult(ResultCode.CLIENT_SIDE_CONNECT_ERROR,
                   ioe.getMessage(), ioe);
             }
           }
@@ -187,6 +179,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public void cancelled()
     {
       // Ignore this.
@@ -197,7 +190,8 @@
     /**
      * {@inheritDoc}
      */
-    public void completed(final Connection connection)
+    @Override
+    public void completed(final org.glassfish.grizzly.Connection connection)
     {
       futureConnectionResult.handleResult(adaptConnection(connection));
     }
@@ -207,6 +201,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public void failed(final Throwable throwable)
     {
       futureConnectionResult
@@ -218,7 +213,8 @@
     /**
      * {@inheritDoc}
      */
-    public void updated(final Connection connection)
+    @Override
+    public void updated(final org.glassfish.grizzly.Connection connection)
     {
       // Ignore this.
     }
@@ -228,13 +224,9 @@
 
 
   private final SocketAddress socketAddress;
-
   private final TCPNIOTransport transport;
-
   private final FilterChain defaultFilterChain;
-
   private final LDAPClientFilter clientFilter;
-
   private final LDAPOptions options;
 
 
@@ -275,8 +267,20 @@
    * {@inheritDoc}
    */
   @Override
-  public FutureResult<AsynchronousConnection> getAsynchronousConnection(
-      final ResultHandler<? super AsynchronousConnection> handler)
+  public Connection getConnection() throws ErrorResultException,
+      InterruptedException
+  {
+    return getConnectionAsync(null).get();
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public FutureResult<Connection> getConnectionAsync(
+      final ResultHandler<? super Connection> handler)
   {
     final FutureResultImpl future = new FutureResultImpl(handler);
 
@@ -289,7 +293,7 @@
     catch (final IOException e)
     {
       final ErrorResultException result = adaptConnectionException(e);
-      return new CompletedFutureResult<AsynchronousConnection>(result);
+      return new CompletedFutureResult<Connection>(result);
     }
   }
 
@@ -310,6 +314,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public String toString()
   {
     final StringBuilder builder = new StringBuilder();
@@ -321,7 +326,8 @@
 
 
 
-  private LDAPConnection adaptConnection(final Connection<?> connection)
+  private LDAPConnection adaptConnection(
+      final org.glassfish.grizzly.Connection<?> connection)
   {
     // Test shows that its much faster with non block writes but risk
     // running out of memory if the server is slow.
@@ -343,7 +349,7 @@
       t = t.getCause();
     }
 
-    return newErrorResult(ResultCode.CLIENT_SIDE_CONNECT_ERROR,
-        t.getMessage(), t);
+    return newErrorResult(ResultCode.CLIENT_SIDE_CONNECT_ERROR, t.getMessage(),
+        t);
   }
 }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPExtendedFutureResultImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPExtendedFutureResultImpl.java
index 3ea5771..ccba5e7 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPExtendedFutureResultImpl.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPExtendedFutureResultImpl.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package com.forgerock.opendj.ldap;
@@ -53,7 +54,7 @@
       final ExtendedRequest<R> request,
       final ResultHandler<? super R> resultHandler,
       final IntermediateResponseHandler intermediateResponseHandler,
-      final AsynchronousConnection connection)
+      final Connection connection)
   {
     super(requestID, resultHandler, intermediateResponseHandler, connection);
     this.request = request;
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPFutureResultImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPFutureResultImpl.java
index 4061c01..f5a12ec 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPFutureResultImpl.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPFutureResultImpl.java
@@ -23,13 +23,14 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package com.forgerock.opendj.ldap;
 
 
 
-import org.forgerock.opendj.ldap.AsynchronousConnection;
+import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.IntermediateResponseHandler;
 import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.opendj.ldap.ResultHandler;
@@ -51,7 +52,7 @@
   LDAPFutureResultImpl(final int requestID, final Request request,
       final ResultHandler<? super Result> resultHandler,
       final IntermediateResponseHandler intermediateResponseHandler,
-      final AsynchronousConnection connection)
+      final Connection connection)
   {
     super(requestID, resultHandler, intermediateResponseHandler, connection);
     this.request = request;
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPSearchFutureResultImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPSearchFutureResultImpl.java
index 547f2d8..7dc0669 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPSearchFutureResultImpl.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPSearchFutureResultImpl.java
@@ -23,13 +23,14 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package com.forgerock.opendj.ldap;
 
 
 
-import org.forgerock.opendj.ldap.AsynchronousConnection;
+import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.IntermediateResponseHandler;
 import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.opendj.ldap.SearchResultHandler;
@@ -57,7 +58,7 @@
   LDAPSearchFutureResultImpl(final int requestID, final SearchRequest request,
       final SearchResultHandler resultHandler,
       final IntermediateResponseHandler intermediateResponseHandler,
-      final AsynchronousConnection connection)
+      final Connection connection)
   {
     super(requestID, resultHandler, intermediateResponseHandler, connection);
     this.request = request;
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/AbstractConnectionFactory.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/AbstractConnectionFactory.java
deleted file mode 100644
index 032021f..0000000
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/AbstractConnectionFactory.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions copyright 2011 ForgeRock AS
- */
-
-package com.forgerock.opendj.util;
-
-import org.forgerock.opendj.ldap.*;
-
-
-
-/**
- * This class provides a skeletal implementation of the
- * {@code ConnectionFactory} interface, to minimize the effort required to
- * implement this interface.
- */
-public abstract class AbstractConnectionFactory implements ConnectionFactory
-{
-  /**
-   * Creates a new abstract connection factory.
-   */
-  protected AbstractConnectionFactory()
-  {
-    // Nothing to do.
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public abstract FutureResult<AsynchronousConnection> getAsynchronousConnection(
-      ResultHandler<? super AsynchronousConnection> handler);
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to convert the asynchronous connection
-   * returned from {@code getAsynchronousConnection()} to a synchronous
-   * connection using {@link AsynchronousConnection#getSynchronousConnection()}.
-   * <p>
-   * Implementations should override this method if they wish to return a
-   * different type of synchronous connection.
-   *
-   * @return A connection to the Directory Server associated with this
-   *         connection factory.
-   * @throws ErrorResultException
-   *           If the connection request failed for some reason.
-   * @throws InterruptedException
-   *           If the current thread was interrupted while waiting.
-   */
-  public Connection getConnection() throws ErrorResultException,
-      InterruptedException
-  {
-    return getAsynchronousConnection(null).get().getSynchronousConnection();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public abstract String toString();
-}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/AsynchronousConnectionDecorator.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/AsynchronousConnectionDecorator.java
deleted file mode 100644
index 3cc077f..0000000
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/AsynchronousConnectionDecorator.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2010 Sun Microsystems, Inc.
- *      Portions copyright 2011 ForgeRock AS
- */
-
-package com.forgerock.opendj.util;
-
-
-
-import java.util.Collection;
-
-import org.forgerock.opendj.ldap.*;
-import org.forgerock.opendj.ldap.requests.*;
-import org.forgerock.opendj.ldap.responses.*;
-
-
-
-/**
- * A base class from which asynchronous connection decorators may be easily
- * implemented. The default implementation of each method is to delegate to the
- * decorated connection.
- */
-public abstract class AsynchronousConnectionDecorator implements
-    AsynchronousConnection
-{
-  /**
-   * The decorated asynchronous connection.
-   */
-  protected final AsynchronousConnection connection;
-
-
-
-  /**
-   * Creates a new asynchronous connection decorator.
-   *
-   * @param connection
-   *          The asynchronous connection to be decorated.
-   */
-  protected AsynchronousConnectionDecorator(AsynchronousConnection connection)
-  {
-    Validator.ensureNotNull(connection);
-    this.connection = connection;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<Void> abandon(AbandonRequest request)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.abandon(request);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<Result> add(AddRequest request,
-      ResultHandler<? super Result> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.add(request, handler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<Result> add(AddRequest request,
-      ResultHandler<? super Result> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.add(request, resultHandler, intermediateResponseHandler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public void addConnectionEventListener(ConnectionEventListener listener)
-      throws IllegalStateException, NullPointerException
-  {
-    connection.addConnectionEventListener(listener);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<BindResult> bind(BindRequest request,
-      ResultHandler<? super BindResult> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.bind(request, handler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<BindResult> bind(BindRequest request,
-      ResultHandler<? super BindResult> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.bind(request, resultHandler, intermediateResponseHandler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public void close()
-  {
-    connection.close();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public void close(UnbindRequest request, String reason)
-      throws NullPointerException
-  {
-    connection.close(request, reason);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<CompareResult> compare(CompareRequest request,
-      ResultHandler<? super CompareResult> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.compare(request, handler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<CompareResult> compare(CompareRequest request,
-      ResultHandler<? super CompareResult> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.compare(request, resultHandler,
-        intermediateResponseHandler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<Result> delete(DeleteRequest request,
-      ResultHandler<? super Result> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.delete(request, handler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<Result> delete(DeleteRequest request,
-      ResultHandler<? super Result> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.delete(request, resultHandler,
-        intermediateResponseHandler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public <R extends ExtendedResult> FutureResult<R> extendedRequest(
-      ExtendedRequest<R> request, ResultHandler<? super R> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.extendedRequest(request, handler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public <R extends ExtendedResult> FutureResult<R> extendedRequest(
-      ExtendedRequest<R> request, ResultHandler<? super R> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.extendedRequest(request, resultHandler,
-        intermediateResponseHandler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to return a synchronous view of this
-   * decorated connection.
-   */
-  public Connection getSynchronousConnection()
-  {
-    return new SynchronousConnection(this);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public boolean isClosed()
-  {
-    return connection.isClosed();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public boolean isValid()
-  {
-    return connection.isValid();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<Result> modify(ModifyRequest request,
-      ResultHandler<? super Result> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.modify(request, handler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<Result> modify(ModifyRequest request,
-      ResultHandler<? super Result> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.modify(request, resultHandler,
-        intermediateResponseHandler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<Result> modifyDN(ModifyDNRequest request,
-      ResultHandler<? super Result> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.modifyDN(request, handler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<Result> modifyDN(ModifyDNRequest request,
-      ResultHandler<? super Result> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.modifyDN(request, resultHandler,
-        intermediateResponseHandler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<SearchResultEntry> readEntry(DN name,
-      Collection<String> attributeDescriptions,
-      ResultHandler<? super SearchResultEntry> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.readEntry(name, attributeDescriptions, handler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public void removeConnectionEventListener(ConnectionEventListener listener)
-      throws NullPointerException
-  {
-    connection.removeConnectionEventListener(listener);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<Result> search(SearchRequest request,
-      SearchResultHandler handler) throws UnsupportedOperationException,
-      IllegalStateException, NullPointerException
-  {
-    return connection.search(request, handler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<Result> search(SearchRequest request,
-      SearchResultHandler resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.search(request, resultHandler,
-        intermediateResponseHandler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public FutureResult<SearchResultEntry> searchSingleEntry(
-      SearchRequest request, ResultHandler<? super SearchResultEntry> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return connection.searchSingleEntry(request, handler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation is to delegate.
-   */
-  public String toString()
-  {
-    return connection.toString();
-  }
-
-}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ConnectionDecorator.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ConnectionDecorator.java
new file mode 100644
index 0000000..3006e28
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/ConnectionDecorator.java
@@ -0,0 +1,766 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opendj3/legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS
+ */
+
+package com.forgerock.opendj.util;
+
+
+
+import java.util.Collection;
+import java.util.concurrent.BlockingQueue;
+
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
+import org.forgerock.opendj.ldap.*;
+import org.forgerock.opendj.ldap.requests.*;
+import org.forgerock.opendj.ldap.responses.*;
+import org.forgerock.opendj.ldif.ConnectionEntryReader;
+
+
+
+/**
+ * A base class from which connection decorators may be easily implemented. The
+ * default implementation of each method is to delegate to the decorated
+ * connection.
+ */
+public abstract class ConnectionDecorator implements Connection
+{
+  /**
+   * The decorated connection.
+   */
+  protected final Connection connection;
+
+
+
+  /**
+   * Creates a new connection decorator.
+   *
+   * @param connection
+   *          The connection to be decorated.
+   */
+  protected ConnectionDecorator(final Connection connection)
+  {
+    Validator.ensureNotNull(connection);
+    this.connection = connection;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public FutureResult<Void> abandonAsync(final AbandonRequest request)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.abandonAsync(request);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public Result add(final AddRequest request) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    return connection.add(request);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public Result add(final Entry entry) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    return connection.add(entry);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public Result add(final String... ldifLines) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
+      LocalizedIllegalArgumentException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.add(ldifLines);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public FutureResult<Result> addAsync(final AddRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super Result> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.addAsync(request, intermediateResponseHandler,
+        resultHandler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public void addConnectionEventListener(final ConnectionEventListener listener)
+      throws IllegalStateException, NullPointerException
+  {
+    connection.addConnectionEventListener(listener);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public BindResult bind(final BindRequest request)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.bind(request);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public BindResult bind(final String name, final char[] password)
+      throws ErrorResultException, InterruptedException,
+      LocalizedIllegalArgumentException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    return connection.bind(name, password);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public FutureResult<BindResult> bindAsync(final BindRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super BindResult> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.bindAsync(request, intermediateResponseHandler,
+        resultHandler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public void close()
+  {
+    connection.close();
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public void close(final UnbindRequest request, final String reason)
+      throws NullPointerException
+  {
+    connection.close(request, reason);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public CompareResult compare(final CompareRequest request)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.compare(request);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public CompareResult compare(final String name,
+      final String attributeDescription, final String assertionValue)
+      throws ErrorResultException, InterruptedException,
+      LocalizedIllegalArgumentException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    return connection.compare(name, attributeDescription, assertionValue);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public FutureResult<CompareResult> compareAsync(final CompareRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super CompareResult> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.compareAsync(request, intermediateResponseHandler,
+        resultHandler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public Result delete(final DeleteRequest request)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.delete(request);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public Result delete(final String name) throws ErrorResultException,
+      InterruptedException, LocalizedIllegalArgumentException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.delete(name);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public FutureResult<Result> deleteAsync(final DeleteRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super Result> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.deleteAsync(request, intermediateResponseHandler,
+        resultHandler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public <R extends ExtendedResult> R extendedRequest(
+      final ExtendedRequest<R> request) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    return connection.extendedRequest(request);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public <R extends ExtendedResult> R extendedRequest(
+      final ExtendedRequest<R> request,
+      final IntermediateResponseHandler handler) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    return connection.extendedRequest(request, handler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public GenericExtendedResult extendedRequest(final String requestName,
+      final ByteString requestValue) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    return connection.extendedRequest(requestName, requestValue);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public <R extends ExtendedResult> FutureResult<R> extendedRequestAsync(
+      final ExtendedRequest<R> request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super R> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.extendedRequestAsync(request, intermediateResponseHandler,
+        resultHandler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public boolean isClosed()
+  {
+    return connection.isClosed();
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public boolean isValid()
+  {
+    return connection.isValid();
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public Result modify(final ModifyRequest request)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.modify(request);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public Result modify(final String... ldifLines) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
+      LocalizedIllegalArgumentException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.modify(ldifLines);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public FutureResult<Result> modifyAsync(final ModifyRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super Result> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.modifyAsync(request, intermediateResponseHandler,
+        resultHandler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public Result modifyDN(final ModifyDNRequest request)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.modifyDN(request);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public Result modifyDN(final String name, final String newRDN)
+      throws ErrorResultException, LocalizedIllegalArgumentException,
+      InterruptedException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    return connection.modifyDN(name, newRDN);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public FutureResult<Result> modifyDNAsync(final ModifyDNRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final ResultHandler<? super Result> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.modifyDNAsync(request, intermediateResponseHandler,
+        resultHandler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public SearchResultEntry readEntry(final DN name,
+      final String... attributeDescriptions) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    return connection.readEntry(name, attributeDescriptions);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public SearchResultEntry readEntry(final String name,
+      final String... attributeDescriptions) throws ErrorResultException,
+      InterruptedException, LocalizedIllegalArgumentException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.readEntry(name, attributeDescriptions);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public FutureResult<SearchResultEntry> readEntryAsync(final DN name,
+      final Collection<String> attributeDescriptions,
+      final ResultHandler<? super SearchResultEntry> handler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.readEntryAsync(name, attributeDescriptions, handler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public void removeConnectionEventListener(
+      final ConnectionEventListener listener) throws NullPointerException
+  {
+    connection.removeConnectionEventListener(listener);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public ConnectionEntryReader search(final SearchRequest request,
+      final BlockingQueue<Response> entries)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.search(request, entries);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public Result search(final SearchRequest request,
+      final Collection<? super SearchResultEntry> entries)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.search(request, entries);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public Result search(final SearchRequest request,
+      final Collection<? super SearchResultEntry> entries,
+      final Collection<? super SearchResultReference> references)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.search(request, entries, references);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public Result search(final SearchRequest request,
+      final SearchResultHandler handler) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    return connection.search(request, handler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public ConnectionEntryReader search(final String baseObject,
+      final SearchScope scope, final String filter,
+      final String... attributeDescriptions)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.search(baseObject, scope, filter, attributeDescriptions);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public FutureResult<Result> searchAsync(final SearchRequest request,
+      final IntermediateResponseHandler intermediateResponseHandler,
+      final SearchResultHandler resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.searchAsync(request, intermediateResponseHandler,
+        resultHandler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public SearchResultEntry searchSingleEntry(final SearchRequest request)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.searchSingleEntry(request);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public SearchResultEntry searchSingleEntry(final String baseObject,
+      final SearchScope scope, final String filter,
+      final String... attributeDescriptions) throws ErrorResultException,
+      InterruptedException, LocalizedIllegalArgumentException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.searchSingleEntry(baseObject, scope, filter,
+        attributeDescriptions);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public FutureResult<SearchResultEntry> searchSingleEntryAsync(
+      final SearchRequest request,
+      final ResultHandler<? super SearchResultEntry> handler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return connection.searchSingleEntryAsync(request, handler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * The default implementation is to delegate.
+   */
+  @Override
+  public String toString()
+  {
+    return connection.toString();
+  }
+
+}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/SynchronousConnection.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/SynchronousConnection.java
deleted file mode 100644
index dc31c1a..0000000
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/SynchronousConnection.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions copyright 2011 ForgeRock AS
- */
-
-package com.forgerock.opendj.util;
-
-
-
-import java.util.concurrent.BlockingQueue;
-
-import org.forgerock.opendj.ldap.*;
-import org.forgerock.opendj.ldap.requests.*;
-import org.forgerock.opendj.ldap.responses.*;
-import org.forgerock.opendj.ldif.ConnectionEntryReader;
-
-
-
-
-/**
- * A {@code SynchronousConnection} adapts an {@code AsynchronousConnection} into
- * a synchronous {@code Connection}.
- */
-public class SynchronousConnection extends AbstractConnection
-{
-  private final AsynchronousConnection connection;
-
-
-
-  /**
-   * Creates a new abstract connection which will route all synchronous requests
-   * to the provided asynchronous connection.
-   *
-   * @param connection
-   *          The asynchronous connection to be used.
-   * @throws NullPointerException
-   *           If {@code connection} was {@code null}.
-   */
-  public SynchronousConnection(final AsynchronousConnection connection)
-      throws NullPointerException
-  {
-    Validator.ensureNotNull(connection);
-    this.connection = connection;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public Result add(final AddRequest request) throws ErrorResultException,
-      InterruptedException, UnsupportedOperationException,
-      IllegalStateException, NullPointerException
-  {
-    final FutureResult<Result> future = connection.add(request, null);
-    try
-    {
-      return future.get();
-    }
-    finally
-    {
-      // Cancel the request if it hasn't completed.
-      future.cancel(false);
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public void addConnectionEventListener(final ConnectionEventListener listener)
-      throws IllegalStateException, NullPointerException
-  {
-    connection.addConnectionEventListener(listener);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public BindResult bind(final BindRequest request)
-      throws ErrorResultException, InterruptedException,
-      UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    final FutureResult<BindResult> future = connection.bind(request, null);
-    try
-    {
-      return future.get();
-    }
-    finally
-    {
-      // Cancel the request if it hasn't completed.
-      future.cancel(false);
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public void close()
-  {
-    connection.close();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public void close(final UnbindRequest request, final String reason)
-      throws NullPointerException
-  {
-    connection.close(request, reason);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public CompareResult compare(final CompareRequest request)
-      throws ErrorResultException, InterruptedException,
-      UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    final FutureResult<CompareResult> future = connection
-        .compare(request, null);
-    try
-    {
-      return future.get();
-    }
-    finally
-    {
-      // Cancel the request if it hasn't completed.
-      future.cancel(false);
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public Result delete(final DeleteRequest request)
-      throws ErrorResultException, InterruptedException,
-      UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    final FutureResult<Result> future = connection.delete(request, null);
-    try
-    {
-      return future.get();
-    }
-    finally
-    {
-      // Cancel the request if it hasn't completed.
-      future.cancel(false);
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public <R extends ExtendedResult> R extendedRequest(
-      final ExtendedRequest<R> request) throws ErrorResultException,
-      InterruptedException, UnsupportedOperationException,
-      IllegalStateException, NullPointerException
-  {
-    final FutureResult<R> future = connection.extendedRequest(request, null);
-    try
-    {
-      return future.get();
-    }
-    finally
-    {
-      // Cancel the request if it hasn't completed.
-      future.cancel(false);
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public <R extends ExtendedResult> R extendedRequest(
-      final ExtendedRequest<R> request,
-      final IntermediateResponseHandler handler) throws ErrorResultException,
-      InterruptedException, UnsupportedOperationException,
-      IllegalStateException, NullPointerException
-  {
-    final FutureResult<R> future = connection.extendedRequest(request, null,
-        handler);
-    try
-    {
-      return future.get();
-    }
-    finally
-    {
-      // Cancel the request if it hasn't completed.
-      future.cancel(false);
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public AsynchronousConnection getAsynchronousConnection()
-  {
-    return connection;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public boolean isClosed()
-  {
-    return connection.isClosed();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public boolean isValid()
-  {
-    return connection.isValid();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public Result modify(final ModifyRequest request)
-      throws ErrorResultException, InterruptedException,
-      UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    final FutureResult<Result> future = connection.modify(request, null);
-    try
-    {
-      return future.get();
-    }
-    finally
-    {
-      // Cancel the request if it hasn't completed.
-      future.cancel(false);
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public Result modifyDN(final ModifyDNRequest request)
-      throws ErrorResultException, InterruptedException,
-      UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    final FutureResult<Result> future = connection.modifyDN(request, null);
-    try
-    {
-      return future.get();
-    }
-    finally
-    {
-      // Cancel the request if it hasn't completed.
-      future.cancel(false);
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public void removeConnectionEventListener(
-      final ConnectionEventListener listener) throws NullPointerException
-  {
-    connection.removeConnectionEventListener(listener);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public Result search(final SearchRequest request,
-      final SearchResultHandler handler) throws ErrorResultException,
-      InterruptedException, UnsupportedOperationException,
-      IllegalStateException, NullPointerException
-  {
-    final FutureResult<Result> future = connection.search(request, handler);
-    try
-    {
-      return future.get();
-    }
-    finally
-    {
-      // Cancel the request if it hasn't completed.
-      future.cancel(false);
-    }
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public ConnectionEntryReader search(final SearchRequest request,
-      BlockingQueue<Response> entries) throws UnsupportedOperationException,
-      IllegalStateException, NullPointerException
-  {
-    return new ConnectionEntryReader(getAsynchronousConnection(), request,
-        entries);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public String toString()
-  {
-    return connection.toString();
-  }
-
-}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java
index 568e296..c1d8454 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java
@@ -30,192 +30,23 @@
 
 
 
-import static org.forgerock.opendj.ldap.CoreMessages.*;
-import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
-
-import java.util.Collection;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
 import org.forgerock.opendj.ldap.requests.*;
-import org.forgerock.opendj.ldap.responses.*;
-
-import com.forgerock.opendj.util.SynchronousConnection;
+import org.forgerock.opendj.ldap.responses.BindResult;
+import org.forgerock.opendj.ldap.responses.CompareResult;
+import org.forgerock.opendj.ldap.responses.ExtendedResult;
+import org.forgerock.opendj.ldap.responses.Result;
 
 
 
 /**
- * This class provides a skeletal implementation of the
- * {@code AsynchronousConnection} interface, to minimize the effort required to
- * implement this interface.
+ * An abstract connection whose synchronous methods are implemented in terms of
+ * asynchronous methods.
  */
-public abstract class AbstractAsynchronousConnection implements
-    AsynchronousConnection
+public abstract class AbstractAsynchronousConnection extends AbstractConnection
 {
 
-  private static final class SingleEntryFuture implements
-      FutureResult<SearchResultEntry>, SearchResultHandler
-  {
-    private final ResultHandler<? super SearchResultEntry> handler;
-
-    private volatile SearchResultEntry firstEntry = null;
-
-    private volatile SearchResultReference firstReference = null;
-
-    private volatile int entryCount = 0;
-
-    private volatile FutureResult<Result> future = null;
-
-
-
-    private SingleEntryFuture(
-        final ResultHandler<? super SearchResultEntry> handler)
-    {
-      this.handler = handler;
-    }
-
-
-
-    public boolean cancel(final boolean mayInterruptIfRunning)
-    {
-      return future.cancel(mayInterruptIfRunning);
-    }
-
-
-
-    public SearchResultEntry get() throws ErrorResultException,
-        InterruptedException
-    {
-      future.get();
-      return get0();
-    }
-
-
-
-    public SearchResultEntry get(final long timeout, final TimeUnit unit)
-        throws ErrorResultException, TimeoutException, InterruptedException
-    {
-      future.get(timeout, unit);
-      return get0();
-    }
-
-
-
-    public int getRequestID()
-    {
-      return future.getRequestID();
-    }
-
-
-
-    public boolean handleEntry(final SearchResultEntry entry)
-    {
-      if (firstEntry == null)
-      {
-        firstEntry = entry;
-      }
-      entryCount++;
-      return true;
-    }
-
-
-
-    public void handleErrorResult(final ErrorResultException error)
-    {
-      if (handler != null)
-      {
-        handler.handleErrorResult(error);
-      }
-    }
-
-
-
-    public boolean handleReference(final SearchResultReference reference)
-    {
-      if (firstReference == null)
-      {
-        firstReference = reference;
-      }
-      return true;
-    }
-
-
-
-    public void handleResult(final Result result)
-    {
-      if (handler != null)
-      {
-        try
-        {
-          handler.handleResult(get0());
-        }
-        catch (final ErrorResultException e)
-        {
-          handler.handleErrorResult(e);
-        }
-      }
-    }
-
-
-
-    public boolean isCancelled()
-    {
-      return future.isCancelled();
-    }
-
-
-
-    public boolean isDone()
-    {
-      return future.isDone();
-    }
-
-
-
-    private SearchResultEntry get0() throws ErrorResultException
-    {
-      if (entryCount == 0)
-      {
-        // Did not find any entries.
-        throw newErrorResult(
-            ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED,
-            ERR_NO_SEARCH_RESULT_ENTRIES.get().toString());
-      }
-      else if (entryCount > 1)
-      {
-        // Got more entries than expected.
-        throw newErrorResult(
-            ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED,
-            ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES.get(entryCount)
-                .toString());
-      }
-      else if (firstReference != null)
-      {
-        // Got an unexpected search result reference.
-        throw newErrorResult(
-            ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED,
-            ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES.get(
-                firstReference.getURIs().iterator().next())
-                .toString());
-      }
-      else
-      {
-        return firstEntry;
-      }
-    }
-
-
-
-    private void setResultFuture(final FutureResult<Result> future)
-    {
-      this.future = future;
-    }
-  }
-
-
-
   /**
-   * Creates a new abstract connection.
+   * Creates a new abstract asynchronous connection.
    */
   protected AbstractAsynchronousConnection()
   {
@@ -227,142 +58,21 @@
   /**
    * {@inheritDoc}
    */
-  public FutureResult<Result> add(final AddRequest request,
-      final ResultHandler<? super Result> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return add(request, handler, null);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public FutureResult<BindResult> bind(final BindRequest request,
-      final ResultHandler<? super BindResult> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return bind(request, handler, null);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public void close()
-  {
-    close(Requests.newUnbindRequest(), null);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public FutureResult<CompareResult> compare(final CompareRequest request,
-      final ResultHandler<? super CompareResult> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return compare(request, handler, null);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public FutureResult<Result> delete(final DeleteRequest request,
-      final ResultHandler<? super Result> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return delete(request, handler, null);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public <R extends ExtendedResult> FutureResult<R> extendedRequest(
-      final ExtendedRequest<R> request, final ResultHandler<? super R> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return extendedRequest(request, handler, null);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public Connection getSynchronousConnection()
-  {
-    return new SynchronousConnection(this);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public FutureResult<Result> modify(final ModifyRequest request,
-      final ResultHandler<? super Result> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return modify(request, handler, null);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public FutureResult<Result> modifyDN(final ModifyDNRequest request,
-      final ResultHandler<? super Result> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    return modifyDN(request, handler, null);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public FutureResult<SearchResultEntry> readEntry(final DN name,
-      final Collection<String> attributeDescriptions,
-      final ResultHandler<? super SearchResultEntry> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException
-  {
-    final SearchRequest request = Requests.newSearchRequest(name,
-        SearchScope.BASE_OBJECT, Filter.getObjectClassPresentFilter());
-    if (attributeDescriptions != null)
-    {
-      request.getAttributes().addAll(attributeDescriptions);
-    }
-    return searchSingleEntry(request, handler);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public FutureResult<Result> search(final SearchRequest request,
-      final SearchResultHandler handler) throws UnsupportedOperationException,
+  @Override
+  public Result add(final AddRequest request) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
       IllegalStateException, NullPointerException
   {
-    return search(request, handler, null);
+    final FutureResult<Result> future = addAsync(request, null, null);
+    try
+    {
+      return future.get();
+    }
+    finally
+    {
+      // Cancel the request if it hasn't completed.
+      future.cancel(false);
+    }
   }
 
 
@@ -370,26 +80,161 @@
   /**
    * {@inheritDoc}
    */
-  public FutureResult<SearchResultEntry> searchSingleEntry(
-      final SearchRequest request,
-      final ResultHandler<? super SearchResultEntry> handler)
-      throws UnsupportedOperationException, IllegalStateException,
+  @Override
+  public BindResult bind(final BindRequest request)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
       NullPointerException
   {
-    final SingleEntryFuture innerFuture = new SingleEntryFuture(handler);
-    final FutureResult<Result> future = search(request, innerFuture);
-    innerFuture.setResultFuture(future);
-    return innerFuture;
+    final FutureResult<BindResult> future = bindAsync(request, null, null);
+    try
+    {
+      return future.get();
+    }
+    finally
+    {
+      // Cancel the request if it hasn't completed.
+      future.cancel(false);
+    }
   }
 
 
 
   /**
    * {@inheritDoc}
-   * <p>
-   * Sub-classes should provide an implementation which returns an appropriate
-   * description of the connection which may be used for debugging purposes.
    */
-  public abstract String toString();
+  @Override
+  public CompareResult compare(final CompareRequest request)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    final FutureResult<CompareResult> future = compareAsync(request, null, null);
+    try
+    {
+      return future.get();
+    }
+    finally
+    {
+      // Cancel the request if it hasn't completed.
+      future.cancel(false);
+    }
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Result delete(final DeleteRequest request)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    final FutureResult<Result> future = deleteAsync(request, null, null);
+    try
+    {
+      return future.get();
+    }
+    finally
+    {
+      // Cancel the request if it hasn't completed.
+      future.cancel(false);
+    }
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public <R extends ExtendedResult> R extendedRequest(
+      final ExtendedRequest<R> request,
+      final IntermediateResponseHandler handler) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    final FutureResult<R> future = extendedRequestAsync(request, handler, null);
+    try
+    {
+      return future.get();
+    }
+    finally
+    {
+      // Cancel the request if it hasn't completed.
+      future.cancel(false);
+    }
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Result modify(final ModifyRequest request)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    final FutureResult<Result> future = modifyAsync(request, null, null);
+    try
+    {
+      return future.get();
+    }
+    finally
+    {
+      // Cancel the request if it hasn't completed.
+      future.cancel(false);
+    }
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Result modifyDN(final ModifyDNRequest request)
+      throws ErrorResultException, InterruptedException,
+      UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    final FutureResult<Result> future = modifyDNAsync(request, null, null);
+    try
+    {
+      return future.get();
+    }
+    finally
+    {
+      // Cancel the request if it hasn't completed.
+      future.cancel(false);
+    }
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Result search(final SearchRequest request,
+      final SearchResultHandler handler) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    final FutureResult<Result> future = searchAsync(request, null, handler);
+    try
+    {
+      return future.get();
+    }
+    finally
+    {
+      // Cancel the request if it hasn't completed.
+      future.cancel(false);
+    }
+  }
 
 }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java
index b1b34f4..869c71d 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java
@@ -38,10 +38,11 @@
 import java.util.Collection;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 import org.forgerock.i18n.LocalizedIllegalArgumentException;
-import org.forgerock.opendj.ldap.requests.Requests;
-import org.forgerock.opendj.ldap.requests.SearchRequest;
+import org.forgerock.opendj.ldap.requests.*;
 import org.forgerock.opendj.ldap.responses.*;
 import org.forgerock.opendj.ldif.ConnectionEntryReader;
 
@@ -56,16 +57,66 @@
 public abstract class AbstractConnection implements Connection
 {
 
-  private static final class SingleEntryHandler implements SearchResultHandler
+  private static final class SingleEntryFuture implements
+      FutureResult<SearchResultEntry>, SearchResultHandler
   {
+    private final ResultHandler<? super SearchResultEntry> handler;
+
     private volatile SearchResultEntry firstEntry = null;
 
     private volatile SearchResultReference firstReference = null;
 
     private volatile int entryCount = 0;
 
+    private volatile FutureResult<Result> future = null;
 
 
+
+    private SingleEntryFuture(
+        final ResultHandler<? super SearchResultEntry> handler)
+    {
+      this.handler = handler;
+    }
+
+
+
+    @Override
+    public boolean cancel(final boolean mayInterruptIfRunning)
+    {
+      return future.cancel(mayInterruptIfRunning);
+    }
+
+
+
+    @Override
+    public SearchResultEntry get() throws ErrorResultException,
+        InterruptedException
+    {
+      future.get();
+      return get0();
+    }
+
+
+
+    @Override
+    public SearchResultEntry get(final long timeout, final TimeUnit unit)
+        throws ErrorResultException, TimeoutException, InterruptedException
+    {
+      future.get(timeout, unit);
+      return get0();
+    }
+
+
+
+    @Override
+    public int getRequestID()
+    {
+      return future.getRequestID();
+    }
+
+
+
+    @Override
     public boolean handleEntry(final SearchResultEntry entry)
     {
       if (firstEntry == null)
@@ -78,6 +129,137 @@
 
 
 
+    @Override
+    public void handleErrorResult(final ErrorResultException error)
+    {
+      if (handler != null)
+      {
+        handler.handleErrorResult(error);
+      }
+    }
+
+
+
+    @Override
+    public boolean handleReference(final SearchResultReference reference)
+    {
+      if (firstReference == null)
+      {
+        firstReference = reference;
+      }
+      return true;
+    }
+
+
+
+    @Override
+    public void handleResult(final Result result)
+    {
+      if (handler != null)
+      {
+        try
+        {
+          handler.handleResult(get0());
+        }
+        catch (final ErrorResultException e)
+        {
+          handler.handleErrorResult(e);
+        }
+      }
+    }
+
+
+
+    @Override
+    public boolean isCancelled()
+    {
+      return future.isCancelled();
+    }
+
+
+
+    @Override
+    public boolean isDone()
+    {
+      return future.isDone();
+    }
+
+
+
+    private SearchResultEntry get0() throws ErrorResultException
+    {
+      if (entryCount == 0)
+      {
+        // Did not find any entries.
+        throw newErrorResult(ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED,
+            ERR_NO_SEARCH_RESULT_ENTRIES.get().toString());
+      }
+      else if (entryCount > 1)
+      {
+        // Got more entries than expected.
+        throw newErrorResult(
+            ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED,
+            ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES.get(entryCount).toString());
+      }
+      else if (firstReference != null)
+      {
+        // Got an unexpected search result reference.
+        throw newErrorResult(
+            ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED,
+            ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES.get(
+                firstReference.getURIs().iterator().next()).toString());
+      }
+      else
+      {
+        return firstEntry;
+      }
+    }
+
+
+
+    private void setResultFuture(final FutureResult<Result> future)
+    {
+      this.future = future;
+    }
+  }
+
+
+
+  private static final class SingleEntryHandler implements SearchResultHandler
+  {
+    private volatile SearchResultEntry firstEntry = null;
+
+    private volatile SearchResultReference firstReference = null;
+
+    private volatile int entryCount = 0;
+
+
+
+    @Override
+    public boolean handleEntry(final SearchResultEntry entry)
+    {
+      if (firstEntry == null)
+      {
+        firstEntry = entry;
+      }
+      entryCount++;
+      return true;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void handleErrorResult(final ErrorResultException error)
+    {
+      // Ignore.
+    }
+
+
+
+    @Override
     public boolean handleReference(final SearchResultReference reference)
     {
       if (firstReference == null)
@@ -92,17 +274,8 @@
     /**
      * {@inheritDoc}
      */
-    public void handleErrorResult(ErrorResultException error)
-    {
-      // Ignore.
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void handleResult(Result result)
+    @Override
+    public void handleResult(final Result result)
     {
       // Ignore.
     }
@@ -124,6 +297,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public Result add(final Entry entry) throws ErrorResultException,
       InterruptedException, UnsupportedOperationException,
       IllegalStateException, NullPointerException
@@ -136,6 +310,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public Result add(final String... ldifLines) throws ErrorResultException,
       InterruptedException, UnsupportedOperationException,
       LocalizedIllegalArgumentException, IllegalStateException,
@@ -149,6 +324,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public BindResult bind(final String name, final char[] password)
       throws ErrorResultException, InterruptedException,
       LocalizedIllegalArgumentException, UnsupportedOperationException,
@@ -162,6 +338,18 @@
   /**
    * {@inheritDoc}
    */
+  @Override
+  public void close()
+  {
+    close(Requests.newUnbindRequest(), null);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
   public CompareResult compare(final String name,
       final String attributeDescription, final String assertionValue)
       throws ErrorResultException, InterruptedException,
@@ -177,6 +365,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public Result delete(final String name) throws ErrorResultException,
       InterruptedException, LocalizedIllegalArgumentException,
       UnsupportedOperationException, IllegalStateException,
@@ -190,6 +379,21 @@
   /**
    * {@inheritDoc}
    */
+  @Override
+  public <R extends ExtendedResult> R extendedRequest(
+      final ExtendedRequest<R> request) throws ErrorResultException,
+      InterruptedException, UnsupportedOperationException,
+      IllegalStateException, NullPointerException
+  {
+    return extendedRequest(request, null);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
   public GenericExtendedResult extendedRequest(final String requestName,
       final ByteString requestValue) throws ErrorResultException,
       InterruptedException, UnsupportedOperationException,
@@ -204,6 +408,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public Result modify(final String... ldifLines) throws ErrorResultException,
       InterruptedException, UnsupportedOperationException,
       LocalizedIllegalArgumentException, IllegalStateException,
@@ -217,6 +422,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public Result modifyDN(final String name, final String newRDN)
       throws ErrorResultException, InterruptedException,
       LocalizedIllegalArgumentException, UnsupportedOperationException,
@@ -230,6 +436,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public SearchResultEntry readEntry(final DN baseObject,
       final String... attributeDescriptions) throws ErrorResultException,
       InterruptedException, UnsupportedOperationException,
@@ -246,6 +453,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public SearchResultEntry readEntry(final String baseObject,
       final String... attributeDescriptions) throws ErrorResultException,
       InterruptedException, LocalizedIllegalArgumentException,
@@ -260,6 +468,42 @@
   /**
    * {@inheritDoc}
    */
+  @Override
+  public FutureResult<SearchResultEntry> readEntryAsync(final DN name,
+      final Collection<String> attributeDescriptions,
+      final ResultHandler<? super SearchResultEntry> handler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    final SearchRequest request = Requests.newSearchRequest(name,
+        SearchScope.BASE_OBJECT, Filter.getObjectClassPresentFilter());
+    if (attributeDescriptions != null)
+    {
+      request.getAttributes().addAll(attributeDescriptions);
+    }
+    return searchSingleEntryAsync(request, handler);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ConnectionEntryReader search(final SearchRequest request,
+      final BlockingQueue<Response> entries)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    return new ConnectionEntryReader(this, request, entries);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
   public Result search(final SearchRequest request,
       final Collection<? super SearchResultEntry> entries)
       throws ErrorResultException, InterruptedException,
@@ -274,6 +518,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public Result search(final SearchRequest request,
       final Collection<? super SearchResultEntry> entries,
       final Collection<? super SearchResultReference> references)
@@ -287,6 +532,7 @@
     final SearchResultHandler handler = new SearchResultHandler()
     {
 
+      @Override
       public boolean handleEntry(final SearchResultEntry entry)
       {
         entries.add(entry);
@@ -295,6 +541,18 @@
 
 
 
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public void handleErrorResult(final ErrorResultException error)
+      {
+        // Ignore.
+      }
+
+
+
+      @Override
       public boolean handleReference(final SearchResultReference reference)
       {
         if (references != null)
@@ -309,17 +567,8 @@
       /**
        * {@inheritDoc}
        */
-      public void handleErrorResult(ErrorResultException error)
-      {
-        // Ignore.
-      }
-
-
-
-      /**
-       * {@inheritDoc}
-       */
-      public void handleResult(Result result)
+      @Override
+      public void handleResult(final Result result)
       {
         // Ignore.
       }
@@ -333,6 +582,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public ConnectionEntryReader search(final String baseObject,
       final SearchScope scope, final String filter,
       final String... attributeDescriptions)
@@ -350,6 +600,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public SearchResultEntry searchSingleEntry(final SearchRequest request)
       throws ErrorResultException, InterruptedException,
       UnsupportedOperationException, IllegalStateException,
@@ -361,17 +612,15 @@
     if (handler.entryCount == 0)
     {
       // Did not find any entries.
-      throw newErrorResult(
-          ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED,
+      throw newErrorResult(ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED,
           ERR_NO_SEARCH_RESULT_ENTRIES.get().toString());
     }
     else if (handler.entryCount > 1)
     {
       // Got more entries than expected.
-      throw newErrorResult(
-          ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED,
-          ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES
-              .get(handler.entryCount).toString());
+      throw newErrorResult(ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED,
+          ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES.get(handler.entryCount)
+              .toString());
     }
     else if (handler.firstReference != null)
     {
@@ -379,8 +628,7 @@
       throw newErrorResult(
           ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED,
           ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES.get(
-              handler.firstReference.getURIs().iterator().next())
-              .toString());
+              handler.firstReference.getURIs().iterator().next()).toString());
     }
     else
     {
@@ -393,6 +641,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public SearchResultEntry searchSingleEntry(final String baseObject,
       final SearchScope scope, final String filter,
       final String... attributeDescriptions) throws ErrorResultException,
@@ -409,10 +658,29 @@
 
   /**
    * {@inheritDoc}
+   */
+  @Override
+  public FutureResult<SearchResultEntry> searchSingleEntryAsync(
+      final SearchRequest request,
+      final ResultHandler<? super SearchResultEntry> handler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException
+  {
+    final SingleEntryFuture innerFuture = new SingleEntryFuture(handler);
+    final FutureResult<Result> future = searchAsync(request, null, innerFuture);
+    innerFuture.setResultFuture(future);
+    return innerFuture;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
    * <p>
    * Sub-classes should provide an implementation which returns an appropriate
    * description of the connection which may be used for debugging purposes.
    */
+  @Override
   public abstract String toString();
 
 }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
index 9de0205..4d41dba 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
@@ -40,7 +41,6 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Level;
 
-import com.forgerock.opendj.util.AbstractConnectionFactory;
 import com.forgerock.opendj.util.AsynchronousFutureResult;
 import com.forgerock.opendj.util.StaticUtils;
 import com.forgerock.opendj.util.Validator;
@@ -57,9 +57,8 @@
  */
 abstract class AbstractLoadBalancingAlgorithm implements LoadBalancingAlgorithm
 {
-  private final class MonitoredConnectionFactory extends
-      AbstractConnectionFactory implements
-      ResultHandler<AsynchronousConnection>
+  private final class MonitoredConnectionFactory implements ConnectionFactory,
+      ResultHandler<Connection>
   {
 
     private final ConnectionFactory factory;
@@ -84,28 +83,53 @@
     /**
      * {@inheritDoc}
      */
-    @Override
-    public FutureResult<AsynchronousConnection> getAsynchronousConnection(
-        final ResultHandler<? super AsynchronousConnection> resultHandler)
+    public Connection getConnection() throws ErrorResultException,
+        InterruptedException
     {
-      final AsynchronousFutureResult<AsynchronousConnection> future =
-        new AsynchronousFutureResult<AsynchronousConnection>(resultHandler);
+      final Connection connection;
+      try
+      {
+        connection = factory.getConnection();
+      }
+      catch (ErrorResultException e)
+      {
+        // Attempt failed - try next factory.
+        notifyOffline(e);
+        final int nextIndex = (index + 1) % monitoredFactories.size();
+        final MonitoredConnectionFactory nextFactory =
+            getMonitoredConnectionFactory(nextIndex);
+        return nextFactory.getConnection();
+      }
+      notifyOnline();
+      return connection;
+    }
 
-      final ResultHandler<AsynchronousConnection> failoverHandler =
-        new ResultHandler<AsynchronousConnection>()
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FutureResult<Connection> getConnectionAsync(
+        final ResultHandler<? super Connection> resultHandler)
+    {
+      final AsynchronousFutureResult<Connection> future =
+        new AsynchronousFutureResult<Connection>(resultHandler);
+
+      final ResultHandler<Connection> failoverHandler =
+        new ResultHandler<Connection>()
       {
         @Override
         public void handleErrorResult(final ErrorResultException error)
         {
           // Attempt failed - try next factory.
           notifyOffline(error);
-
           final int nextIndex = (index + 1) % monitoredFactories.size();
           try
           {
             final MonitoredConnectionFactory nextFactory =
               getMonitoredConnectionFactory(nextIndex);
-            nextFactory.getAsynchronousConnection(future);
+            nextFactory.getConnectionAsync(future);
           }
           catch (final ErrorResultException e)
           {
@@ -116,14 +140,14 @@
 
 
         @Override
-        public void handleResult(final AsynchronousConnection result)
+        public void handleResult(final Connection result)
         {
           notifyOnline();
           future.handleResult(result);
         }
       };
 
-      factory.getAsynchronousConnection(failoverHandler);
+      factory.getConnectionAsync(failoverHandler);
       return future;
     }
 
@@ -144,7 +168,7 @@
      * Handle monitoring connection request success.
      */
     @Override
-    public void handleResult(final AsynchronousConnection connection)
+    public void handleResult(final Connection connection)
     {
       notifyOnline();
 
@@ -179,7 +203,7 @@
           StaticUtils.DEBUG_LOG.fine(String
               .format("Attempting reconnect to offline factory " + this));
         }
-        pendingConnectFuture = factory.getAsynchronousConnection(this);
+        pendingConnectFuture = factory.getConnectionAsync(this);
       }
     }
 
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AsynchronousConnection.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AsynchronousConnection.java
deleted file mode 100644
index f67dc84..0000000
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AsynchronousConnection.java
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions copyright 2011 ForgeRock AS
- */
-
-package org.forgerock.opendj.ldap;
-
-
-
-import java.io.Closeable;
-import java.util.Collection;
-
-import org.forgerock.opendj.ldap.requests.*;
-import org.forgerock.opendj.ldap.responses.*;
-
-
-
-/**
- * An asynchronous connection with a Directory Server over which read and update
- * operations may be performed. See RFC 4511 for the LDAPv3 protocol
- * specification and more information about the types of operations defined in
- * LDAP.
- * <p>
- * <h3>Operation processing</h3>
- * <p>
- * All operations are performed asynchronously and return a {@link FutureResult}
- * or sub-type thereof which can be used for retrieving the result using the
- * {@link FutureResult#get} method. Operation failures, for whatever reason, are
- * signalled by the {@link FutureResult#get()} method throwing an
- * {@link ErrorResultException}.
- * <p>
- * Synchronous operations are easily simulated by immediately getting the
- * result:
- *
- * <pre>
- * Connection connection = ...;
- * AddRequest request = ...;
- * // Will block until operation completes, and
- * // throws exception on failure.
- * connection.add(request).get();
- * </pre>
- *
- * Operations can be performed in parallel while taking advantage of the
- * simplicity of a synchronous application design:
- *
- * <pre>
- * Connection connection1 = ...;
- * Connection connection2 = ...;
- * AddRequest request = ...;
- * // Add the entry to the first server (don't block).
- * FutureResult future1 = connection1.add(request);
- * // Add the entry to the second server (in parallel).
- * FutureResult future2 = connection2.add(request);
- * // Total time = is O(1) instead of O(n).
- * future1.get();
- * future2.get();
- * </pre>
- *
- * More complex client applications can take advantage of a fully asynchronous
- * event driven design using {@link ResultHandler}s:
- *
- * <pre>
- * Connection connection = ...;
- * SearchRequest request = ...;
- * // Process results in the search result handler
- * // in a separate thread.
- * SearchResponseHandler handle = ...;
- * connection.search(request, handler);
- * </pre>
- * <p>
- * <h3>Closing connections</h3>
- * <p>
- * Applications must ensure that a connection is closed by calling
- * {@link #close()} even if a fatal error occurs on the connection. Once a
- * connection has been closed by the client application, any attempts to
- * continue to use the connection will result in an
- * {@link IllegalStateException} being thrown. Note that, if a fatal error is
- * encountered on the connection, then the application can continue to use the
- * connection. In this case all requests subsequent to the failure will fail
- * with an appropriate {@link ErrorResultException} when their result is
- * retrieved.
- * <p>
- * <h3>Event notification</h3>
- * <p>
- * Applications can choose to be notified when a connection is closed by the
- * application, receives an unsolicited notification, or experiences a fatal
- * error by registering a {@link ConnectionEventListener} with the connection
- * using the {@link #addConnectionEventListener} method.
- *
- * @see <a href="http://tools.ietf.org/html/rfc4511">RFC 4511 - Lightweight
- *      Directory Access Protocol (LDAP): The Protocol </a>
- */
-public interface AsynchronousConnection extends Closeable
-{
-
-  /**
-   * Abandons the unfinished operation identified in the provided abandon
-   * request.
-   * <p>
-   * Since abandon requests do not have a response, invoking the method
-   * {@code get()} on the returned future will not block, nor return anything
-   * (it is {@code Void}), but may throw an exception if a problem occurred
-   * while sending the abandon request.
-   * <p>
-   * <b>Note:</b> a more convenient approach to abandoning unfinished operations
-   * is provided via the {@link FutureResult#cancel(boolean)} method.
-   *
-   * @param request
-   *          The request identifying the operation to be abandoned.
-   * @return An future whose result is {@code Void}.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support abandon operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<Void> abandon(AbandonRequest request)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Adds an entry to the Directory Server using the provided add request. Any
-   * intermediate responses will be ignored.
-   *
-   * @param request
-   *          The add request.
-   * @param handler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support add operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<Result> add(AddRequest request,
-      ResultHandler<? super Result> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Adds an entry to the Directory Server using the provided add request.
-   *
-   * @param request
-   *          The add request.
-   * @param resultHandler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @param intermediateResponseHandler
-   *          An intermediate response handler which can be used to process any
-   *          intermediate responses as they are received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support add operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<Result> add(AddRequest request,
-      ResultHandler<? super Result> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Registers the provided connection event listener so that it will be
-   * notified when this connection is closed by the application, receives an
-   * unsolicited notification, or experiences a fatal error.
-   *
-   * @param listener
-   *          The listener which wants to be notified when events occur on this
-   *          connection.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If the {@code listener} was {@code null}.
-   */
-  void addConnectionEventListener(ConnectionEventListener listener)
-      throws IllegalStateException, NullPointerException;
-
-
-
-  /**
-   * Authenticates to the Directory Server using the provided bind request. Any
-   * intermediate responses will be ignored.
-   *
-   * @param request
-   *          The bind request.
-   * @param handler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support bind operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<BindResult> bind(BindRequest request,
-      ResultHandler<? super BindResult> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Authenticates to the Directory Server using the provided bind request.
-   *
-   * @param request
-   *          The bind request.
-   * @param resultHandler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @param intermediateResponseHandler
-   *          An intermediate response handler which can be used to process any
-   *          intermediate responses as they are received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support bind operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<BindResult> bind(BindRequest request,
-      ResultHandler<? super BindResult> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Releases any resources associated with this connection. For physical
-   * connections to a Directory Server this will mean that an unbind request is
-   * sent and the underlying socket is closed.
-   * <p>
-   * Other connection implementations may behave differently, and may choose not
-   * to send an unbind request if its use is inappropriate (for example a pooled
-   * connection will be released and returned to its connection pool without
-   * ever issuing an unbind request).
-   * <p>
-   * This method is semantically equivalent to the following code:
-   *
-   * <pre>
-   * UnbindRequest request = Requests.newUnbindRequest();
-   * connection.close(request);
-   * </pre>
-   *
-   * Calling {@code close} on a connection that is already closed has no effect.
-   */
-  void close();
-
-
-
-  /**
-   * Releases any resources associated with this connection. For physical
-   * connections to a Directory Server this will mean that the provided unbind
-   * request is sent and the underlying socket is closed.
-   * <p>
-   * Other connection implementations may behave differently, and may choose to
-   * ignore the provided unbind request if its use is inappropriate (for example
-   * a pooled connection will be released and returned to its connection pool
-   * without ever issuing an unbind request).
-   * <p>
-   * Calling {@code close} on a connection that is already closed has no effect.
-   *
-   * @param request
-   *          The unbind request to use in the case where a physical connection
-   *          is closed.
-   * @param reason
-   *          A reason describing why the connection was closed.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  void close(UnbindRequest request, String reason) throws NullPointerException;
-
-
-
-  /**
-   * Compares an entry in the Directory Server using the provided compare
-   * request. Any intermediate responses will be ignored.
-   *
-   * @param request
-   *          The compare request.
-   * @param handler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support compare operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<CompareResult> compare(CompareRequest request,
-      ResultHandler<? super CompareResult> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Compares an entry in the Directory Server using the provided compare
-   * request.
-   *
-   * @param request
-   *          The compare request.
-   * @param resultHandler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @param intermediateResponseHandler
-   *          An intermediate response handler which can be used to process any
-   *          intermediate responses as they are received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support compare operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<CompareResult> compare(CompareRequest request,
-      ResultHandler<? super CompareResult> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Deletes an entry from the Directory Server using the provided delete
-   * request. Any intermediate responses will be ignored.
-   *
-   * @param request
-   *          The delete request.
-   * @param handler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support delete operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<Result> delete(DeleteRequest request,
-      ResultHandler<? super Result> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Deletes an entry from the Directory Server using the provided delete
-   * request.
-   *
-   * @param request
-   *          The delete request.
-   * @param resultHandler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @param intermediateResponseHandler
-   *          An intermediate response handler which can be used to process any
-   *          intermediate responses as they are received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support delete operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<Result> delete(DeleteRequest request,
-      ResultHandler<? super Result> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Requests that the Directory Server performs the provided extended request.
-   * Any intermediate responses will be ignored.
-   *
-   * @param <R>
-   *          The type of result returned by the extended request.
-   * @param request
-   *          The extended request.
-   * @param handler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support extended operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  <R extends ExtendedResult> FutureResult<R> extendedRequest(
-      ExtendedRequest<R> request, ResultHandler<? super R> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Requests that the Directory Server performs the provided extended request.
-   *
-   * @param <R>
-   *          The type of result returned by the extended request.
-   * @param request
-   *          The extended request.
-   * @param resultHandler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @param intermediateResponseHandler
-   *          An intermediate response handler which can be used to process any
-   *          intermediate responses as they are received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support extended operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  <R extends ExtendedResult> FutureResult<R> extendedRequest(
-      ExtendedRequest<R> request, ResultHandler<? super R> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Returns a synchronous connection sharing the same underlying network
-   * connection as this asynchronous connection.
-   *
-   * @return A synchronous connection sharing the same underlying network
-   *         connection as this asynchronous connection.
-   */
-  Connection getSynchronousConnection();
-
-
-
-  /**
-   * Indicates whether or not this connection has been explicitly closed by
-   * calling {@code close}. This method will not return {@code true} if a fatal
-   * error has occurred on the connection unless {@code close} has been called.
-   *
-   * @return {@code true} if this connection has been explicitly closed by
-   *         calling {@code close}, or {@code false} otherwise.
-   */
-  boolean isClosed();
-
-
-
-  /**
-   * Returns {@code true} if this connection has not been closed and no fatal
-   * errors have been detected. This method is guaranteed to return
-   * {@code false} only when it is called after the method {@code close} has
-   * been called.
-   *
-   * @return {@code true} if the connection is valid, {@code false} otherwise.
-   */
-  boolean isValid();
-
-
-
-  /**
-   * Modifies an entry in the Directory Server using the provided modify
-   * request. Any intermediate responses will be ignored.
-   *
-   * @param request
-   *          The modify request.
-   * @param handler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support modify operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<Result> modify(ModifyRequest request,
-      ResultHandler<? super Result> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Modifies an entry in the Directory Server using the provided modify
-   * request.
-   *
-   * @param request
-   *          The modify request.
-   * @param resultHandler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @param intermediateResponseHandler
-   *          An intermediate response handler which can be used to process any
-   *          intermediate responses as they are received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support modify operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<Result> modify(ModifyRequest request,
-      ResultHandler<? super Result> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Renames an entry in the Directory Server using the provided modify DN
-   * request. Any intermediate responses will be ignored.
-   *
-   * @param request
-   *          The modify DN request.
-   * @param handler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support modify DN operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<Result> modifyDN(ModifyDNRequest request,
-      ResultHandler<? super Result> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Renames an entry in the Directory Server using the provided modify DN
-   * request.
-   *
-   * @param request
-   *          The modify DN request.
-   * @param resultHandler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @param intermediateResponseHandler
-   *          An intermediate response handler which can be used to process any
-   *          intermediate responses as they are received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support modify DN operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<Result> modifyDN(ModifyDNRequest request,
-      ResultHandler<? super Result> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Reads the named entry from the Directory Server.
-   * <p>
-   * If the requested entry is not returned by the Directory Server then the
-   * request will fail with an {@link EntryNotFoundException}. More
-   * specifically, the returned future will never return {@code null}.
-   * <p>
-   * This method is equivalent to the following code:
-   *
-   * <pre>
-   * SearchRequest request = new SearchRequest(name, SearchScope.BASE_OBJECT,
-   *     &quot;(objectClass=*)&quot;, attributeDescriptions);
-   * connection.searchSingleEntry(request, resultHandler, p);
-   * </pre>
-   *
-   * @param name
-   *          The distinguished name of the entry to be read.
-   * @param attributeDescriptions
-   *          The names of the attributes to be included with the entry, which
-   *          may be {@code null} or empty indicating that all user attributes
-   *          should be returned.
-   * @param handler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support search operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If the {@code name} was {@code null}.
-   */
-  FutureResult<SearchResultEntry> readEntry(DN name,
-      Collection<String> attributeDescriptions,
-      ResultHandler<? super SearchResultEntry> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Removes the provided connection event listener from this connection so that
-   * it will no longer be notified when this connection is closed by the
-   * application, receives an unsolicited notification, or experiences a fatal
-   * error.
-   *
-   * @param listener
-   *          The listener which no longer wants to be notified when events
-   *          occur on this connection.
-   * @throws NullPointerException
-   *           If the {@code listener} was {@code null}.
-   */
-  void removeConnectionEventListener(ConnectionEventListener listener)
-      throws NullPointerException;
-
-
-
-  /**
-   * Searches the Directory Server using the provided search request. Any
-   * intermediate responses will be ignored.
-   *
-   * @param request
-   *          The search request.
-   * @param handler
-   *          A search result handler which can be used to asynchronously
-   *          process the search result entries and references as they are
-   *          received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support search operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<Result> search(SearchRequest request,
-      SearchResultHandler handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Searches the Directory Server using the provided search request.
-   *
-   * @param request
-   *          The search request.
-   * @param resultHandler
-   *          A search result handler which can be used to asynchronously
-   *          process the search result entries and references as they are
-   *          received, may be {@code null}.
-   * @param intermediateResponseHandler
-   *          An intermediate response handler which can be used to process any
-   *          intermediate responses as they are received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support search operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If {@code request} was {@code null}.
-   */
-  FutureResult<Result> search(SearchRequest request,
-      SearchResultHandler resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-
-
-
-  /**
-   * Searches the Directory Server for a single entry using the provided search
-   * request.
-   * <p>
-   * If the requested entry is not returned by the Directory Server then the
-   * request will fail with an {@link EntryNotFoundException}. More
-   * specifically, the returned future will never return {@code null}. If
-   * multiple matching entries are returned by the Directory Server then the
-   * request will fail with an {@link MultipleEntriesFoundException}.
-   *
-   * @param request
-   *          The search request.
-   * @param handler
-   *          A result handler which can be used to asynchronously process the
-   *          operation result when it is received, may be {@code null}.
-   * @return A future representing the result of the operation.
-   * @throws UnsupportedOperationException
-   *           If this connection does not support search operations.
-   * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if
-   *           {@code isClosed() == true}.
-   * @throws NullPointerException
-   *           If the {@code request} was {@code null}.
-   */
-  FutureResult<SearchResultEntry> searchSingleEntry(SearchRequest request,
-      ResultHandler<? super SearchResultEntry> handler)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
-}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AuthenticatedConnectionFactory.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AuthenticatedConnectionFactory.java
index 70c4b7f..dcd524f 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AuthenticatedConnectionFactory.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AuthenticatedConnectionFactory.java
@@ -23,17 +23,18 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
 
 
 
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
 import org.forgerock.opendj.ldap.requests.BindRequest;
 import org.forgerock.opendj.ldap.responses.BindResult;
 
-import com.forgerock.opendj.util.AbstractConnectionFactory;
-import com.forgerock.opendj.util.AsynchronousConnectionDecorator;
+import com.forgerock.opendj.util.ConnectionDecorator;
 import com.forgerock.opendj.util.FutureResultTransformer;
 import com.forgerock.opendj.util.RecursiveFutureResult;
 
@@ -51,19 +52,16 @@
  * the connection attempt will fail and an {@code ErrorResultException} will be
  * thrown.
  */
-final class AuthenticatedConnectionFactory extends AbstractConnectionFactory
+final class AuthenticatedConnectionFactory implements ConnectionFactory
 {
 
   /**
-   * An authenticated asynchronous connection supports all operations except
-   * Bind operations.
+   * An authenticated connection supports all operations except Bind operations.
    */
-  public static final class AuthenticatedAsynchronousConnection extends
-      AsynchronousConnectionDecorator
+  public static final class AuthenticatedConnection extends ConnectionDecorator
   {
 
-    private AuthenticatedAsynchronousConnection(
-        final AsynchronousConnection connection)
+    private AuthenticatedConnection(final Connection connection)
     {
       super(connection);
     }
@@ -74,8 +72,13 @@
      * Bind operations are not supported by pre-authenticated connections. This
      * method will always throw {@code UnsupportedOperationException}.
      */
-    public FutureResult<BindResult> bind(final BindRequest request,
-        final ResultHandler<? super BindResult> handler)
+
+    /**
+     * {@inheritDoc}
+     */
+    public FutureResult<BindResult> bindAsync(final BindRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super BindResult> resultHandler)
         throws UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
@@ -85,14 +88,24 @@
 
 
     /**
-     * Bind operations are not supported by pre-authenticated connections. This
-     * method will always throw {@code UnsupportedOperationException}.
+     * {@inheritDoc}
      */
-    public FutureResult<BindResult> bind(final BindRequest request,
-        final ResultHandler<? super BindResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
-        throws UnsupportedOperationException, IllegalStateException,
-        NullPointerException
+    public BindResult bind(BindRequest request) throws ErrorResultException,
+        InterruptedException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
+    {
+      throw new UnsupportedOperationException();
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public BindResult bind(String name, char[] password)
+        throws ErrorResultException, InterruptedException,
+        LocalizedIllegalArgumentException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
     {
       throw new UnsupportedOperationException();
     }
@@ -117,21 +130,21 @@
 
   private static final class FutureResultImpl
   {
-    private final FutureResultTransformer<BindResult, AsynchronousConnection> futureBindResult;
+    private final FutureResultTransformer<BindResult, Connection> futureBindResult;
 
-    private final RecursiveFutureResult<AsynchronousConnection, BindResult> futureConnectionResult;
+    private final RecursiveFutureResult<Connection, BindResult> futureConnectionResult;
 
     private final BindRequest bindRequest;
 
-    private AsynchronousConnection connection;
+    private Connection connection;
 
 
 
     private FutureResultImpl(final BindRequest request,
-        final ResultHandler<? super AsynchronousConnection> handler)
+        final ResultHandler<? super Connection> handler)
     {
       this.bindRequest = request;
-      this.futureBindResult = new FutureResultTransformer<BindResult, AsynchronousConnection>(
+      this.futureBindResult = new FutureResultTransformer<BindResult, Connection>(
           handler)
       {
 
@@ -140,40 +153,33 @@
             final ErrorResultException errorResult)
         {
           // Ensure that the connection is closed.
-          try
-          {
-            connection.close();
-            connection = null;
-          }
-          catch (final Exception e)
-          {
-            // Ignore.
-          }
+          connection.close();
+          connection = null;
           return errorResult;
         }
 
 
 
         @Override
-        protected AsynchronousConnection transformResult(final BindResult result)
+        protected Connection transformResult(final BindResult result)
             throws ErrorResultException
         {
-          return new AuthenticatedAsynchronousConnection(connection);
+          return new AuthenticatedConnection(connection);
         }
 
       };
-      this.futureConnectionResult = new RecursiveFutureResult<AsynchronousConnection, BindResult>(
+      this.futureConnectionResult = new RecursiveFutureResult<Connection, BindResult>(
           futureBindResult)
       {
 
         @Override
         protected FutureResult<? extends BindResult> chainResult(
-            final AsynchronousConnection innerResult,
+            final Connection innerResult,
             final ResultHandler<? super BindResult> handler)
             throws ErrorResultException
         {
           connection = innerResult;
-          return connection.bind(bindRequest, handler);
+          return connection.bindAsync(bindRequest, null, handler);
         }
       };
       futureBindResult.setFutureResult(futureConnectionResult);
@@ -214,13 +220,40 @@
   /**
    * {@inheritDoc}
    */
+  public Connection getConnection() throws ErrorResultException,
+      InterruptedException
+  {
+    final Connection connection = parentFactory.getConnection();
+    boolean bindSucceeded = false;
+    try
+    {
+      connection.bind(request);
+      bindSucceeded = true;
+    }
+    finally
+    {
+      if (!bindSucceeded)
+      {
+        connection.close();
+      }
+    }
+    // If the bind didn't succeed then an exception will have been thrown and
+    // this line will not be reached.
+    return new AuthenticatedConnection(connection);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
   @Override
-  public FutureResult<AsynchronousConnection> getAsynchronousConnection(
-      final ResultHandler<? super AsynchronousConnection> handler)
+  public FutureResult<Connection> getConnectionAsync(
+      final ResultHandler<? super Connection> handler)
   {
     final FutureResultImpl future = new FutureResultImpl(request, handler);
     future.futureConnectionResult.setFutureResult(parentFactory
-        .getAsynchronousConnection(future.futureConnectionResult));
+        .getConnectionAsync(future.futureConnectionResult));
     return future.futureBindResult;
   }
 
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connection.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connection.java
index f19e9ff..697f44a 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connection.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connection.java
@@ -42,17 +42,78 @@
 
 
 /**
- * A synchronous connection with a Directory Server over which read and update
- * operations may be performed. See RFC 4511 for the LDAPv3 protocol
- * specification and more information about the types of operations defined in
- * LDAP.
+ * A connection with a Directory Server over which read and update operations
+ * may be performed. See RFC 4511 for the LDAPv3 protocol specification and more
+ * information about the types of operations defined in LDAP.
  * <p>
  * <h3>Operation processing</h3>
  * <p>
- * All operations are performed synchronously and return an appropriate
- * {@link Result} representing the final status of the operation. Operation
- * failures, for whatever reason, are signalled using an
- * {@link ErrorResultException}.
+ * Operations may be performed synchronously or asynchronously depending on the
+ * method chosen. Asynchronous methods can be identified by their {@code Async}
+ * suffix.
+ * <p>
+ * <h4>Performing operations synchronously</h4>
+ * <p>
+ * Synchronous methods block until a response is received from the Directory
+ * Server, at which point an appropriate {@link Result} object is returned if
+ * the operation succeeded, or thrown as an {@link ErrorResultException} if the
+ * operation failed.
+ * <p>
+ * Since synchronous operations block the calling thread, the only way to
+ * abandon a long running operation is to interrupt the calling thread from
+ * another thread. This will cause the calling thread unblock and throw an
+ * {@link InterruptedException}.
+ * <p>
+ * <h4>Performing operations asynchronously</h4>
+ * <p>
+ * Asynchronous methods, identified by their {code Async} suffix, are
+ * non-blocking, returning a {@link FutureResult} or sub-type thereof which can
+ * be used for retrieving the result using the {@link FutureResult#get} method.
+ * Operation failures, for whatever reason, are signalled by the
+ * {@link FutureResult#get()} method throwing an {@link ErrorResultException}.
+ * <p>
+ * In addition to returning a {@code FutureResult}, all asynchronous methods
+ * accept a {@link ResultHandler} which will be notified upon completion of the
+ * operation.
+ * <p>
+ * Synchronous operations are easily simulated by immediately getting the
+ * result:
+ *
+ * <pre>
+ * Connection connection = ...;
+ * AddRequest request = ...;
+ * // Will block until operation completes, and
+ * // throws exception on failure.
+ * connection.add(request).get();
+ * </pre>
+ *
+ * Operations can be performed in parallel while taking advantage of the
+ * simplicity of a synchronous application design:
+ *
+ * <pre>
+ * Connection connection1 = ...;
+ * Connection connection2 = ...;
+ * AddRequest request = ...;
+ * // Add the entry to the first server (don't block).
+ * FutureResult future1 = connection1.add(request);
+ * // Add the entry to the second server (in parallel).
+ * FutureResult future2 = connection2.add(request);
+ * // Total time = is O(1) instead of O(n).
+ * future1.get();
+ * future2.get();
+ * </pre>
+ *
+ * More complex client applications can take advantage of a fully asynchronous
+ * event driven design using {@link ResultHandler}s:
+ *
+ * <pre>
+ * Connection connection = ...;
+ * SearchRequest request = ...;
+ * // Process results in the search result handler
+ * // in a separate thread.
+ * SearchResponseHandler handle = ...;
+ * connection.search(request, handler);
+ * </pre>
  * <p>
  * <h3>Closing connections</h3>
  * <p>
@@ -80,6 +141,37 @@
 {
 
   /**
+   * Abandons the unfinished operation identified in the provided abandon
+   * request.
+   * <p>
+   * Abandon requests do not have a response, so invoking the method get() on
+   * the returned future will not block, nor return anything (it is Void), but
+   * may throw an exception if a problem occurred while sending the abandon
+   * request. In addition the returned future may be used in order to determine
+   * the message ID of the abandon request.
+   * <p>
+   * <b>Note:</b> a more convenient approach to abandoning unfinished
+   * asynchronous operations is provided via the
+   * {@link FutureResult#cancel(boolean)} method.
+   *
+   * @param request
+   *          The request identifying the operation to be abandoned.
+   * @return A future whose result is Void.
+   * @throws UnsupportedOperationException
+   *           If this connection does not support abandon operations.
+   * @throws IllegalStateException
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
+   * @throws NullPointerException
+   *           If {@code request} was {@code null}.
+   */
+  FutureResult<Void> abandonAsync(AbandonRequest request)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException;
+
+
+
+  /**
    * Adds an entry to the Directory Server using the provided add request.
    *
    * @param request
@@ -93,8 +185,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support add operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code request} was {@code null}.
    */
@@ -125,8 +217,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support add operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code entry} was {@code null} .
    */
@@ -161,8 +253,8 @@
    *           If {@code ldifLines} was empty, or contained invalid LDIF, or
    *           could not be decoded using the default schema.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code ldifLines} was {@code null} .
    */
@@ -174,6 +266,35 @@
 
 
   /**
+   * Asynchronously adds an entry to the Directory Server using the provided add
+   * request.
+   *
+   * @param request
+   *          The add request.
+   * @param intermediateResponseHandler
+   *          An intermediate response handler which can be used to process any
+   *          intermediate responses as they are received, may be {@code null}.
+   * @param resultHandler
+   *          A result handler which can be used to asynchronously process the
+   *          operation result when it is received, may be {@code null}.
+   * @return A future representing the result of the operation.
+   * @throws UnsupportedOperationException
+   *           If this connection does not support add operations.
+   * @throws IllegalStateException
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
+   * @throws NullPointerException
+   *           If {@code request} was {@code null}.
+   */
+  FutureResult<Result> addAsync(AddRequest request,
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super Result> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException;
+
+
+
+  /**
    * Registers the provided connection event listener so that it will be
    * notified when this connection is closed by the application, receives an
    * unsolicited notification, or experiences a fatal error.
@@ -182,8 +303,8 @@
    *          The listener which wants to be notified when events occur on this
    *          connection.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If the {@code listener} was {@code null}.
    */
@@ -206,8 +327,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support bind operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code request} was {@code null}.
    */
@@ -245,8 +366,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support bind operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code name} or {@code password} was {@code null}.
    */
@@ -258,6 +379,35 @@
 
 
   /**
+   * Asynchronously authenticates to the Directory Server using the provided
+   * bind request.
+   *
+   * @param request
+   *          The bind request.
+   * @param intermediateResponseHandler
+   *          An intermediate response handler which can be used to process any
+   *          intermediate responses as they are received, may be {@code null}.
+   * @param resultHandler
+   *          A result handler which can be used to asynchronously process the
+   *          operation result when it is received, may be {@code null}.
+   * @return A future representing the result of the operation.
+   * @throws UnsupportedOperationException
+   *           If this connection does not support bind operations.
+   * @throws IllegalStateException
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
+   * @throws NullPointerException
+   *           If {@code request} was {@code null}.
+   */
+  FutureResult<BindResult> bindAsync(BindRequest request,
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super BindResult> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException;
+
+
+
+  /**
    * Releases any resources associated with this connection. For physical
    * connections to a Directory Server this will mean that an unbind request is
    * sent and the underlying socket is closed.
@@ -319,8 +469,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support compare operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code request} was {@code null}.
    */
@@ -360,11 +510,11 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support compare operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
-   *           If {@code name}, {@code attributeDescription}, or {@code
-   *           assertionValue} was {@code null}.
+   *           If {@code name}, {@code attributeDescription}, or
+   *           {@code assertionValue} was {@code null}.
    */
   CompareResult compare(String name, String attributeDescription,
       String assertionValue) throws ErrorResultException, InterruptedException,
@@ -374,6 +524,35 @@
 
 
   /**
+   * Asynchronously compares an entry in the Directory Server using the provided
+   * compare request.
+   *
+   * @param request
+   *          The compare request.
+   * @param intermediateResponseHandler
+   *          An intermediate response handler which can be used to process any
+   *          intermediate responses as they are received, may be {@code null}.
+   * @param resultHandler
+   *          A result handler which can be used to asynchronously process the
+   *          operation result when it is received, may be {@code null}.
+   * @return A future representing the result of the operation.
+   * @throws UnsupportedOperationException
+   *           If this connection does not support compare operations.
+   * @throws IllegalStateException
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
+   * @throws NullPointerException
+   *           If {@code request} was {@code null}.
+   */
+  FutureResult<CompareResult> compareAsync(CompareRequest request,
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super CompareResult> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException;
+
+
+
+  /**
    * Deletes an entry from the Directory Server using the provided delete
    * request.
    *
@@ -388,8 +567,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support delete operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code request} was {@code null}.
    */
@@ -422,8 +601,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support delete operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code name} was {@code null}.
    */
@@ -434,6 +613,35 @@
 
 
   /**
+   * Asynchronously deletes an entry from the Directory Server using the
+   * provided delete request.
+   *
+   * @param request
+   *          The delete request.
+   * @param intermediateResponseHandler
+   *          An intermediate response handler which can be used to process any
+   *          intermediate responses as they are received, may be {@code null}.
+   * @param resultHandler
+   *          A result handler which can be used to asynchronously process the
+   *          operation result when it is received, may be {@code null}.
+   * @return A future representing the result of the operation.
+   * @throws UnsupportedOperationException
+   *           If this connection does not support delete operations.
+   * @throws IllegalStateException
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
+   * @throws NullPointerException
+   *           If {@code request} was {@code null}.
+   */
+  FutureResult<Result> deleteAsync(DeleteRequest request,
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super Result> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException;
+
+
+
+  /**
    * Requests that the Directory Server performs the provided extended request.
    *
    * @param <R>
@@ -449,8 +657,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support extended operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code request} was {@code null}.
    */
@@ -481,8 +689,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support extended operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code request} was {@code null}.
    */
@@ -519,8 +727,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support extended operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code requestName} was {@code null}.
    */
@@ -532,13 +740,34 @@
 
 
   /**
-   * Returns an asynchronous connection sharing the same underlying network
-   * connection as this synchronous connection.
+   * Asynchronously performs the provided extended request in the Directory
+   * Server.
    *
-   * @return An asynchronous connection sharing the same underlying network
-   *         connection as this synchronous connection.
+   * @param <R>
+   *          The type of result returned by the extended request.
+   * @param request
+   *          The extended request.
+   * @param intermediateResponseHandler
+   *          An intermediate response handler which can be used to process any
+   *          intermediate responses as they are received, may be {@code null}.
+   * @param resultHandler
+   *          A result handler which can be used to asynchronously process the
+   *          operation result when it is received, may be {@code null}.
+   * @return A future representing the result of the operation.
+   * @throws UnsupportedOperationException
+   *           If this connection does not support extended operations.
+   * @throws IllegalStateException
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
+   * @throws NullPointerException
+   *           If {@code request} was {@code null}.
    */
-  AsynchronousConnection getAsynchronousConnection();
+  <R extends ExtendedResult> FutureResult<R> extendedRequestAsync(
+      ExtendedRequest<R> request,
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super R> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException;
 
 
 
@@ -556,9 +785,9 @@
 
   /**
    * Returns {@code true} if this connection has not been closed and no fatal
-   * errors have been detected. This method is guaranteed to return {@code
-   * false} only when it is called after the method {@code close} has been
-   * called.
+   * errors have been detected. This method is guaranteed to return
+   * {@code false} only when it is called after the method {@code close} has
+   * been called.
    *
    * @return {@code true} if this connection is valid, {@code false} otherwise.
    */
@@ -581,8 +810,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support modify operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code request} was {@code null}.
    */
@@ -616,8 +845,8 @@
    *           If {@code ldifLines} was empty, or contained invalid LDIF, or
    *           could not be decoded using the default schema.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code ldifLines} was {@code null} .
    */
@@ -629,6 +858,35 @@
 
 
   /**
+   * Asynchronously modifies an entry in the Directory Server using the provided
+   * modify request.
+   *
+   * @param request
+   *          The modify request.
+   * @param intermediateResponseHandler
+   *          An intermediate response handler which can be used to process any
+   *          intermediate responses as they are received, may be {@code null}.
+   * @param resultHandler
+   *          A result handler which can be used to asynchronously process the
+   *          operation result when it is received, may be {@code null}.
+   * @return A future representing the result of the operation.
+   * @throws UnsupportedOperationException
+   *           If this connection does not support modify operations.
+   * @throws IllegalStateException
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
+   * @throws NullPointerException
+   *           If {@code request} was {@code null}.
+   */
+  FutureResult<Result> modifyAsync(ModifyRequest request,
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super Result> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException;
+
+
+
+  /**
    * Renames an entry in the Directory Server using the provided modify DN
    * request.
    *
@@ -643,8 +901,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support modify DN operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code request} was {@code null}.
    */
@@ -680,8 +938,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support modify DN operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code name} or {@code newRDN} was {@code null}.
    */
@@ -693,6 +951,35 @@
 
 
   /**
+   * Asynchronously renames an entry in the Directory Server using the provided
+   * modify DN request.
+   *
+   * @param request
+   *          The modify DN request.
+   * @param intermediateResponseHandler
+   *          An intermediate response handler which can be used to process any
+   *          intermediate responses as they are received, may be {@code null}.
+   * @param resultHandler
+   *          A result handler which can be used to asynchronously process the
+   *          operation result when it is received, may be {@code null}.
+   * @return A future representing the result of the operation.
+   * @throws UnsupportedOperationException
+   *           If this connection does not support modify DN operations.
+   * @throws IllegalStateException
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
+   * @throws NullPointerException
+   *           If {@code request} was {@code null}.
+   */
+  FutureResult<Result> modifyDNAsync(ModifyDNRequest request,
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super Result> resultHandler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException;
+
+
+
+  /**
    * Reads the named entry from the Directory Server.
    * <p>
    * If the requested entry is not returned by the Directory Server then the
@@ -722,8 +1009,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support search operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If the {@code name} was {@code null}.
    */
@@ -765,8 +1052,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support search operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If the {@code name} was {@code null}.
    */
@@ -778,6 +1065,47 @@
 
 
   /**
+   * Asynchronously reads the named entry from the Directory Server.
+   * <p>
+   * If the requested entry is not returned by the Directory Server then the
+   * request will fail with an {@link EntryNotFoundException}. More
+   * specifically, the returned future will never return {@code null}.
+   * <p>
+   * This method is equivalent to the following code:
+   *
+   * <pre>
+   * SearchRequest request = new SearchRequest(name, SearchScope.BASE_OBJECT,
+   *     &quot;(objectClass=*)&quot;, attributeDescriptions);
+   * connection.searchSingleEntryAsync(request, resultHandler, p);
+   * </pre>
+   *
+   * @param name
+   *          The distinguished name of the entry to be read.
+   * @param attributeDescriptions
+   *          The names of the attributes to be included with the entry, which
+   *          may be {@code null} or empty indicating that all user attributes
+   *          should be returned.
+   * @param handler
+   *          A result handler which can be used to asynchronously process the
+   *          operation result when it is received, may be {@code null}.
+   * @return A future representing the result of the operation.
+   * @throws UnsupportedOperationException
+   *           If this connection does not support search operations.
+   * @throws IllegalStateException
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
+   * @throws NullPointerException
+   *           If the {@code name} was {@code null}.
+   */
+  FutureResult<SearchResultEntry> readEntryAsync(DN name,
+      Collection<String> attributeDescriptions,
+      ResultHandler<? super SearchResultEntry> handler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException;
+
+
+
+  /**
    * Removes the provided connection event listener from this connection so that
    * it will no longer be notified when this connection is closed by the
    * application, receives an unsolicited notification, or experiences a fatal
@@ -795,6 +1123,34 @@
 
 
   /**
+   * Searches the Directory Server using the provided search parameters. Any
+   * matching entries returned by the search will be exposed through the
+   * {@code EntryReader} interface.
+   * <p>
+   * <b>Warning:</b> When using a queue with an optional capacity bound, the
+   * connection will stop reading responses and wait if necessary for space to
+   * become available.
+   *
+   * @param request
+   *          The search request.
+   * @param entries
+   *          The queue to which matching entries should be added.
+   * @return The result of the operation.
+   * @throws UnsupportedOperationException
+   *           If this connection does not support search operations.
+   * @throws IllegalStateException
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
+   * @throws NullPointerException
+   *           If {@code request} or {@code entries} was {@code null}.
+   */
+  ConnectionEntryReader search(SearchRequest request,
+      BlockingQueue<Response> entries) throws UnsupportedOperationException,
+      IllegalStateException, NullPointerException;
+
+
+
+  /**
    * Searches the Directory Server using the provided search request. Any
    * matching entries returned by the search will be added to {@code entries},
    * even if the final search result indicates that the search failed. Search
@@ -802,8 +1158,8 @@
    * <p>
    * <b>Warning:</b> Usage of this method is discouraged if the search request
    * is expected to yield a large number of search results since the entire set
-   * of results will be stored in memory, potentially causing an {@code
-   * OutOfMemoryError}.
+   * of results will be stored in memory, potentially causing an
+   * {@code OutOfMemoryError}.
    * <p>
    * This method is equivalent to the following code:
    *
@@ -824,8 +1180,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support search operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code request} or {@code entries} was {@code null}.
    */
@@ -846,8 +1202,8 @@
    * <p>
    * <b>Warning:</b> Usage of this method is discouraged if the search request
    * is expected to yield a large number of search results since the entire set
-   * of results will be stored in memory, potentially causing an {@code
-   * OutOfMemoryError}.
+   * of results will be stored in memory, potentially causing an
+   * {@code OutOfMemoryError}.
    *
    * @param request
    *          The search request.
@@ -865,8 +1221,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support search operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code request} or {@code entries} was {@code null}.
    */
@@ -888,8 +1244,8 @@
    *          The search request.
    * @param handler
    *          A search result handler which can be used to process the search
-   *          result entries and references as they are received, may be {@code
-   *          null}.
+   *          result entries and references as they are received, may be
+   *          {@code null}.
    * @return The result of the operation.
    * @throws ErrorResultException
    *           If the result code indicates that the request failed for some
@@ -899,8 +1255,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support search operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If {@code request} was {@code null}.
    */
@@ -916,9 +1272,9 @@
    * matching entries returned by the search will be exposed through the
    * {@code EntryReader} interface.
    * <p>
-   * <b>Warning:</b> When using a queue with an optional capacity bound,
-   * the connection will stop reading responses and wait if necessary for
-   * space to become available.
+   * <b>Warning:</b> When using a queue with an optional capacity bound, the
+   * connection will stop reading responses and wait if necessary for space to
+   * become available.
    * <p>
    * This method is equivalent to the following code:
    *
@@ -942,44 +1298,46 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support search operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If the {@code baseObject}, {@code scope}, or {@code filter} were
    *           {@code null}.
    */
   ConnectionEntryReader search(String baseObject, SearchScope scope,
       String filter, String... attributeDescriptions)
-      throws UnsupportedOperationException,
-      IllegalStateException, NullPointerException;
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException;
+
 
 
   /**
-   * Searches the Directory Server using the provided search parameters. Any
-   * matching entries returned by the search will be exposed through the
-   * {@code EntryReader} interface.
-   * <p>
-   * <b>Warning:</b> When using a queue with an optional capacity bound,
-   * the connection will stop reading responses and wait if necessary for
-   * space to become available.
+   * Asynchronously searches the Directory Server using the provided search
+   * request.
    *
    * @param request
    *          The search request.
-   * @param entries
-   *          The queue to which matching entries should be added.
-   * @return The result of the operation.
+   * @param intermediateResponseHandler
+   *          An intermediate response handler which can be used to process any
+   *          intermediate responses as they are received, may be {@code null}.
+   * @param resultHandler
+   *          A search result handler which can be used to asynchronously
+   *          process the search result entries and references as they are
+   *          received, may be {@code null}.
+   * @return A future representing the result of the operation.
    * @throws UnsupportedOperationException
    *           If this connection does not support search operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
-   *           If {@code request} or {@code entries} was {@code null}.
+   *           If {@code request} was {@code null}.
    */
-  ConnectionEntryReader search(SearchRequest request,
-                               BlockingQueue<Response> entries)
-      throws UnsupportedOperationException, IllegalStateException,
-      NullPointerException;
+  FutureResult<Result> searchAsync(SearchRequest request,
+      IntermediateResponseHandler intermediateResponseHandler,
+      SearchResultHandler resultHandler) throws UnsupportedOperationException,
+      IllegalStateException, NullPointerException;
+
 
 
   /**
@@ -1003,8 +1361,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support search operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If the {@code request} was {@code null}.
    */
@@ -1056,8 +1414,8 @@
    * @throws UnsupportedOperationException
    *           If this connection does not support search operations.
    * @throws IllegalStateException
-   *           If this connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If the {@code baseObject}, {@code scope}, or {@code filter} were
    *           {@code null}.
@@ -1067,4 +1425,35 @@
       throws ErrorResultException, InterruptedException,
       LocalizedIllegalArgumentException, UnsupportedOperationException,
       IllegalStateException, NullPointerException;
+
+
+
+  /**
+   * Asynchronously searches the Directory Server for a single entry using the
+   * provided search request.
+   * <p>
+   * If the requested entry is not returned by the Directory Server then the
+   * request will fail with an {@link EntryNotFoundException}. More
+   * specifically, the returned future will never return {@code null}. If
+   * multiple matching entries are returned by the Directory Server then the
+   * request will fail with an {@link MultipleEntriesFoundException}.
+   *
+   * @param request
+   *          The search request.
+   * @param handler
+   *          A result handler which can be used to asynchronously process the
+   *          operation result when it is received, may be {@code null}.
+   * @return A future representing the result of the operation.
+   * @throws UnsupportedOperationException
+   *           If this connection does not support search operations.
+   * @throws IllegalStateException
+   *           If this connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
+   * @throws NullPointerException
+   *           If the {@code request} was {@code null}.
+   */
+  FutureResult<SearchResultEntry> searchSingleEntryAsync(SearchRequest request,
+      ResultHandler<? super SearchResultEntry> handler)
+      throws UnsupportedOperationException, IllegalStateException,
+      NullPointerException;
 }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionFactory.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionFactory.java
index 292fd69..c729819 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionFactory.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionFactory.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
@@ -54,19 +55,19 @@
 public interface ConnectionFactory
 {
   /**
-   * Initiates an asynchronous connection request to the Directory Server
-   * associated with this connection factory. The returned {@code FutureResult}
-   * can be used to retrieve the completed asynchronous connection.
-   * Alternatively, if a {@code ResultHandler} is provided, the handler will be
-   * notified when the connection is available and ready for use.
+   * Asynchronously obtains a connection to the Directory Server associated with
+   * this connection factory. The returned {@code FutureResult} can be used to
+   * retrieve the completed connection. Alternatively, if a
+   * {@code ResultHandler} is provided, the handler will be notified when the
+   * connection is available and ready for use.
    *
    * @param handler
    *          The completion handler, or {@code null} if no handler is to be
    *          used.
-   * @return A future which can be used to retrieve the asynchronous connection.
+   * @return A future which can be used to retrieve the connection.
    */
-  FutureResult<AsynchronousConnection> getAsynchronousConnection(
-      ResultHandler<? super AsynchronousConnection> handler);
+  FutureResult<Connection> getConnectionAsync(
+      ResultHandler<? super Connection> handler);
 
 
 
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionPool.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionPool.java
index ac686e4..b11862c 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionPool.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ConnectionPool.java
@@ -64,11 +64,11 @@
 
 
   /**
-   * Obtains an asynchronous connection from this connection pool, potentially
+   * Asynchronously obtains a connection from this connection pool, potentially
    * opening a new connection if needed.
    * <p>
    * The returned {@code FutureResult} can be used to retrieve the pooled
-   * asynchronous connection. Alternatively, if a {@code ResultHandler} is
+   * connection. Alternatively, if a {@code ResultHandler} is
    * provided, the handler will be notified when the pooled connection is
    * available and ready for use.
    * <p>
@@ -78,13 +78,12 @@
    * @param handler
    *          The completion handler, or {@code null} if no handler is to be
    *          used.
-   * @return A future which can be used to retrieve the pooled asynchronous
-   *         connection.
+   * @return A future which can be used to retrieve the pooled connection.
    * @throws IllegalStateException
    *           If this connection pool has already been closed.
    */
-  FutureResult<AsynchronousConnection> getAsynchronousConnection(
-      ResultHandler<? super AsynchronousConnection> handler);
+  FutureResult<Connection> getConnectionAsync(
+      ResultHandler<? super Connection> handler);
 
 
 
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java
index 0429693..a5eb899 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java
@@ -151,9 +151,6 @@
 
 
 
-
-
-
   /**
    * Creates a new heart-beat connection factory which will create connections
    * using the provided connection factory and periodically ping any created
@@ -184,9 +181,6 @@
 
 
 
-
-
-
   /**
    * Creates a new heart-beat connection factory which will create connections
    * using the provided connection factory and periodically ping any created
@@ -304,10 +298,10 @@
     {
 
       @Override
-      public FutureResult<AsynchronousConnection> getAsynchronousConnection(
-          final ResultHandler<? super AsynchronousConnection> handler)
+      public FutureResult<Connection> getConnectionAsync(
+          final ResultHandler<? super Connection> handler)
       {
-        return factory.getAsynchronousConnection(handler);
+        return factory.getConnectionAsync(handler);
       }
 
 
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java
index f20244f..6b2be72 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java
@@ -35,15 +35,21 @@
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Level;
 
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
 import org.forgerock.opendj.ldap.requests.*;
 import org.forgerock.opendj.ldap.responses.*;
+import org.forgerock.opendj.ldif.ConnectionEntryReader;
 
-import com.forgerock.opendj.util.*;
+import com.forgerock.opendj.util.AsynchronousFutureResult;
+import com.forgerock.opendj.util.CompletedFutureResult;
+import com.forgerock.opendj.util.StaticUtils;
+import com.forgerock.opendj.util.Validator;
 
 
 
@@ -51,8 +57,7 @@
  * A simple connection pool implementation which maintains a fixed number of
  * connections.
  */
-final class FixedConnectionPool extends AbstractConnectionFactory implements
-    ConnectionPool
+final class FixedConnectionPool implements ConnectionPool
 {
 
   /**
@@ -60,7 +65,7 @@
    * the pool completes.
    */
   private final class ConnectionResultHandler implements
-      ResultHandler<AsynchronousConnection>
+      ResultHandler<Connection>
   {
     /**
      * {@inheritDoc}
@@ -102,7 +107,7 @@
      * {@inheritDoc}
      */
     @Override
-    public void handleResult(final AsynchronousConnection connection)
+    public void handleResult(final Connection connection)
     {
       if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
       {
@@ -124,77 +129,76 @@
    * the client application closes this connection. More specifically, pooled
    * connections are not actually stored in the internal queue.
    */
-  private final class PooledConnection implements AsynchronousConnection
+  private final class PooledConnection implements Connection
   {
     // Connection event listeners registed against this pooled connection should
     // have the same life time as the pooled connection.
     private final List<ConnectionEventListener> listeners =
-      new CopyOnWriteArrayList<ConnectionEventListener>();
+        new CopyOnWriteArrayList<ConnectionEventListener>();
 
-    private final AsynchronousConnection connection;
+    private final Connection connection;
 
     private final AtomicBoolean isClosed = new AtomicBoolean(false);
 
 
 
-    PooledConnection(final AsynchronousConnection connection)
+    PooledConnection(final Connection connection)
     {
       this.connection = connection;
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<Void> abandon(final AbandonRequest request)
+    public FutureResult<Void> abandonAsync(final AbandonRequest request)
         throws UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.abandon(request);
+      return checkState().abandonAsync(request);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<Result> add(final AddRequest request,
-        final ResultHandler<? super Result> handler)
-        throws UnsupportedOperationException, IllegalStateException,
-        NullPointerException
+    public Result add(final AddRequest request) throws ErrorResultException,
+        InterruptedException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.add(request, handler);
+      return checkState().add(request);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<Result> add(final AddRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+    public Result add(final Entry entry) throws ErrorResultException,
+        InterruptedException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
+    {
+      return checkState().add(entry);
+    }
+
+
+
+    @Override
+    public Result add(final String... ldifLines) throws ErrorResultException,
+        InterruptedException, UnsupportedOperationException,
+        LocalizedIllegalArgumentException, IllegalStateException,
+        NullPointerException
+    {
+      return checkState().add(ldifLines);
+    }
+
+
+
+    @Override
+    public FutureResult<Result> addAsync(final AddRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection
-          .add(request, resultHandler, intermediateResponseHandler);
+      return checkState().addAsync(request, intermediateResponseHandler,
+          resultHandler);
     }
 
 
@@ -208,49 +212,43 @@
         NullPointerException
     {
       Validator.ensureNotNull(listener);
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
+      checkState();
       listeners.add(listener);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<BindResult> bind(final BindRequest request,
-        final ResultHandler<? super BindResult> handler)
-        throws UnsupportedOperationException, IllegalStateException,
+    public BindResult bind(final BindRequest request)
+        throws ErrorResultException, InterruptedException,
+        UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.bind(request, handler);
+      return checkState().bind(request);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<BindResult> bind(final BindRequest request,
-        final ResultHandler<? super BindResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+    public BindResult bind(final String name, final char[] password)
+        throws ErrorResultException, InterruptedException,
+        LocalizedIllegalArgumentException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
+    {
+      return checkState().bind(name, password);
+    }
+
+
+
+    @Override
+    public FutureResult<BindResult> bindAsync(final BindRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super BindResult> resultHandler)
         throws UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.bind(request, resultHandler,
-          intermediateResponseHandler);
+      return checkState().bindAsync(request, intermediateResponseHandler,
+          resultHandler);
     }
 
 
@@ -282,7 +280,7 @@
         connection.close();
 
         // Try to get a new connection to replace it.
-        factory.getAsynchronousConnection(connectionResultHandler);
+        factory.getConnectionAsync(connectionResultHandler);
 
         if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
         {
@@ -308,128 +306,122 @@
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<CompareResult> compare(final CompareRequest request,
-        final ResultHandler<? super CompareResult> handler)
-        throws UnsupportedOperationException, IllegalStateException,
+    public CompareResult compare(final CompareRequest request)
+        throws ErrorResultException, InterruptedException,
+        UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.compare(request, handler);
+      return checkState().compare(request);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<CompareResult> compare(final CompareRequest request,
-        final ResultHandler<? super CompareResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
-        throws UnsupportedOperationException, IllegalStateException,
-        NullPointerException
+    public CompareResult compare(final String name,
+        final String attributeDescription, final String assertionValue)
+        throws ErrorResultException, InterruptedException,
+        LocalizedIllegalArgumentException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.compare(request, resultHandler,
-          intermediateResponseHandler);
+      return checkState().compare(name, attributeDescription, assertionValue);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<Result> delete(final DeleteRequest request,
-        final ResultHandler<? super Result> handler)
+    public FutureResult<CompareResult> compareAsync(
+        final CompareRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super CompareResult> resultHandler)
         throws UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.delete(request, handler);
+      return checkState().compareAsync(request, intermediateResponseHandler,
+          resultHandler);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<Result> delete(final DeleteRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
-        throws UnsupportedOperationException, IllegalStateException,
+    public Result delete(final DeleteRequest request)
+        throws ErrorResultException, InterruptedException,
+        UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.delete(request, resultHandler,
-          intermediateResponseHandler);
+      return checkState().delete(request);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public <R extends ExtendedResult> FutureResult<R> extendedRequest(
-        final ExtendedRequest<R> request, final ResultHandler<? super R> handler)
-        throws UnsupportedOperationException, IllegalStateException,
+    public Result delete(final String name) throws ErrorResultException,
+        InterruptedException, LocalizedIllegalArgumentException,
+        UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.extendedRequest(request, handler);
+      return checkState().delete(name);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public <R extends ExtendedResult> FutureResult<R> extendedRequest(
+    public FutureResult<Result> deleteAsync(final DeleteRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      return checkState().deleteAsync(request, intermediateResponseHandler,
+          resultHandler);
+    }
+
+
+
+    @Override
+    public <R extends ExtendedResult> R extendedRequest(
+        final ExtendedRequest<R> request) throws ErrorResultException,
+        InterruptedException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
+    {
+      return checkState().extendedRequest(request);
+    }
+
+
+
+    @Override
+    public <R extends ExtendedResult> R extendedRequest(
         final ExtendedRequest<R> request,
-        final ResultHandler<? super R> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
-        throws UnsupportedOperationException, IllegalStateException,
-        NullPointerException
+        final IntermediateResponseHandler handler) throws ErrorResultException,
+        InterruptedException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.extendedRequest(request, resultHandler,
-          intermediateResponseHandler);
+      return checkState().extendedRequest(request, handler);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public Connection getSynchronousConnection()
+    public GenericExtendedResult extendedRequest(final String requestName,
+        final ByteString requestValue) throws ErrorResultException,
+        InterruptedException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
     {
-      return new SynchronousConnection(this);
+      return checkState().extendedRequest(requestName, requestValue);
+    }
+
+
+
+    @Override
+    public <R extends ExtendedResult> FutureResult<R> extendedRequestAsync(
+        final ExtendedRequest<R> request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super R> resultHandler)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      return checkState().extendedRequestAsync(request,
+          intermediateResponseHandler, resultHandler);
     }
 
 
@@ -456,97 +448,107 @@
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<Result> modify(final ModifyRequest request,
-        final ResultHandler<? super Result> handler)
-        throws UnsupportedOperationException, IllegalStateException,
+    public Result modify(final ModifyRequest request)
+        throws ErrorResultException, InterruptedException,
+        UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.modify(request, handler);
+      return checkState().modify(request);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<Result> modify(final ModifyRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
-        throws UnsupportedOperationException, IllegalStateException,
-        NullPointerException
+    public Result modify(final String... ldifLines)
+        throws ErrorResultException, InterruptedException,
+        UnsupportedOperationException, LocalizedIllegalArgumentException,
+        IllegalStateException, NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.modify(request, resultHandler,
-          intermediateResponseHandler);
+      return checkState().modify(ldifLines);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<Result> modifyDN(final ModifyDNRequest request,
-        final ResultHandler<? super Result> handler)
+    public FutureResult<Result> modifyAsync(final ModifyRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.modifyDN(request, handler);
+      return checkState().modifyAsync(request, intermediateResponseHandler,
+          resultHandler);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<Result> modifyDN(final ModifyDNRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
-        throws UnsupportedOperationException, IllegalStateException,
+    public Result modifyDN(final ModifyDNRequest request)
+        throws ErrorResultException, InterruptedException,
+        UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.modifyDN(request, resultHandler,
-          intermediateResponseHandler);
+      return checkState().modifyDN(request);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<SearchResultEntry> readEntry(final DN name,
+    public Result modifyDN(final String name, final String newRDN)
+        throws ErrorResultException, LocalizedIllegalArgumentException,
+        InterruptedException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
+    {
+      return checkState().modifyDN(name, newRDN);
+    }
+
+
+
+    @Override
+    public FutureResult<Result> modifyDNAsync(final ModifyDNRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      return checkState().modifyDNAsync(request, intermediateResponseHandler,
+          resultHandler);
+    }
+
+
+
+    @Override
+    public SearchResultEntry readEntry(final DN name,
+        final String... attributeDescriptions) throws ErrorResultException,
+        InterruptedException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
+    {
+      return checkState().readEntry(name, attributeDescriptions);
+    }
+
+
+
+    @Override
+    public SearchResultEntry readEntry(final String name,
+        final String... attributeDescriptions) throws ErrorResultException,
+        InterruptedException, LocalizedIllegalArgumentException,
+        UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      return checkState().readEntry(name, attributeDescriptions);
+    }
+
+
+
+    @Override
+    public FutureResult<SearchResultEntry> readEntryAsync(final DN name,
         final Collection<String> attributeDescriptions,
-        final ResultHandler<? super SearchResultEntry> resultHandler)
+        final ResultHandler<? super SearchResultEntry> handler)
         throws UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.readEntry(name, attributeDescriptions, resultHandler);
+      return checkState().readEntryAsync(name, attributeDescriptions, handler);
     }
 
 
@@ -559,68 +561,118 @@
         final ConnectionEventListener listener) throws NullPointerException
     {
       Validator.ensureNotNull(listener);
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
+      checkState();
       listeners.remove(listener);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<Result> search(final SearchRequest request,
-        final SearchResultHandler handler)
+    public ConnectionEntryReader search(final SearchRequest request,
+        final BlockingQueue<Response> entries)
         throws UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.search(request, handler);
+      return checkState().search(request, entries);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<Result> search(final SearchRequest request,
-        final SearchResultHandler resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
-        throws UnsupportedOperationException, IllegalStateException,
+    public Result search(final SearchRequest request,
+        final Collection<? super SearchResultEntry> entries)
+        throws ErrorResultException, InterruptedException,
+        UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.search(request, resultHandler,
-          intermediateResponseHandler);
+      return checkState().search(request, entries);
     }
 
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public FutureResult<SearchResultEntry> searchSingleEntry(
+    public Result search(final SearchRequest request,
+        final Collection<? super SearchResultEntry> entries,
+        final Collection<? super SearchResultReference> references)
+        throws ErrorResultException, InterruptedException,
+        UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      return checkState().search(request, entries, references);
+    }
+
+
+
+    @Override
+    public Result search(final SearchRequest request,
+        final SearchResultHandler handler) throws ErrorResultException,
+        InterruptedException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
+    {
+      return checkState().search(request, handler);
+    }
+
+
+
+    @Override
+    public ConnectionEntryReader search(final String baseObject,
+        final SearchScope scope, final String filter,
+        final String... attributeDescriptions)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      return checkState().search(baseObject, scope, filter,
+          attributeDescriptions);
+    }
+
+
+
+    @Override
+    public FutureResult<Result> searchAsync(final SearchRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final SearchResultHandler resultHandler)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      return checkState().searchAsync(request, intermediateResponseHandler,
+          resultHandler);
+    }
+
+
+
+    @Override
+    public SearchResultEntry searchSingleEntry(final SearchRequest request)
+        throws ErrorResultException, InterruptedException,
+        UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      return checkState().searchSingleEntry(request);
+    }
+
+
+
+    @Override
+    public SearchResultEntry searchSingleEntry(final String baseObject,
+        final SearchScope scope, final String filter,
+        final String... attributeDescriptions) throws ErrorResultException,
+        InterruptedException, LocalizedIllegalArgumentException,
+        UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      return checkState().searchSingleEntry(baseObject, scope, filter,
+          attributeDescriptions);
+    }
+
+
+
+    @Override
+    public FutureResult<SearchResultEntry> searchSingleEntryAsync(
         final SearchRequest request,
-        final ResultHandler<? super SearchResultEntry> resultHandler)
+        final ResultHandler<? super SearchResultEntry> handler)
         throws UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
-      if (isClosed())
-      {
-        throw new IllegalStateException();
-      }
-      return connection.searchSingleEntry(request, resultHandler);
+      return checkState().searchSingleEntryAsync(request, handler);
     }
 
 
@@ -637,14 +689,27 @@
       builder.append(')');
       return builder.toString();
     }
+
+
+
+    // Checks that this pooled connection has not been closed.
+    private Connection checkState()
+    {
+      if (isClosed())
+      {
+        throw new IllegalStateException();
+      }
+      return connection;
+    }
+
   }
 
 
 
   /**
    * A queue element is either a pending connection request future awaiting an
-   * {@code AsynchronousConnection} or it is an unused
-   * {@code AsynchronousConnection} awaiting a connection request.
+   * {@code Connection} or it is an unused {@code Connection} awaiting a
+   * connection request.
    */
   private static final class QueueElement
   {
@@ -652,16 +717,16 @@
 
 
 
-    QueueElement(final AsynchronousConnection connection)
+    QueueElement(final Connection connection)
     {
       this.value = connection;
     }
 
 
 
-    QueueElement(final ResultHandler<? super AsynchronousConnection> handler)
+    QueueElement(final ResultHandler<? super Connection> handler)
     {
-      this.value = new AsynchronousFutureResult<AsynchronousConnection>(handler);
+      this.value = new AsynchronousFutureResult<Connection>(handler);
     }
 
 
@@ -674,11 +739,11 @@
 
 
 
-    AsynchronousConnection getWaitingConnection()
+    Connection getWaitingConnection()
     {
-      if (value instanceof AsynchronousConnection)
+      if (value instanceof Connection)
       {
-        return (AsynchronousConnection) value;
+        return (Connection) value;
       }
       else
       {
@@ -689,11 +754,11 @@
 
 
     @SuppressWarnings("unchecked")
-    AsynchronousFutureResult<AsynchronousConnection> getWaitingFuture()
+    AsynchronousFutureResult<Connection> getWaitingFuture()
     {
       if (value instanceof AsynchronousFutureResult)
       {
-        return (AsynchronousFutureResult<AsynchronousConnection>) value;
+        return (AsynchronousFutureResult<Connection>) value;
       }
       else
       {
@@ -723,8 +788,7 @@
 
   private final Semaphore currentPoolSize;
 
-  private final ResultHandler<AsynchronousConnection> connectionResultHandler =
-    new ConnectionResultHandler();
+  private final ResultHandler<Connection> connectionResultHandler = new ConnectionResultHandler();
 
 
 
@@ -752,7 +816,7 @@
   @Override
   public void close()
   {
-    final LinkedList<AsynchronousConnection> idleConnections;
+    final LinkedList<Connection> idleConnections;
     synchronized (queue)
     {
       if (isClosed)
@@ -763,7 +827,7 @@
 
       // Remove any connections which are waiting in the queue as these can be
       // closed immediately.
-      idleConnections = new LinkedList<AsynchronousConnection>();
+      idleConnections = new LinkedList<Connection>();
       while (!queue.isEmpty() && !queue.getFirst().isWaitingFuture())
       {
         final QueueElement holder = queue.removeFirst();
@@ -779,7 +843,7 @@
     }
 
     // Close the idle connections.
-    for (final AsynchronousConnection connection : idleConnections)
+    for (final Connection connection : idleConnections)
     {
       closeConnection(connection);
     }
@@ -791,8 +855,20 @@
    * {@inheritDoc}
    */
   @Override
-  public FutureResult<AsynchronousConnection> getAsynchronousConnection(
-      final ResultHandler<? super AsynchronousConnection> handler)
+  public Connection getConnection() throws ErrorResultException,
+      InterruptedException
+  {
+    return getConnectionAsync(null).get();
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public FutureResult<Connection> getConnectionAsync(
+      final ResultHandler<? super Connection> handler)
   {
     QueueElement holder;
     synchronized (queue)
@@ -816,22 +892,21 @@
     if (!holder.isWaitingFuture())
     {
       // There was a completed connection attempt.
-      final AsynchronousConnection connection = holder.getWaitingConnection();
+      final Connection connection = holder.getWaitingConnection();
       final PooledConnection pooledConnection = new PooledConnection(connection);
       if (handler != null)
       {
         handler.handleResult(pooledConnection);
       }
-      return new CompletedFutureResult<AsynchronousConnection>(pooledConnection);
+      return new CompletedFutureResult<Connection>(pooledConnection);
     }
     else
     {
       // Grow the pool if needed.
-      final FutureResult<AsynchronousConnection> future = holder
-          .getWaitingFuture();
+      final FutureResult<Connection> future = holder.getWaitingFuture();
       if (!future.isDone() && currentPoolSize.tryAcquire())
       {
-        factory.getAsynchronousConnection(connectionResultHandler);
+        factory.getConnectionAsync(connectionResultHandler);
       }
       return future;
     }
@@ -869,7 +944,7 @@
 
 
 
-  private void closeConnection(final AsynchronousConnection connection)
+  private void closeConnection(final Connection connection)
   {
     // The connection will be closed, so decrease the pool size.
     currentPoolSize.release();
@@ -886,7 +961,7 @@
 
 
 
-  private void publishConnection(final AsynchronousConnection connection)
+  private void publishConnection(final Connection connection)
   {
     final QueueElement holder;
     boolean connectionPoolIsClosing = false;
@@ -941,4 +1016,5 @@
       holder.getWaitingFuture().handleResult(pooledConnection);
     }
   }
+
 }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java
index 02bc5f2..e95795c 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
@@ -42,7 +43,10 @@
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
 import org.forgerock.opendj.ldap.responses.SearchResultReference;
 
-import com.forgerock.opendj.util.*;
+import com.forgerock.opendj.util.ConnectionDecorator;
+import com.forgerock.opendj.util.FutureResultTransformer;
+import com.forgerock.opendj.util.StaticUtils;
+import com.forgerock.opendj.util.Validator;
 
 
 
@@ -50,15 +54,13 @@
  * An heart beat connection factory can be used to create connections that sends
  * a periodic search request to a Directory Server.
  */
-final class HeartBeatConnectionFactory extends AbstractConnectionFactory
+final class HeartBeatConnectionFactory implements ConnectionFactory
 {
   /**
-   * An asynchronous connection that sends heart beats and supports all
-   * operations.
+   * A connection that sends heart beats and supports all operations.
    */
-  private final class AsynchronousConnectionImpl extends
-      AsynchronousConnectionDecorator implements ConnectionEventListener,
-      SearchResultHandler
+  private final class ConnectionImpl extends ConnectionDecorator implements
+      ConnectionEventListener, SearchResultHandler
   {
     private long lastSuccessfulPing;
 
@@ -66,7 +68,7 @@
 
 
 
-    private AsynchronousConnectionImpl(final AsynchronousConnection connection)
+    private ConnectionImpl(final Connection connection)
     {
       super(connection);
     }
@@ -192,12 +194,11 @@
 
 
   private final class FutureResultImpl extends
-      FutureResultTransformer<AsynchronousConnection, AsynchronousConnection>
-      implements ResultHandler<AsynchronousConnection>
+      FutureResultTransformer<Connection, Connection> implements
+      ResultHandler<Connection>
   {
 
-    private FutureResultImpl(
-        final ResultHandler<? super AsynchronousConnection> handler)
+    private FutureResultImpl(final ResultHandler<? super Connection> handler)
     {
       super(handler);
     }
@@ -208,23 +209,10 @@
      * {@inheritDoc}
      */
     @Override
-    protected AsynchronousConnection transformResult(
-        final AsynchronousConnection connection) throws ErrorResultException
+    protected Connection transformResult(final Connection connection)
+        throws ErrorResultException
     {
-      final AsynchronousConnectionImpl heartBeatConnection = new AsynchronousConnectionImpl(
-          connection);
-      synchronized (activeConnections)
-      {
-        connection.addConnectionEventListener(heartBeatConnection);
-        if (activeConnections.isEmpty())
-        {
-          // This is the first active connection, so start the heart beat.
-          heartBeatFuture = scheduler.scheduleWithFixedDelay(
-              new HeartBeatRunnable(), 0, interval, unit);
-        }
-        activeConnections.add(heartBeatConnection);
-      }
-      return heartBeatConnection;
+      return adaptConnection(connection);
     }
 
   }
@@ -245,13 +233,13 @@
     {
       synchronized (activeConnections)
       {
-        for (final AsynchronousConnectionImpl connection : activeConnections)
+        for (final ConnectionImpl connection : activeConnections)
         {
           if (connection.lastPingFuture == null
               || connection.lastPingFuture.isDone())
           {
-            connection.lastPingFuture = connection.search(heartBeat,
-                connection, null);
+            connection.lastPingFuture = connection.searchAsync(heartBeat, null,
+                connection);
           }
         }
       }
@@ -268,7 +256,7 @@
 
   private final TimeUnit unit;
 
-  private final List<AsynchronousConnectionImpl> activeConnections;
+  private final List<ConnectionImpl> activeConnections;
 
   private final ConnectionFactory factory;
 
@@ -369,19 +357,34 @@
     this.heartBeat = heartBeat;
     this.interval = interval;
     this.unit = unit;
-    this.activeConnections = new LinkedList<AsynchronousConnectionImpl>();
+    this.activeConnections = new LinkedList<ConnectionImpl>();
     this.factory = factory;
     this.scheduler = scheduler;
   }
 
 
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
-  public FutureResult<AsynchronousConnection> getAsynchronousConnection(
-      final ResultHandler<? super AsynchronousConnection> handler)
+  public Connection getConnection() throws ErrorResultException,
+      InterruptedException
+  {
+    return adaptConnection(factory.getConnection());
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public FutureResult<Connection> getConnectionAsync(
+      final ResultHandler<? super Connection> handler)
   {
     final FutureResultImpl future = new FutureResultImpl(handler);
-    future.setFutureResult(factory.getAsynchronousConnection(future));
+    future.setFutureResult(factory.getConnectionAsync(future));
     return future;
   }
 
@@ -399,4 +402,23 @@
     builder.append(')');
     return builder.toString();
   }
+
+
+
+  private Connection adaptConnection(final Connection connection)
+  {
+    final ConnectionImpl heartBeatConnection = new ConnectionImpl(connection);
+    synchronized (activeConnections)
+    {
+      connection.addConnectionEventListener(heartBeatConnection);
+      if (activeConnections.isEmpty())
+      {
+        // This is the first active connection, so start the heart beat.
+        heartBeatFuture = scheduler.scheduleWithFixedDelay(
+            new HeartBeatRunnable(), 0, interval, unit);
+      }
+      activeConnections.add(heartBeatConnection);
+    }
+    return heartBeatConnection;
+  }
 }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/IntermediateResponseHandler.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/IntermediateResponseHandler.java
index ba91cb1..1049d46 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/IntermediateResponseHandler.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/IntermediateResponseHandler.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
@@ -38,12 +39,16 @@
  * extended operations, or other operations for which an appropriate control was
  * sent.
  * <p>
- * {@link Connection} objects support intermediate responses for extended
- * operations only via the {@link Connection#extendedRequest}
- * method. {@link AsynchronousConnection} objects support intermediate responses
- * for extended operations, and all other operation types for which appropriate
- * controls were used. When no handler is provided any intermediate responses
- * will be discarded.
+ * Intermediate responses are rarely used in practice and are therefore only
+ * supported in a few specialized cases where they are most likely to be
+ * encountered:
+ * <ul>
+ * <li>when performing extended requests using the
+ * {@link Connection#extendedRequest} methods
+ * <li>when using the asynchronous operation methods, such as
+ * {@link Connection#addAsync}
+ * </ul>
+ * When no handler is provided any intermediate responses will be discarded.
  * <p>
  * The {@link #handleIntermediateResponse} method is invoked each time a
  * Intermediate Response is returned from the Directory Server.
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/InternalConnectionFactory.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/InternalConnectionFactory.java
index bacf838..f0f4374 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/InternalConnectionFactory.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/InternalConnectionFactory.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
@@ -30,7 +31,6 @@
 
 
 import com.forgerock.opendj.ldap.InternalConnection;
-import com.forgerock.opendj.util.AbstractConnectionFactory;
 import com.forgerock.opendj.util.CompletedFutureResult;
 
 
@@ -54,7 +54,7 @@
  * @param <C>
  *          The type of client context.
  */
-final class InternalConnectionFactory<C> extends AbstractConnectionFactory
+final class InternalConnectionFactory<C> implements ConnectionFactory
 {
 
   private final ServerConnectionFactory<C, Integer> factory;
@@ -72,9 +72,24 @@
 
 
 
-  @Override
-  public FutureResult<AsynchronousConnection> getAsynchronousConnection(
-      final ResultHandler<? super AsynchronousConnection> handler)
+  /**
+   * {@inheritDoc}
+   */
+  public Connection getConnection() throws ErrorResultException,
+      InterruptedException
+  {
+    final ServerConnection<Integer> serverConnection = factory
+        .handleAccept(clientContext);
+    return new InternalConnection(serverConnection);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public FutureResult<Connection> getConnectionAsync(
+      final ResultHandler<? super Connection> handler)
   {
     final ServerConnection<Integer> serverConnection;
     try
@@ -87,7 +102,7 @@
       {
         handler.handleErrorResult(e);
       }
-      return new CompletedFutureResult<AsynchronousConnection>(e);
+      return new CompletedFutureResult<Connection>(e);
     }
 
     final InternalConnection connection = new InternalConnection(
@@ -96,7 +111,7 @@
     {
       handler.handleResult(connection);
     }
-    return new CompletedFutureResult<AsynchronousConnection>(connection);
+    return new CompletedFutureResult<Connection>(connection);
   }
 
 
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java
index ee13b7e..378a152 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LDAPConnectionFactory.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
@@ -44,9 +45,8 @@
  */
 public final class LDAPConnectionFactory implements ConnectionFactory
 {
-  // We implement the factory using the pimpl idiom in order have
-  // cleaner Javadoc which does not expose implementation methods from
-  // AbstractConnectionFactory.
+  // We implement the factory using the pimpl idiom in order to avoid making too
+  // many implementation classes public.
 
   private final LDAPConnectionFactoryImpl impl;
 
@@ -157,10 +157,10 @@
    * {@inheritDoc}
    */
   @Override
-  public FutureResult<AsynchronousConnection> getAsynchronousConnection(
-      final ResultHandler<? super AsynchronousConnection> handler)
+  public FutureResult<Connection> getConnectionAsync(
+      final ResultHandler<? super Connection> handler)
   {
-    return impl.getAsynchronousConnection(handler);
+    return impl.getConnectionAsync(handler);
   }
 
 
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LoadBalancer.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LoadBalancer.java
index d9e6626..3fb7352 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LoadBalancer.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LoadBalancer.java
@@ -23,13 +23,13 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
 
 
 
-import com.forgerock.opendj.util.AbstractConnectionFactory;
 import com.forgerock.opendj.util.CompletedFutureResult;
 import com.forgerock.opendj.util.Validator;
 
@@ -39,7 +39,7 @@
  * A load balancing connection factory allocates connections using the provided
  * algorithm.
  */
-final class LoadBalancer extends AbstractConnectionFactory
+final class LoadBalancer implements ConnectionFactory
 {
   private final LoadBalancingAlgorithm algorithm;
 
@@ -63,9 +63,20 @@
   /**
    * {@inheritDoc}
    */
+  public Connection getConnection() throws ErrorResultException,
+      InterruptedException
+  {
+    return algorithm.getConnectionFactory().getConnection();
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
   @Override
-  public FutureResult<AsynchronousConnection> getAsynchronousConnection(
-      final ResultHandler<? super AsynchronousConnection> resultHandler)
+  public FutureResult<Connection> getConnectionAsync(
+      final ResultHandler<? super Connection> resultHandler)
   {
     final ConnectionFactory factory;
 
@@ -79,10 +90,10 @@
       {
         resultHandler.handleErrorResult(e);
       }
-      return new CompletedFutureResult<AsynchronousConnection>(e);
+      return new CompletedFutureResult<Connection>(e);
     }
 
-    return factory.getAsynchronousConnection(resultHandler);
+    return factory.getConnectionAsync(resultHandler);
   }
 
 
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandler.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandler.java
index 1d98481..1f2802e 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandler.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandler.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
@@ -64,18 +65,18 @@
    *          The request context.
    * @param request
    *          The add request.
-   * @param resultHandler
-   *          The handler which should be used to send back the result to the
-   *          client.
    * @param intermediateResponseHandler
    *          The handler which should be used to send back any intermediate
    *          responses to the client.
+   * @param resultHandler
+   *          The handler which should be used to send back the result to the
+   *          client.
    * @throws UnsupportedOperationException
    *           If this request handler does not handle add requests.
    */
   void handleAdd(C requestContext, AddRequest request,
-      ResultHandler<? super Result> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super Result> resultHandler)
       throws UnsupportedOperationException;
 
 
@@ -89,18 +90,18 @@
    *          The protocol version included with the bind request.
    * @param request
    *          The bind request.
-   * @param resultHandler
-   *          The handler which should be used to send back the result to the
-   *          client.
    * @param intermediateResponseHandler
    *          The handler which should be used to send back any intermediate
    *          responses to the client.
+   * @param resultHandler
+   *          The handler which should be used to send back the result to the
+   *          client.
    * @throws UnsupportedOperationException
    *           If this request handler does not handle bind requests.
    */
   void handleBind(C requestContext, int version, BindRequest request,
-      ResultHandler<? super BindResult> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super BindResult> resultHandler)
       throws UnsupportedOperationException;
 
 
@@ -112,18 +113,18 @@
    *          The request context.
    * @param request
    *          The compare request.
-   * @param resultHandler
-   *          The handler which should be used to send back the result to the
-   *          client.
    * @param intermediateResponseHandler
    *          The handler which should be used to send back any intermediate
    *          responses to the client.
+   * @param resultHandler
+   *          The handler which should be used to send back the result to the
+   *          client.
    * @throws UnsupportedOperationException
    *           If this request handler does not handle compare requests.
    */
   void handleCompare(C requestContext, CompareRequest request,
-      ResultHandler<? super CompareResult> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super CompareResult> resultHandler)
       throws UnsupportedOperationException;
 
 
@@ -135,18 +136,18 @@
    *          The request context.
    * @param request
    *          The delete request.
-   * @param resultHandler
-   *          The handler which should be used to send back the result to the
-   *          client.
    * @param intermediateResponseHandler
    *          The handler which should be used to send back any intermediate
    *          responses to the client.
+   * @param resultHandler
+   *          The handler which should be used to send back the result to the
+   *          client.
    * @throws UnsupportedOperationException
    *           If this request handler does not handle delete requests.
    */
   void handleDelete(C requestContext, DeleteRequest request,
-      ResultHandler<? super Result> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super Result> resultHandler)
       throws UnsupportedOperationException;
 
 
@@ -160,18 +161,19 @@
    *          The request context.
    * @param request
    *          The extended request.
-   * @param resultHandler
-   *          The handler which should be used to send back the result to the
-   *          client.
    * @param intermediateResponseHandler
    *          The handler which should be used to send back any intermediate
    *          responses to the client.
+   * @param resultHandler
+   *          The handler which should be used to send back the result to the
+   *          client.
    * @throws UnsupportedOperationException
    *           If this request handler does not handle extended requests.
    */
   <R extends ExtendedResult> void handleExtendedRequest(C requestContext,
-      ExtendedRequest<R> request, ResultHandler<? super R> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
+      ExtendedRequest<R> request,
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super R> resultHandler)
       throws UnsupportedOperationException;
 
 
@@ -183,18 +185,18 @@
    *          The request context.
    * @param request
    *          The modify request.
-   * @param resultHandler
-   *          The handler which should be used to send back the result to the
-   *          client.
    * @param intermediateResponseHandler
    *          The handler which should be used to send back any intermediate
    *          responses to the client.
+   * @param resultHandler
+   *          The handler which should be used to send back the result to the
+   *          client.
    * @throws UnsupportedOperationException
    *           If this request handler does not handle modify requests.
    */
   void handleModify(C requestContext, ModifyRequest request,
-      ResultHandler<? super Result> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super Result> resultHandler)
       throws UnsupportedOperationException;
 
 
@@ -206,18 +208,18 @@
    *          The request context.
    * @param request
    *          The modify DN request.
-   * @param resultHandler
-   *          The handler which should be used to send back the result to the
-   *          client.
    * @param intermediateResponseHandler
    *          The handler which should be used to send back any intermediate
    *          responses to the client.
+   * @param resultHandler
+   *          The handler which should be used to send back the result to the
+   *          client.
    * @throws UnsupportedOperationException
    *           If this request handler does not handle modify DN requests.
    */
   void handleModifyDN(C requestContext, ModifyDNRequest request,
-      ResultHandler<? super Result> resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
+      IntermediateResponseHandler intermediateResponseHandler,
+      ResultHandler<? super Result> resultHandler)
       throws UnsupportedOperationException;
 
 
@@ -229,17 +231,16 @@
    *          The request context.
    * @param request
    *          The search request.
-   * @param resultHandler
-   *          The handler which should be used to send back the search results
-   *          to the client.
    * @param intermediateResponseHandler
    *          The handler which should be used to send back any intermediate
    *          responses to the client.
+   * @param resultHandler
+   *          The handler which should be used to send back the search results
+   *          to the client.
    * @throws UnsupportedOperationException
    *           If this request handler does not handle search requests.
    */
   void handleSearch(C requestContext, SearchRequest request,
-      SearchResultHandler resultHandler,
-      IntermediateResponseHandler intermediateResponseHandler)
-      throws UnsupportedOperationException;
+      IntermediateResponseHandler intermediateResponseHandler,
+      SearchResultHandler resultHandler) throws UnsupportedOperationException;
 }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactoryAdapter.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactoryAdapter.java
index 4f5476d..a097fcf 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactoryAdapter.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactoryAdapter.java
@@ -72,8 +72,7 @@
 
 
 
-      private ExtendedResultHandlerHolder(
-          final ExtendedRequest<R> request,
+      private ExtendedResultHandlerHolder(final ExtendedRequest<R> request,
           final ResultHandler<? super R> resultHandler)
       {
         this.request = request;
@@ -148,9 +147,8 @@
 
 
     protected RequestContextImpl(
-        final ServerConnectionImpl<?> clientConnection,
-        final H resultHandler, final int messageID,
-        final boolean isCancelSupported)
+        final ServerConnectionImpl<?> clientConnection, final H resultHandler,
+        final int messageID, final boolean isCancelSupported)
     {
       this.clientConnection = clientConnection;
       this.resultHandler = resultHandler;
@@ -164,8 +162,7 @@
      * {@inheritDoc}
      */
     @Override
-    public void addCancelRequestListener(
-        final CancelRequestListener listener)
+    public void addCancelRequestListener(final CancelRequestListener listener)
         throws NullPointerException
     {
       Validator.ensureNotNull(listener);
@@ -224,8 +221,8 @@
           break;
         case CANCEL_REQUESTED:
           // Don't change state: let the handler ack the cancellation request.
-          throw (CancelledResultException) newErrorResult(
-              ResultCode.CANCELLED, cancelRequestReason.toString());
+          throw (CancelledResultException) newErrorResult(ResultCode.CANCELLED,
+              cancelRequestReason.toString());
         case TOO_LATE:
           // Already too late. Nothing to do.
           break;
@@ -294,8 +291,7 @@
      * {@inheritDoc}
      */
     @Override
-    public void removeCancelRequestListener(
-        final CancelRequestListener listener)
+    public void removeCancelRequestListener(final CancelRequestListener listener)
         throws NullPointerException
     {
       Validator.ensureNotNull(listener);
@@ -325,8 +321,7 @@
         {
           final Result result = Responses
               .newGenericExtendedResult(ResultCode.CANNOT_CANCEL);
-          cancelResultHandler
-              .handleErrorResult(newErrorResult(result));
+          cancelResultHandler.handleErrorResult(newErrorResult(result));
         }
         return;
       }
@@ -345,9 +340,8 @@
           if (cancelResultHandler != null)
           {
             cancelResultHandlers = new LinkedList<ExtendedResultHandlerHolder<?>>();
-            cancelResultHandlers
-                .add(new ExtendedResultHandlerHolder<R>(
-                    cancelRequest, cancelResultHandler));
+            cancelResultHandlers.add(new ExtendedResultHandlerHolder<R>(
+                cancelRequest, cancelResultHandler));
           }
           tmpListeners = cancelRequestListeners;
           cancelRequestListeners = null;
@@ -362,9 +356,8 @@
             {
               cancelResultHandlers = new LinkedList<ExtendedResultHandlerHolder<?>>();
             }
-            cancelResultHandlers
-                .add(new ExtendedResultHandlerHolder<R>(
-                    cancelRequest, cancelResultHandler));
+            cancelResultHandlers.add(new ExtendedResultHandlerHolder<R>(
+                cancelRequest, cancelResultHandler));
           }
           break;
         case TOO_LATE:
@@ -509,8 +502,7 @@
         final SearchResultHandler resultHandler, final int messageID,
         final boolean isCancelSupported)
     {
-      super(clientConnection, resultHandler, messageID,
-          isCancelSupported);
+      super(clientConnection, resultHandler, messageID, isCancelSupported);
     }
 
 
@@ -530,8 +522,7 @@
      * {@inheritDoc}
      */
     @Override
-    public boolean handleReference(
-        final SearchResultReference reference)
+    public boolean handleReference(final SearchResultReference reference)
     {
       return resultHandler.handleReference(reference);
     }
@@ -543,11 +534,9 @@
       ServerConnection<Integer>
   {
     private final RequestHandler<RequestContext> requestHandler;
-
     private final AtomicBoolean isClosed = new AtomicBoolean();
-
     private final ConcurrentHashMap<Integer, RequestContextImpl<?, ?>> pendingRequests =
-      new ConcurrentHashMap<Integer, RequestContextImpl<?, ?>>();
+        new ConcurrentHashMap<Integer, RequestContextImpl<?, ?>>();
 
 
 
@@ -564,8 +553,7 @@
      */
     @Override
     public void handleAbandon(final Integer messageID,
-        final AbandonRequest request)
-        throws UnsupportedOperationException
+        final AbandonRequest request) throws UnsupportedOperationException
     {
       final RequestContextImpl<?, ?> abandonedRequest = getPendingRequest(request
           .getRequestID());
@@ -583,19 +571,18 @@
      * {@inheritDoc}
      */
     @Override
-    public void handleAdd(final Integer messageID,
-        final AddRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+    public void handleAdd(final Integer messageID, final AddRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       final RequestContextImpl<Result, ResultHandler<? super Result>> requestContext =
-        new RequestContextImpl<Result, ResultHandler<? super Result>>(
+          new RequestContextImpl<Result, ResultHandler<? super Result>>(
           this, resultHandler, messageID, true);
       if (addPendingRequest(requestContext))
       {
         requestHandler.handleAdd(requestContext, request,
-            requestContext, intermediateResponseHandler);
+            intermediateResponseHandler, requestContext);
       }
     }
 
@@ -605,19 +592,19 @@
      * {@inheritDoc}
      */
     @Override
-    public void handleBind(final Integer messageID,
-        final int version, final BindRequest request,
-        final ResultHandler<? super BindResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+    public void handleBind(final Integer messageID, final int version,
+        final BindRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super BindResult> resultHandler)
         throws UnsupportedOperationException
     {
       final RequestContextImpl<BindResult, ResultHandler<? super BindResult>> requestContext =
-        new RequestContextImpl<BindResult, ResultHandler<? super BindResult>>(
+          new RequestContextImpl<BindResult, ResultHandler<? super BindResult>>(
           this, resultHandler, messageID, false);
       if (addPendingRequest(requestContext))
       {
         requestHandler.handleBind(requestContext, version, request,
-            requestContext, intermediateResponseHandler);
+            intermediateResponseHandler, requestContext);
       }
     }
 
@@ -629,17 +616,17 @@
     @Override
     public void handleCompare(final Integer messageID,
         final CompareRequest request,
-        final ResultHandler<? super CompareResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super CompareResult> resultHandler)
         throws UnsupportedOperationException
     {
       final RequestContextImpl<CompareResult, ResultHandler<? super CompareResult>> requestContext =
-        new RequestContextImpl<CompareResult, ResultHandler<? super CompareResult>>(
+          new RequestContextImpl<CompareResult, ResultHandler<? super CompareResult>>(
           this, resultHandler, messageID, true);
       if (addPendingRequest(requestContext))
       {
         requestHandler.handleCompare(requestContext, request,
-            requestContext, intermediateResponseHandler);
+            intermediateResponseHandler, requestContext);
       }
     }
 
@@ -663,8 +650,8 @@
      * {@inheritDoc}
      */
     @Override
-    public void handleConnectionDisconnected(
-        final ResultCode resultCode, final String message)
+    public void handleConnectionDisconnected(final ResultCode resultCode,
+        final String message)
     {
       final LocalizableMessage cancelReason = INFO_CANCELED_BY_SERVER_DISCONNECT
           .get();
@@ -692,17 +679,17 @@
     @Override
     public void handleDelete(final Integer messageID,
         final DeleteRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       final RequestContextImpl<Result, ResultHandler<? super Result>> requestContext =
-        new RequestContextImpl<Result, ResultHandler<? super Result>>(
+          new RequestContextImpl<Result, ResultHandler<? super Result>>(
           this, resultHandler, messageID, true);
       if (addPendingRequest(requestContext))
       {
         requestHandler.handleDelete(requestContext, request,
-            requestContext, intermediateResponseHandler);
+            intermediateResponseHandler, requestContext);
       }
     }
 
@@ -714,8 +701,8 @@
     @Override
     public <R extends ExtendedResult> void handleExtendedRequest(
         final Integer messageID, final ExtendedRequest<R> request,
-        final ResultHandler<? super R> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super R> resultHandler)
         throws UnsupportedOperationException
     {
       if (request.getOID().equals(CancelExtendedRequest.OID))
@@ -724,8 +711,8 @@
         CancelExtendedRequest cancelRequest;
         try
         {
-          cancelRequest = CancelExtendedRequest.DECODER
-              .decodeExtendedRequest(request, new DecodeOptions());
+          cancelRequest = CancelExtendedRequest.DECODER.decodeExtendedRequest(
+              request, new DecodeOptions());
         }
         catch (final DecodeException e)
         {
@@ -739,7 +726,7 @@
         // this request cannot be cancelled, it is important to do this in
         // order to monitor the number of pending operations.
         final RequestContextImpl<R, ResultHandler<? super R>> requestContext =
-          new RequestContextImpl<R, ResultHandler<? super R>>(
+            new RequestContextImpl<R, ResultHandler<? super R>>(
             this, resultHandler, messageID, false);
         if (addPendingRequest(requestContext))
         {
@@ -750,8 +737,8 @@
           {
             final LocalizableMessage cancelReason = INFO_CANCELED_BY_CANCEL_REQUEST
                 .get(messageID);
-            cancelledRequest.cancel(cancelReason, request,
-                requestContext, true);
+            cancelledRequest
+                .cancel(cancelReason, request, requestContext, true);
           }
           else
           {
@@ -779,8 +766,8 @@
 
         if (addPendingRequest(requestContext))
         {
-          requestHandler.handleExtendedRequest(requestContext,
-              request, requestContext, intermediateResponseHandler);
+          requestHandler.handleExtendedRequest(requestContext, request,
+              intermediateResponseHandler, requestContext);
         }
       }
     }
@@ -793,17 +780,17 @@
     @Override
     public void handleModify(final Integer messageID,
         final ModifyRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       final RequestContextImpl<Result, ResultHandler<? super Result>> requestContext =
-        new RequestContextImpl<Result, ResultHandler<? super Result>>(
+          new RequestContextImpl<Result, ResultHandler<? super Result>>(
           this, resultHandler, messageID, true);
       if (addPendingRequest(requestContext))
       {
         requestHandler.handleModify(requestContext, request,
-            requestContext, intermediateResponseHandler);
+            intermediateResponseHandler, requestContext);
       }
     }
 
@@ -815,17 +802,17 @@
     @Override
     public void handleModifyDN(final Integer messageID,
         final ModifyDNRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       final RequestContextImpl<Result, ResultHandler<? super Result>> requestContext =
-        new RequestContextImpl<Result, ResultHandler<? super Result>>(
+          new RequestContextImpl<Result, ResultHandler<? super Result>>(
           this, resultHandler, messageID, true);
       if (addPendingRequest(requestContext))
       {
         requestHandler.handleModifyDN(requestContext, request,
-            requestContext, intermediateResponseHandler);
+            intermediateResponseHandler, requestContext);
       }
     }
 
@@ -837,8 +824,8 @@
     @Override
     public void handleSearch(final Integer messageID,
         final SearchRequest request,
-        final SearchResultHandler resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final SearchResultHandler resultHandler)
         throws UnsupportedOperationException
     {
       final SearchRequestContextImpl requestContext = new SearchRequestContextImpl(
@@ -846,7 +833,7 @@
       if (addPendingRequest(requestContext))
       {
         requestHandler.handleSearch(requestContext, request,
-            requestContext, intermediateResponseHandler);
+            intermediateResponseHandler, requestContext);
       }
     }
 
@@ -859,8 +846,7 @@
 
       if (isClosed.get())
       {
-        final LocalizableMessage message = INFO_CLIENT_CONNECTION_CLOSING
-            .get();
+        final LocalizableMessage message = INFO_CLIENT_CONNECTION_CLOSING.get();
         requestContext.handleErrorResult(newErrorResult(
             ResultCode.UNWILLING_TO_PERFORM, message.toString()));
         return false;
@@ -879,8 +865,7 @@
         // it will have only been notified for cancellation.
         pendingRequests.remove(messageID);
 
-        final LocalizableMessage message = INFO_CLIENT_CONNECTION_CLOSING
-            .get();
+        final LocalizableMessage message = INFO_CLIENT_CONNECTION_CLOSING.get();
         requestContext.handleErrorResult(newErrorResult(
             ResultCode.UNWILLING_TO_PERFORM, message.toString()));
         return false;
@@ -906,8 +891,7 @@
             .values().iterator();
         while (iterator.hasNext())
         {
-          final RequestContextImpl<?, ?> pendingRequest = iterator
-              .next();
+          final RequestContextImpl<?, ?> pendingRequest = iterator.next();
           pendingRequest.cancel(cancelReason, null, null, false);
           iterator.remove();
         }
@@ -923,8 +907,7 @@
      *          The message ID associated with the request context.
      * @return The pending request context.
      */
-    private RequestContextImpl<?, ?> getPendingRequest(
-        final Integer messageID)
+    private RequestContextImpl<?, ?> getPendingRequest(final Integer messageID)
     {
       return pendingRequests.get(messageID);
     }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ResultHandler.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ResultHandler.java
index 48a0591..8688336 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ResultHandler.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ResultHandler.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2009 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
@@ -34,7 +35,7 @@
  * connection attempts.
  * <p>
  * A result completion handler may be specified when performing asynchronous
- * operations using an {@link AsynchronousConnection} object or when connecting
+ * operations using a {@link Connection} object or when connecting
  * asynchronously to a remote Directory Server using an
  * {@link ConnectionFactory}. The {@link #handleResult} method is invoked when
  * the operation or connection attempt completes successfully. The
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RootDSE.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RootDSE.java
index c153fbe..067d9d2 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RootDSE.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RootDSE.java
@@ -135,7 +135,8 @@
 
 
   /**
-   * Reads the Root DSE from the Directory Server using the provided connection.
+   * Asynchronously reads the Root DSE from the Directory Server using the
+   * provided connection.
    * <p>
    * If the Root DSE is not returned by the Directory Server then the request
    * will fail with an {@link EntryNotFoundException}. More specifically, the
@@ -150,14 +151,13 @@
    * @throws UnsupportedOperationException
    *           If the connection does not support search operations.
    * @throws IllegalStateException
-   *           If the connection has already been closed, i.e. if {@code
-   *           isClosed() == true}.
+   *           If the connection has already been closed, i.e. if
+   *           {@code isClosed() == true}.
    * @throws NullPointerException
    *           If the {@code connection} was {@code null}.
    */
-  public static FutureResult<RootDSE> readRootDSE(
-      final AsynchronousConnection connection,
-      final ResultHandler<? super RootDSE> handler)
+  public static FutureResult<RootDSE> readRootDSEAsync(
+      final Connection connection, final ResultHandler<? super RootDSE> handler)
       throws UnsupportedOperationException, IllegalStateException,
       NullPointerException
   {
@@ -175,7 +175,7 @@
     };
 
     final FutureResult<SearchResultEntry> innerFuture = connection
-        .searchSingleEntry(SEARCH_REQUEST, future);
+        .searchSingleEntryAsync(SEARCH_REQUEST, future);
     future.setFutureResult(innerFuture);
     return future;
   }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/SearchResultHandler.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/SearchResultHandler.java
index 0679c1f..4a7b2da 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/SearchResultHandler.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/SearchResultHandler.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
@@ -38,7 +39,7 @@
 /**
  * A completion handler for consuming the results of a Search operation.
  * <p>
- * {@link Connection} and {@link AsynchronousConnection} objects allow a search
+ * {@link Connection} and {@link Connection} objects allow a search
  * result completion handler to be specified when sending Search operation
  * requests to a Directory Server. The {@link #handleEntry} method is invoked
  * each time a Search Result Entry is returned from the Directory Server. The
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
index 143114e..fc65ffe 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
@@ -1718,7 +1718,7 @@
 
 
   /**
-   * Reads the schema contained in the named subschema sub-entry.
+   * Asynchronously reads the schema contained in the named subschema sub-entry.
    * <p>
    * If the requested schema is not returned by the Directory Server then the
    * request will fail with an {@link EntryNotFoundException}. More
@@ -1740,8 +1740,8 @@
    * @throws NullPointerException
    *           If the {@code connection} or {@code name} was {@code null}.
    */
-  public static FutureResult<Schema> readSchema(
-      final AsynchronousConnection connection, final DN name,
+  public static FutureResult<Schema> readSchemaAsync(
+      final Connection connection, final DN name,
       final ResultHandler<? super Schema> handler)
       throws UnsupportedOperationException, IllegalStateException,
       NullPointerException
@@ -1760,7 +1760,7 @@
     };
 
     final SchemaBuilder builder = new SchemaBuilder();
-    final FutureResult<SchemaBuilder> innerFuture = builder.addSchema(
+    final FutureResult<SchemaBuilder> innerFuture = builder.addSchemaAsync(
         connection, name, future, true);
     future.setFutureResult(innerFuture);
     return future;
@@ -1804,8 +1804,8 @@
 
 
   /**
-   * Reads the schema contained in the subschema sub-entry which applies to the
-   * named entry.
+   * Asynchronously reads the schema contained in the subschema sub-entry which
+   * applies to the named entry.
    * <p>
    * If the requested entry or its associated schema are not returned by the
    * Directory Server then the request will fail with an
@@ -1814,7 +1814,7 @@
    * <p>
    * This implementation first reads the {@code subschemaSubentry} attribute of
    * the entry in order to identify the schema and then invokes
-   * {@link #readSchema(AsynchronousConnection, DN, ResultHandler)} to read the
+   * {@link #readSchemaAsync(Connection, DN, ResultHandler)} to read the
    * schema.
    *
    * @param connection
@@ -1833,8 +1833,8 @@
    * @throws NullPointerException
    *           If the {@code connection} or {@code name} was {@code null}.
    */
-  public static FutureResult<Schema> readSchemaForEntry(
-      final AsynchronousConnection connection, final DN name,
+  public static FutureResult<Schema> readSchemaForEntryAsync(
+      final Connection connection, final DN name,
       final ResultHandler<? super Schema> handler)
       throws UnsupportedOperationException, IllegalStateException,
       NullPointerException
@@ -1853,8 +1853,8 @@
     };
 
     final SchemaBuilder builder = new SchemaBuilder();
-    final FutureResult<SchemaBuilder> innerFuture = builder.addSchemaForEntry(
-        connection, name, future, true);
+    final FutureResult<SchemaBuilder> innerFuture = builder
+        .addSchemaForEntryAsync(connection, name, future, true);
     future.setFutureResult(innerFuture);
     return future;
 
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
index 836e7b4..8b9469f 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
@@ -2013,8 +2013,8 @@
 
 
   /**
-   * Reads the schema elements contained in the named subschema sub-entry and
-   * adds them to this schema builder.
+   * Asynchronously reads the schema elements contained in the named subschema
+   * sub-entry and adds them to this schema builder.
    * <p>
    * If the requested schema is not returned by the Directory Server then the
    * request will fail with an {@link EntryNotFoundException}.
@@ -2038,8 +2038,8 @@
    * @throws NullPointerException
    *           If the {@code connection} or {@code name} was {@code null}.
    */
-  public FutureResult<SchemaBuilder> addSchema(
-      final AsynchronousConnection connection, final DN name,
+  public FutureResult<SchemaBuilder> addSchemaAsync(
+      final Connection connection, final DN name,
       final ResultHandler<? super SchemaBuilder> handler,
       final boolean overwrite) throws UnsupportedOperationException,
       IllegalStateException, NullPointerException
@@ -2062,7 +2062,7 @@
     };
 
     final FutureResult<SearchResultEntry> innerFuture = connection
-        .searchSingleEntry(request, future);
+        .searchSingleEntryAsync(request, future);
     future.setFutureResult(innerFuture);
     return future;
   }
@@ -2295,8 +2295,9 @@
 
 
   /**
-   * Reads the schema elements contained in the subschema sub-entry which
-   * applies to the named entry and adds them to this schema builder.
+   * Asynchronously reads the schema elements contained in the subschema
+   * sub-entry which applies to the named entry and adds them to this schema
+   * builder.
    * <p>
    * If the requested entry or its associated schema are not returned by the
    * Directory Server then the request will fail with an
@@ -2304,7 +2305,7 @@
    * <p>
    * This implementation first reads the {@code subschemaSubentry} attribute of
    * the entry in order to identify the schema and then invokes
-   * {@link #addSchema(AsynchronousConnection, DN, ResultHandler, boolean)} to
+   * {@link #addSchemaAsync(Connection, DN, ResultHandler, boolean)} to
    * read the schema.
    *
    * @param connection
@@ -2326,8 +2327,8 @@
    * @throws NullPointerException
    *           If the {@code connection} or {@code name} was {@code null}.
    */
-  public FutureResult<SchemaBuilder> addSchemaForEntry(
-      final AsynchronousConnection connection, final DN name,
+  public FutureResult<SchemaBuilder> addSchemaForEntryAsync(
+      final Connection connection, final DN name,
       final ResultHandler<? super SchemaBuilder> handler,
       final boolean overwrite) throws UnsupportedOperationException,
       IllegalStateException, NullPointerException
@@ -2344,14 +2345,14 @@
           throws ErrorResultException
       {
         final DN subschemaDN = getSubschemaSubentryDN(name, innerResult);
-        return addSchema(connection, subschemaDN, handler, overwrite);
+        return addSchemaAsync(connection, subschemaDN, handler, overwrite);
       }
 
     };
 
     final SearchRequest request = getReadSchemaForEntrySearchRequest(name);
     final FutureResult<SearchResultEntry> innerFuture = connection
-        .searchSingleEntry(request, future);
+        .searchSingleEntryAsync(request, future);
     future.setFutureResult(innerFuture);
     return future;
   }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java
index b1029ab..053da05 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldif;
@@ -46,10 +47,10 @@
 
 
 /**
- * A {@code ConnectionEntryReader} is a bridge from
- * {@code AsynchronousConnection}s to {@code EntryReader}s. A connection entry
- * reader allows applications to iterate over search results as they are
- * returned from the server during a search operation.
+ * A {@code ConnectionEntryReader} is a bridge from {@code Connection}s to
+ * {@code EntryReader}s. A connection entry reader allows applications to
+ * iterate over search results as they are returned from the server during a
+ * search operation.
  * <p>
  * The Search operation is performed synchronously, blocking until a search
  * result entry is received. If a search result indicates that the search
@@ -207,7 +208,7 @@
    * @throws NullPointerException
    *           If {@code connection} was {@code null}.
    */
-  public ConnectionEntryReader(final AsynchronousConnection connection,
+  public ConnectionEntryReader(final Connection connection,
       final SearchRequest searchRequest) throws NullPointerException
   {
     this(connection, searchRequest, new LinkedBlockingQueue<Response>());
@@ -229,13 +230,13 @@
    * @throws NullPointerException
    *           If {@code connection} was {@code null}.
    */
-  public ConnectionEntryReader(final AsynchronousConnection connection,
+  public ConnectionEntryReader(final Connection connection,
       final SearchRequest searchRequest, final BlockingQueue<Response> entries)
       throws NullPointerException
   {
     Validator.ensureNotNull(connection);
     buffer = new BufferHandler(entries);
-    future = connection.search(searchRequest, buffer);
+    future = connection.searchAsync(searchRequest, null, buffer);
   }
 
 
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/util/SynchronousConnectionTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/util/SynchronousConnectionTestCase.java
deleted file mode 100644
index abd502e..0000000
--- a/opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/util/SynchronousConnectionTestCase.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2010 Sun Microsystems, Inc.
- */
-
-package com.forgerock.opendj.util;
-
-
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import java.util.NoSuchElementException;
-
-import org.forgerock.opendj.ldap.*;
-import org.forgerock.opendj.ldap.requests.Requests;
-import org.forgerock.opendj.ldap.responses.BindResult;
-import org.forgerock.opendj.ldap.responses.CompareResult;
-import org.forgerock.opendj.ldap.responses.Result;
-import org.forgerock.opendj.ldap.responses.SearchResultEntry;
-import org.forgerock.opendj.ldif.ConnectionEntryReader;
-import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import com.forgerock.opendj.util.SynchronousConnection;
-
-
-
-/**
- * This class tests the Synchronous Connection API.
- */
-@SuppressWarnings("javadoc")
-public class SynchronousConnectionTestCase extends TypesTestCase
-{
-  private AsynchronousConnection asyncCon;
-
-
-
-  /**
-   * Ensures that the LDAP Server is running.
-   *
-   * @throws Exception
-   *           If an unexpected problem occurs.
-   */
-  @BeforeClass()
-  public void startServer() throws Exception
-  {
-    TestCaseUtils.startServer();
-    final ConnectionFactory factory = Connections.newInternalConnectionFactory(
-        LDAPServer.getInstance(), null);
-    asyncCon = factory.getAsynchronousConnection(null).get();
-  }
-
-
-
-  /**
-   * Ensures that the LDAP server is stopped.
-   */
-  @AfterClass()
-  public void stopServer()
-  {
-    asyncCon.close();
-    // Don't stop the server as some futures might get stuck.
-    // TestCaseUtils.stopServer();
-  }
-
-
-
-  /**
-   * Tests the ADD request.
-   *
-   * @throws Exception
-   */
-  @Test()
-  public void testAddRequest() throws Exception
-  {
-    final SynchronousConnection con = new SynchronousConnection(asyncCon);
-    final Result result = con.add(Requests.newAddRequest(DN.valueOf(""
-        + "uid=syncconnectiontestcase,ou=people,o=test")));
-    assertTrue(result.isSuccess());
-  }
-
-
-
-  /**
-   * Tests the BIND request.
-   *
-   * @throws Exception
-   */
-  @Test()
-  public void testBindRequest() throws Exception
-  {
-    final SynchronousConnection con = new SynchronousConnection(asyncCon);
-    final BindResult result = con.bind(Requests.newSimpleBindRequest());
-    assertTrue(result.isSuccess());
-  }
-
-
-
-  /**
-   * Tests the COMPARE request.
-   *
-   * @throws Exception
-   */
-  @Test()
-  public void testCompareRequest() throws Exception
-  {
-    final SynchronousConnection con = new SynchronousConnection(asyncCon);
-    final CompareResult result = con.compare("uid=user.0,ou=people,o=test",
-        "uid", "user.0");
-    assertTrue(result.matched());
-  }
-
-
-
-  /**
-   * Tests the ctor.
-   *
-   * @throws Exception
-   */
-  @Test()
-  public void testCtor() throws Exception
-  {
-    final SynchronousConnection con = new SynchronousConnection(asyncCon);
-    assertFalse(con.isClosed());
-  }
-
-
-
-  /**
-   * Tests the SEARCH request.
-   *
-   * @throws Exception
-   */
-  @Test()
-  public void testSearchRequest() throws Exception
-  {
-    final SynchronousConnection con = new SynchronousConnection(asyncCon);
-    final ConnectionEntryReader reader = con.search(
-        "uid=user.0,ou=people,o=test", SearchScope.BASE_OBJECT,
-        "objectclass=*", "cn");
-    Assert.assertTrue(reader.hasNext());
-    Assert.assertFalse(reader.isReference());
-    Assert.assertTrue(reader.hasNext());
-    SearchResultEntry entry = reader.readEntry();
-    Assert.assertEquals(entry.getName(),
-        DN.valueOf("uid=user.0,ou=people,o=test"));
-    Assert.assertFalse(reader.hasNext());
-    try
-    {
-      reader.readEntry();
-      Assert
-          .fail("reader.readEntry() should have thrown NoSuchElementException");
-    }
-    catch (NoSuchElementException e)
-    {
-      // This is expected.
-    }
-    Assert.assertFalse(reader.hasNext());
-  }
-  // TODO: add more tests.
-}
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnectionTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnectionTestCase.java
new file mode 100644
index 0000000..bfc0dbe
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnectionTestCase.java
@@ -0,0 +1,605 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opendj3/legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
+ */
+
+package org.forgerock.opendj.ldap;
+
+
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.forgerock.opendj.ldap.requests.*;
+import org.forgerock.opendj.ldap.responses.*;
+import org.testng.annotations.Test;
+
+import com.forgerock.opendj.util.CompletedFutureResult;
+
+
+
+/**
+ * Unit test for AbstractAsynchronousConnection. The tests verify that all
+ * synchronous operation methods delegate to the equivalent asynchronous method.
+ */
+@SuppressWarnings("javadoc")
+public class AbstractAsynchronousConnectionTestCase extends SdkTestCase
+{
+
+  private final class MockConnection extends AbstractAsynchronousConnection
+  {
+    private final ResultCode resultCode;
+    private final SearchResultEntry entry;
+
+
+
+    private MockConnection(ResultCode resultCode)
+    {
+      this(resultCode, null);
+    }
+
+
+
+    private MockConnection(ResultCode resultCode, SearchResultEntry entry)
+    {
+      this.resultCode = resultCode;
+      this.entry = entry;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public FutureResult<Void> abandonAsync(AbandonRequest request)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      if (!resultCode.isExceptional())
+      {
+        return new CompletedFutureResult<Void>((Void) null);
+      }
+      else
+      {
+        return new CompletedFutureResult<Void>(newErrorResult(resultCode));
+      }
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public FutureResult<Result> addAsync(AddRequest request,
+        IntermediateResponseHandler intermediateResponseHandler,
+        ResultHandler<? super Result> resultHandler)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      if (!resultCode.isExceptional())
+      {
+        return new CompletedFutureResult<Result>(
+            Responses.newResult(resultCode));
+      }
+      else
+      {
+        return new CompletedFutureResult<Result>(newErrorResult(resultCode));
+      }
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addConnectionEventListener(ConnectionEventListener listener)
+        throws IllegalStateException, NullPointerException
+    {
+      // Do nothing.
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public FutureResult<BindResult> bindAsync(BindRequest request,
+        IntermediateResponseHandler intermediateResponseHandler,
+        ResultHandler<? super BindResult> resultHandler)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      if (!resultCode.isExceptional())
+      {
+        return new CompletedFutureResult<BindResult>(
+            Responses.newBindResult(resultCode));
+      }
+      else
+      {
+        return new CompletedFutureResult<BindResult>(newErrorResult(resultCode));
+      }
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void close(UnbindRequest request, String reason)
+        throws NullPointerException
+    {
+      // Do nothing.
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public FutureResult<CompareResult> compareAsync(CompareRequest request,
+        IntermediateResponseHandler intermediateResponseHandler,
+        ResultHandler<? super CompareResult> resultHandler)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      if (!resultCode.isExceptional())
+      {
+        return new CompletedFutureResult<CompareResult>(
+            Responses.newCompareResult(resultCode));
+      }
+      else
+      {
+        return new CompletedFutureResult<CompareResult>(
+            newErrorResult(resultCode));
+      }
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public FutureResult<Result> deleteAsync(DeleteRequest request,
+        IntermediateResponseHandler intermediateResponseHandler,
+        ResultHandler<? super Result> resultHandler)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      if (!resultCode.isExceptional())
+      {
+        return new CompletedFutureResult<Result>(
+            Responses.newResult(resultCode));
+      }
+      else
+      {
+        return new CompletedFutureResult<Result>(newErrorResult(resultCode));
+      }
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public <R extends ExtendedResult> FutureResult<R> extendedRequestAsync(
+        ExtendedRequest<R> request,
+        IntermediateResponseHandler intermediateResponseHandler,
+        ResultHandler<? super R> resultHandler)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      if (!resultCode.isExceptional())
+      {
+        return new CompletedFutureResult<R>(request.getResultDecoder()
+            .newExtendedErrorResult(resultCode, "", ""));
+      }
+      else
+      {
+        return new CompletedFutureResult<R>(newErrorResult(resultCode));
+      }
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isClosed()
+    {
+      return false;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isValid()
+    {
+      return true;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public FutureResult<Result> modifyAsync(ModifyRequest request,
+        IntermediateResponseHandler intermediateResponseHandler,
+        ResultHandler<? super Result> resultHandler)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      if (!resultCode.isExceptional())
+      {
+        return new CompletedFutureResult<Result>(
+            Responses.newResult(resultCode));
+      }
+      else
+      {
+        return new CompletedFutureResult<Result>(newErrorResult(resultCode));
+      }
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public FutureResult<Result> modifyDNAsync(ModifyDNRequest request,
+        IntermediateResponseHandler intermediateResponseHandler,
+        ResultHandler<? super Result> resultHandler)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      if (!resultCode.isExceptional())
+      {
+        return new CompletedFutureResult<Result>(
+            Responses.newResult(resultCode));
+      }
+      else
+      {
+        return new CompletedFutureResult<Result>(newErrorResult(resultCode));
+      }
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void removeConnectionEventListener(ConnectionEventListener listener)
+        throws NullPointerException
+    {
+      // Do nothing.
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public FutureResult<Result> searchAsync(SearchRequest request,
+        IntermediateResponseHandler intermediateResponseHandler,
+        SearchResultHandler resultHandler)
+        throws UnsupportedOperationException, IllegalStateException,
+        NullPointerException
+    {
+      if (entry != null)
+      {
+        resultHandler.handleEntry(entry);
+      }
+
+      if (!resultCode.isExceptional())
+      {
+        return new CompletedFutureResult<Result>(
+            Responses.newResult(resultCode));
+      }
+      else
+      {
+        return new CompletedFutureResult<Result>(newErrorResult(resultCode));
+      }
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString()
+    {
+      return "MockConnection";
+    }
+
+  }
+
+
+
+  @Test()
+  public void testAddRequestSuccess() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(ResultCode.SUCCESS);
+    final AddRequest addRequest = Requests.newAddRequest("cn=test");
+    assertThat(mockConnection.add(addRequest).getResultCode()).isEqualTo(
+        ResultCode.SUCCESS);
+  }
+
+
+
+  @Test()
+  public void testAddRequestFail() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(
+        ResultCode.UNWILLING_TO_PERFORM);
+    final AddRequest addRequest = Requests.newAddRequest("cn=test");
+    try
+    {
+      mockConnection.add(addRequest);
+      fail();
+    }
+    catch (ErrorResultException e)
+    {
+      assertThat(e.getResult().getResultCode()).isEqualTo(
+          ResultCode.UNWILLING_TO_PERFORM);
+    }
+  }
+
+
+
+  @Test()
+  public void testBindRequestSuccess() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(ResultCode.SUCCESS);
+    final BindRequest bindRequest = Requests.newSimpleBindRequest();
+    assertThat(mockConnection.bind(bindRequest).getResultCode()).isEqualTo(
+        ResultCode.SUCCESS);
+  }
+
+
+
+  @Test()
+  public void testBindRequestFail() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(
+        ResultCode.UNWILLING_TO_PERFORM);
+    final BindRequest bindRequest = Requests.newSimpleBindRequest();
+    try
+    {
+      mockConnection.bind(bindRequest);
+      fail();
+    }
+    catch (ErrorResultException e)
+    {
+      assertThat(e.getResult().getResultCode()).isEqualTo(
+          ResultCode.UNWILLING_TO_PERFORM);
+    }
+  }
+
+
+
+  @Test()
+  public void testCompareRequestSuccess() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(ResultCode.SUCCESS);
+    final CompareRequest compareRequest = Requests.newCompareRequest("cn=test",
+        "cn", "test");
+    assertThat(mockConnection.compare(compareRequest).getResultCode())
+        .isEqualTo(ResultCode.SUCCESS);
+  }
+
+
+
+  @Test()
+  public void testCompareRequestFail() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(
+        ResultCode.UNWILLING_TO_PERFORM);
+    final CompareRequest compareRequest = Requests.newCompareRequest("cn=test",
+        "cn", "test");
+    try
+    {
+      mockConnection.compare(compareRequest);
+      fail();
+    }
+    catch (ErrorResultException e)
+    {
+      assertThat(e.getResult().getResultCode()).isEqualTo(
+          ResultCode.UNWILLING_TO_PERFORM);
+    }
+  }
+
+
+
+  @Test()
+  public void testDeleteRequestSuccess() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(ResultCode.SUCCESS);
+    final DeleteRequest deleteRequest = Requests.newDeleteRequest("cn=test");
+    assertThat(mockConnection.delete(deleteRequest).getResultCode()).isEqualTo(
+        ResultCode.SUCCESS);
+  }
+
+
+
+  @Test()
+  public void testDeleteRequestFail() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(
+        ResultCode.UNWILLING_TO_PERFORM);
+    final DeleteRequest deleteRequest = Requests.newDeleteRequest("cn=test");
+    try
+    {
+      mockConnection.delete(deleteRequest);
+      fail();
+    }
+    catch (ErrorResultException e)
+    {
+      assertThat(e.getResult().getResultCode()).isEqualTo(
+          ResultCode.UNWILLING_TO_PERFORM);
+    }
+  }
+
+
+
+  @Test()
+  public void testExtendedRequestSuccess() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(ResultCode.SUCCESS);
+    final GenericExtendedRequest extendedRequest = Requests
+        .newGenericExtendedRequest("test");
+    assertThat(mockConnection.extendedRequest(extendedRequest).getResultCode())
+        .isEqualTo(ResultCode.SUCCESS);
+  }
+
+
+
+  @Test()
+  public void testExtendedRequestFail() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(
+        ResultCode.UNWILLING_TO_PERFORM);
+    final GenericExtendedRequest extendedRequest = Requests
+        .newGenericExtendedRequest("test");
+    try
+    {
+      mockConnection.extendedRequest(extendedRequest);
+      fail();
+    }
+    catch (ErrorResultException e)
+    {
+      assertThat(e.getResult().getResultCode()).isEqualTo(
+          ResultCode.UNWILLING_TO_PERFORM);
+    }
+  }
+
+
+
+  @Test()
+  public void testModifyRequestSuccess() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(ResultCode.SUCCESS);
+    final ModifyRequest modifyRequest = Requests.newModifyRequest("cn=test");
+    assertThat(mockConnection.modify(modifyRequest).getResultCode()).isEqualTo(
+        ResultCode.SUCCESS);
+  }
+
+
+
+  @Test()
+  public void testModifyRequestFail() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(
+        ResultCode.UNWILLING_TO_PERFORM);
+    final ModifyRequest modifyRequest = Requests.newModifyRequest("cn=test");
+    try
+    {
+      mockConnection.modify(modifyRequest);
+      fail();
+    }
+    catch (ErrorResultException e)
+    {
+      assertThat(e.getResult().getResultCode()).isEqualTo(
+          ResultCode.UNWILLING_TO_PERFORM);
+    }
+  }
+
+
+
+  @Test()
+  public void testModifyDNRequestSuccess() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(ResultCode.SUCCESS);
+    final ModifyDNRequest modifyDNRequest = Requests.newModifyDNRequest(
+        "cn=test", "cn=newrdn");
+    assertThat(mockConnection.modifyDN(modifyDNRequest).getResultCode())
+        .isEqualTo(ResultCode.SUCCESS);
+  }
+
+
+
+  @Test()
+  public void testModifyDNRequestFail() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(
+        ResultCode.UNWILLING_TO_PERFORM);
+    final ModifyDNRequest modifyDNRequest = Requests.newModifyDNRequest(
+        "cn=test", "cn=newrdn");
+    try
+    {
+      mockConnection.modifyDN(modifyDNRequest);
+      fail();
+    }
+    catch (ErrorResultException e)
+    {
+      assertThat(e.getResult().getResultCode()).isEqualTo(
+          ResultCode.UNWILLING_TO_PERFORM);
+    }
+  }
+
+
+
+  @Test()
+  public void testSearchRequestSuccess() throws Exception
+  {
+    final SearchResultEntry entry = Responses.newSearchResultEntry("cn=test");
+    final Connection mockConnection = new MockConnection(ResultCode.SUCCESS,
+        entry);
+    final SearchRequest searchRequest = Requests.newSearchRequest("cn=test",
+        SearchScope.BASE_OBJECT, "(objectClass=*)");
+    List<SearchResultEntry> entries = new LinkedList<SearchResultEntry>();
+    assertThat(mockConnection.search(searchRequest, entries).getResultCode())
+        .isEqualTo(ResultCode.SUCCESS);
+    assertThat(entries.size()).isEqualTo(1);
+    assertThat(entries.iterator().next()).isSameAs(entry);
+  }
+
+
+
+  @Test()
+  public void testSearchRequestFail() throws Exception
+  {
+    final Connection mockConnection = new MockConnection(
+        ResultCode.UNWILLING_TO_PERFORM);
+    final SearchRequest searchRequest = Requests.newSearchRequest("cn=test",
+        SearchScope.BASE_OBJECT, "(objectClass=*)");
+    List<SearchResultEntry> entries = new LinkedList<SearchResultEntry>();
+    try
+    {
+      mockConnection.search(searchRequest, entries);
+      fail();
+    }
+    catch (ErrorResultException e)
+    {
+      assertThat(e.getResult().getResultCode()).isEqualTo(
+          ResultCode.UNWILLING_TO_PERFORM);
+      assertThat(entries.isEmpty());
+    }
+  }
+}
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionFactoryTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionFactoryTestCase.java
index d28c69a..aeb42b3 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionFactoryTestCase.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ConnectionFactoryTestCase.java
@@ -29,6 +29,7 @@
 package org.forgerock.opendj.ldap;
 
 
+
 import static org.fest.assertions.Assertions.assertThat;
 
 import static org.testng.Assert.assertNotNull;
@@ -69,7 +70,7 @@
 @SuppressWarnings("javadoc")
 public class ConnectionFactoryTestCase extends SdkTestCase
 {
-  class MyResultHandler implements ResultHandler<AsynchronousConnection>
+  class MyResultHandler implements ResultHandler<Connection>
   {
     // latch.
     private final CountDownLatch latch;
@@ -94,7 +95,7 @@
 
 
 
-    public void handleResult(final AsynchronousConnection con)
+    public void handleResult(final Connection con)
     {
       //
       latch.countDown();
@@ -166,8 +167,7 @@
     // AuthenticatedConnectionFactory with multi-stage SASL
     factories[3][0] = new AuthenticatedConnectionFactory(
         new LDAPConnectionFactory("localhost", TestCaseUtils.getLdapPort()),
-        Requests.newCRAMMD5SASLBindRequest("id:user",
-            "password".toCharArray()));
+        Requests.newCRAMMD5SASLBindRequest("id:user", "password".toCharArray()));
 
     // LDAPConnectionFactory with default options
     factories[4][0] = new LDAPConnectionFactory("localhost",
@@ -267,12 +267,11 @@
   public void testBlockingFutureNoHandler(ConnectionFactory factory)
       throws Exception
   {
-    final FutureResult<AsynchronousConnection> future = factory
-        .getAsynchronousConnection(null);
-    final AsynchronousConnection con = future.get();
+    final FutureResult<Connection> future = factory.getConnectionAsync(null);
+    final Connection con = future.get();
     // quickly check if it is a valid connection.
     // Don't use a result handler.
-    assertNotNull(con.readEntry(DN.rootDN(), null, null).get());
+    assertNotNull(con.readEntryAsync(DN.rootDN(), null, null).get());
     con.close();
   }
 
@@ -290,7 +289,7 @@
     // Use the handler to get the result asynchronously.
     final CountDownLatch latch = new CountDownLatch(1);
     final MyResultHandler handler = new MyResultHandler(latch);
-    factory.getAsynchronousConnection(handler);
+    factory.getConnectionAsync(handler);
 
     // Since we don't have anything to do, we would rather
     // be notified by the latch when the other thread calls our handler.
@@ -336,8 +335,8 @@
   {
     // Create a connection factory: this should always use the default schema,
     // even if it is updated.
-    final ConnectionFactory factory = new LDAPConnectionFactory(
-        "localhost", TestCaseUtils.getLdapPort());
+    final ConnectionFactory factory = new LDAPConnectionFactory("localhost",
+        TestCaseUtils.getLdapPort());
     final Schema defaultSchema = Schema.getDefaultSchema();
 
     final Connection connection = factory.getConnection();
@@ -346,14 +345,11 @@
       // Simulate a client which reads the schema from the server and then
       // sets it as the application default. We then want subsequent
       // operations to use this schema, not the original default.
-      final SchemaBuilder builder = new SchemaBuilder(
-          Schema.getCoreSchema());
-      builder
-          .addAttributeType(
-              "( 0.9.2342.19200300.100.1.3 NAME 'mail' EQUALITY "
-                  + "caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch "
-                  + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )",
-              false);
+      final SchemaBuilder builder = new SchemaBuilder(Schema.getCoreSchema());
+      builder.addAttributeType(
+          "( 0.9.2342.19200300.100.1.3 NAME 'mail' EQUALITY "
+              + "caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch "
+              + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )", false);
       final Schema testSchema = builder.toSchema().asNonStrictSchema();
       assertThat(testSchema.getWarnings()).isEmpty();
       Schema.setDefaultSchema(testSchema);
@@ -364,8 +360,8 @@
 
       assertThat(e.getAttribute("mail")).isNotNull();
       assertThat(
-          e.getAttribute(AttributeDescription.valueOf("mail",
-              testSchema))).isNotNull();
+          e.getAttribute(AttributeDescription.valueOf("mail", testSchema)))
+          .isNotNull();
     }
     finally
     {
@@ -382,7 +378,8 @@
   /**
    * Tests connection pool closure.
    *
-   * @throws Exception If an unexpected exception occurred.
+   * @throws Exception
+   *           If an unexpected exception occurred.
    */
   @SuppressWarnings("unchecked")
   @Test
@@ -398,19 +395,19 @@
 
     // Mock underlying connection factory which always succeeds.
     final ConnectionFactory mockFactory = mock(ConnectionFactory.class);
-    when(mockFactory.getAsynchronousConnection(any(ResultHandler.class)))
-        .thenAnswer(new Answer<FutureResult<AsynchronousConnection>>()
+    when(mockFactory.getConnectionAsync(any(ResultHandler.class))).thenAnswer(
+        new Answer<FutureResult<Connection>>()
         {
 
-          public FutureResult<AsynchronousConnection> answer(
-              InvocationOnMock invocation) throws Throwable
+          public FutureResult<Connection> answer(InvocationOnMock invocation)
+              throws Throwable
           {
             // Update state.
             final int connectionID = realConnectionCount.getAndIncrement();
             realConnectionIsClosed[connectionID] = false;
 
             // Mock connection decrements counter on close.
-            AsynchronousConnection mockConnection = mock(AsynchronousConnection.class);
+            Connection mockConnection = mock(Connection.class);
             doAnswer(new Answer<Void>()
             {
               public Void answer(InvocationOnMock invocation) throws Throwable
@@ -421,17 +418,17 @@
               }
             }).when(mockConnection).close();
             when(mockConnection.isValid()).thenReturn(true);
-            when(mockConnection.toString()).thenReturn("Mock connection " + connectionID);
+            when(mockConnection.toString()).thenReturn(
+                "Mock connection " + connectionID);
 
-            // Excecute handler and return future.
-            ResultHandler<? super AsynchronousConnection> handler =
-              (ResultHandler<? super AsynchronousConnection>) invocation.getArguments()[0];
+            // Execute handler and return future.
+            ResultHandler<? super Connection> handler = (ResultHandler<? super Connection>) invocation
+                .getArguments()[0];
             if (handler != null)
             {
               handler.handleResult(mockConnection);
             }
-            return new CompletedFutureResult<AsynchronousConnection>(
-                mockConnection);
+            return new CompletedFutureResult<Connection>(mockConnection);
           }
         });
 
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java
index 8e71809..4c1e11c 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
@@ -122,8 +123,8 @@
     @Override
     public void handleAdd(final Integer requestContext,
         final AddRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       resultHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
@@ -137,8 +138,8 @@
     @Override
     public void handleBind(final Integer requestContext, final int version,
         final BindRequest request,
-        final ResultHandler<? super BindResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super BindResult> resultHandler)
         throws UnsupportedOperationException
     {
       resultHandler.handleResult(Responses.newBindResult(ResultCode.SUCCESS));
@@ -152,8 +153,8 @@
     @Override
     public void handleCompare(final Integer requestContext,
         final CompareRequest request,
-        final ResultHandler<? super CompareResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super CompareResult> resultHandler)
         throws UnsupportedOperationException
     {
       resultHandler
@@ -203,8 +204,8 @@
     @Override
     public void handleDelete(final Integer requestContext,
         final DeleteRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       resultHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
@@ -218,15 +219,14 @@
     @Override
     public <R extends ExtendedResult> void handleExtendedRequest(
         final Integer requestContext, final ExtendedRequest<R> request,
-        final ResultHandler<? super R> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super R> resultHandler)
         throws UnsupportedOperationException
     {
-      resultHandler
-          .handleErrorResult(ErrorResultException.newErrorResult(request
-              .getResultDecoder().newExtendedErrorResult(
-                  ResultCode.PROTOCOL_ERROR, "",
-                  "Extended operation " + request.getOID() + " not supported")));
+      resultHandler.handleErrorResult(ErrorResultException
+          .newErrorResult(request.getResultDecoder().newExtendedErrorResult(
+              ResultCode.PROTOCOL_ERROR, "",
+              "Extended operation " + request.getOID() + " not supported")));
     }
 
 
@@ -237,8 +237,8 @@
     @Override
     public void handleModify(final Integer requestContext,
         final ModifyRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       resultHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
@@ -252,8 +252,8 @@
     @Override
     public void handleModifyDN(final Integer requestContext,
         final ModifyDNRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       resultHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
@@ -266,8 +266,9 @@
      */
     @Override
     public void handleSearch(final Integer requestContext,
-        final SearchRequest request, final SearchResultHandler resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final SearchRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final SearchResultHandler resultHandler)
         throws UnsupportedOperationException
     {
       resultHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
@@ -382,7 +383,7 @@
    * @throws Exception
    *           If an unexpected error occurred.
    */
-  @Test(enabled=false)
+  @Test(enabled = false)
   public void testConnectionEventListenerDisconnect() throws Exception
   {
     final MockServerConnection onlineServerConnection = new MockServerConnection();
@@ -416,8 +417,8 @@
 
       connection.addConnectionEventListener(listener);
       Assert.assertEquals(listener.closeLatch.getCount(), 1);
-      Assert.assertTrue(onlineServerConnection.isConnected
-          .await(10, TimeUnit.SECONDS));
+      Assert.assertTrue(onlineServerConnection.isConnected.await(10,
+          TimeUnit.SECONDS));
       onlineServerConnection.context.disconnect();
       listener.closeLatch.await();
       Assert.assertNull(listener.errorMessage);
@@ -474,8 +475,8 @@
 
       connection.addConnectionEventListener(listener);
       Assert.assertEquals(listener.closeLatch.getCount(), 1);
-      Assert.assertTrue(onlineServerConnection.isConnected
-          .await(10, TimeUnit.SECONDS));
+      Assert.assertTrue(onlineServerConnection.isConnected.await(10,
+          TimeUnit.SECONDS));
       onlineServerConnection.context.disconnect(ResultCode.BUSY, "test");
       listener.closeLatch.await();
       Assert.assertNull(listener.errorMessage);
@@ -715,8 +716,8 @@
         @Override
         public void handleBind(final Integer requestContext, final int version,
             final BindRequest request,
-            final ResultHandler<? super BindResult> resultHandler,
-            final IntermediateResponseHandler intermediateResponseHandler)
+            final IntermediateResponseHandler intermediateResponseHandler,
+            final ResultHandler<? super BindResult> resultHandler)
             throws UnsupportedOperationException
         {
           // Get connection from load balancer, this should fail over twice
@@ -904,8 +905,8 @@
         @Override
         public void handleBind(final Integer requestContext, final int version,
             final BindRequest request,
-            final ResultHandler<? super BindResult> resultHandler,
-            final IntermediateResponseHandler intermediateResponseHandler)
+            final IntermediateResponseHandler intermediateResponseHandler,
+            final ResultHandler<? super BindResult> resultHandler)
             throws UnsupportedOperationException
         {
           // First attempt offline server.
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java
index 43081d1..e119952 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java
@@ -137,8 +137,7 @@
 
 
 
-  private class LDAPServerConnection implements
-      ServerConnection<Integer>
+  private class LDAPServerConnection implements ServerConnection<Integer>
   {
 
     private final LDAPClientContext clientContext;
@@ -187,9 +186,9 @@
      * @param intermediateResponseHandler
      * @throws UnsupportedOperationException
      */
-    public void handleAdd(final Integer context,
-        final AddRequest request, final ResultHandler<? super Result> handler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+    public void handleAdd(final Integer context, final AddRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> handler)
         throws UnsupportedOperationException
     {
       Result result = null;
@@ -201,7 +200,8 @@
       {
         // duplicate entry.
         result = Responses.newResult(ResultCode.ENTRY_ALREADY_EXISTS);
-        final ErrorResultException ere = ErrorResultException.newErrorResult(result);
+        final ErrorResultException ere = ErrorResultException
+            .newErrorResult(result);
         handler.handleErrorResult(ere);
         // doesn't matter if it was canceled.
         requestsInProgress.remove(context);
@@ -223,7 +223,8 @@
       if (abReq.isCanceled())
       {
         result = Responses.newResult(ResultCode.CANCELLED);
-        final ErrorResultException ere = ErrorResultException.newErrorResult(result);
+        final ErrorResultException ere = ErrorResultException
+            .newErrorResult(result);
         handler.handleErrorResult(ere);
         requestsInProgress.remove(context);
         return;
@@ -247,8 +248,8 @@
      */
     public void handleBind(final Integer context, final int version,
         final BindRequest request,
-        final ResultHandler<? super BindResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super BindResult> resultHandler)
         throws UnsupportedOperationException
     {
       // TODO: all bind types.
@@ -350,8 +351,8 @@
                   }
                   catch (SaslException e)
                   {
-                    throw ErrorResultException.newErrorResult(Responses.newResult(
-                        ResultCode.OPERATIONS_ERROR).setCause(e));
+                    throw ErrorResultException.newErrorResult(Responses
+                        .newResult(ResultCode.OPERATIONS_ERROR).setCause(e));
                   }
                 }
 
@@ -366,8 +367,8 @@
                   }
                   catch (SaslException e)
                   {
-                    throw ErrorResultException.newErrorResult(Responses.newResult(
-                        ResultCode.OPERATIONS_ERROR).setCause(e));
+                    throw ErrorResultException.newErrorResult(Responses
+                        .newResult(ResultCode.OPERATIONS_ERROR).setCause(e));
                   }
                 }
               };
@@ -385,9 +386,10 @@
         }
         catch (Exception e)
         {
-          resultHandler.handleErrorResult(ErrorResultException.newErrorResult(Responses
-              .newBindResult(ResultCode.OPERATIONS_ERROR).setCause(e)
-              .setDiagnosticMessage(e.toString())));
+          resultHandler.handleErrorResult(ErrorResultException
+              .newErrorResult(Responses
+                  .newBindResult(ResultCode.OPERATIONS_ERROR).setCause(e)
+                  .setDiagnosticMessage(e.toString())));
         }
       }
       else
@@ -457,8 +459,8 @@
      */
     public void handleCompare(final Integer context,
         final CompareRequest request,
-        final ResultHandler<? super CompareResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super CompareResult> resultHandler)
         throws UnsupportedOperationException
     {
       CompareResult result = null;
@@ -470,7 +472,8 @@
       {
         // entry not found.
         result = Responses.newCompareResult(ResultCode.NO_SUCH_ATTRIBUTE);
-        final ErrorResultException ere = ErrorResultException.newErrorResult(result);
+        final ErrorResultException ere = ErrorResultException
+            .newErrorResult(result);
         resultHandler.handleErrorResult(ere);
         // doesn't matter if it was canceled.
         requestsInProgress.remove(context);
@@ -489,7 +492,8 @@
           if (abReq.isCanceled())
           {
             final Result r = Responses.newResult(ResultCode.CANCELLED);
-            final ErrorResultException ere = ErrorResultException.newErrorResult(r);
+            final ErrorResultException ere = ErrorResultException
+                .newErrorResult(r);
             resultHandler.handleErrorResult(ere);
             requestsInProgress.remove(context);
             return;
@@ -519,8 +523,8 @@
      */
     public void handleDelete(final Integer context,
         final DeleteRequest request,
-        final ResultHandler<? super Result> handler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> handler)
         throws UnsupportedOperationException
     {
       Result result = null;
@@ -532,7 +536,8 @@
       {
         // entry is not found.
         result = Responses.newResult(ResultCode.NO_SUCH_OBJECT);
-        final ErrorResultException ere = ErrorResultException.newErrorResult(result);
+        final ErrorResultException ere = ErrorResultException
+            .newErrorResult(result);
         handler.handleErrorResult(ere);
         // doesn't matter if it was canceled.
         requestsInProgress.remove(context);
@@ -542,7 +547,8 @@
       if (abReq.isCanceled())
       {
         result = Responses.newResult(ResultCode.CANCELLED);
-        final ErrorResultException ere = ErrorResultException.newErrorResult(result);
+        final ErrorResultException ere = ErrorResultException
+            .newErrorResult(result);
         handler.handleErrorResult(ere);
         requestsInProgress.remove(context);
         return;
@@ -563,8 +569,8 @@
      */
     public <R extends ExtendedResult> void handleExtendedRequest(
         final Integer context, final ExtendedRequest<R> request,
-        final ResultHandler<? super R> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super R> resultHandler)
         throws UnsupportedOperationException
     {
       if (request.getOID().equals(StartTLSExtendedRequest.OID))
@@ -588,8 +594,8 @@
      */
     public void handleModify(final Integer context,
         final ModifyRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       // TODO:
@@ -606,8 +612,8 @@
      */
     public void handleModifyDN(final Integer context,
         final ModifyDNRequest request,
-        final ResultHandler<? super Result> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final ResultHandler<? super Result> resultHandler)
         throws UnsupportedOperationException
     {
       // TODO
@@ -616,15 +622,16 @@
 
 
     /**
-     * @param context
      * @param request
-     * @param resultHandler
      * @param intermediateResponseHandler
+     * @param resultHandler
+     * @param context
      * @throws UnsupportedOperationException
      */
     public void handleSearch(final Integer context,
-        final SearchRequest request, final SearchResultHandler resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+        final SearchRequest request,
+        final IntermediateResponseHandler intermediateResponseHandler,
+        final SearchResultHandler resultHandler)
         throws UnsupportedOperationException
     {
       Result result = null;
@@ -636,7 +643,8 @@
       {
         // Entry not found.
         result = Responses.newResult(ResultCode.NO_SUCH_OBJECT);
-        final ErrorResultException ere = ErrorResultException.newErrorResult(result);
+        final ErrorResultException ere = ErrorResultException
+            .newErrorResult(result);
         resultHandler.handleErrorResult(ere);
         // Should searchResultHandler handle anything?
 
@@ -648,7 +656,8 @@
       if (abReq.isCanceled())
       {
         result = Responses.newResult(ResultCode.CANCELLED);
-        final ErrorResultException ere = ErrorResultException.newErrorResult(result);
+        final ErrorResultException ere = ErrorResultException
+            .newErrorResult(result);
         resultHandler.handleErrorResult(ere);
         requestsInProgress.remove(context);
         return;
@@ -685,8 +694,7 @@
 
   // The mapping between the message id and the requests the server is currently
   // handling.
-  private final ConcurrentHashMap<Integer, AbandonableRequest> requestsInProgress =
-    new ConcurrentHashMap<Integer, AbandonableRequest>();
+  private final ConcurrentHashMap<Integer, AbandonableRequest> requestsInProgress = new ConcurrentHashMap<Integer, AbandonableRequest>();
 
   private SSLContext sslContext;
 
@@ -704,7 +712,8 @@
       final String sn = String.format("sn: %d", i);
       final String uid = String.format("uid: user.%d", i);
 
-      // See org.forgerock.opendj.ldap.ConnectionFactoryTestCase.testSchemaUsage().
+      // See
+      // org.forgerock.opendj.ldap.ConnectionFactoryTestCase.testSchemaUsage().
       final String mail = String.format("mail: user.%d@example.com", i);
 
       final DN d = DN.valueOf(dn);
diff --git a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthRate.java b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthRate.java
index 75762cf..1ba09f3 100644
--- a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthRate.java
+++ b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthRate.java
@@ -134,7 +134,7 @@
 
 
 
-      private BindWorkerThread(final AsynchronousConnection connection,
+      private BindWorkerThread(final Connection connection,
           final ConnectionFactory connectionFactory)
       {
         super(connection, connectionFactory);
@@ -143,8 +143,7 @@
 
 
       @Override
-      public FutureResult<?> performOperation(
-          final AsynchronousConnection connection,
+      public FutureResult<?> performOperation(final Connection connection,
           final DataSource[] dataSources, final long startTime)
       {
         if (dataSources != null)
@@ -179,7 +178,7 @@
           }
 
           final RecursiveFutureResult<SearchResultEntry, BindResult> future =
-            new RecursiveFutureResult<SearchResultEntry, BindResult>(
+              new RecursiveFutureResult<SearchResultEntry, BindResult>(
               new BindUpdateStatsResultHandler(startTime))
           {
             @Override
@@ -197,7 +196,7 @@
               return performBind(connection, data, resultHandler);
             }
           };
-          connection.searchSingleEntry(sr, future);
+          connection.searchSingleEntryAsync(sr, future);
           return future;
         }
         else
@@ -209,9 +208,8 @@
 
 
 
-      private FutureResult<BindResult> performBind(
-          final AsynchronousConnection connection, final Object[] data,
-          final ResultHandler<? super BindResult> handler)
+      private FutureResult<BindResult> performBind(final Connection connection,
+          final Object[] data, final ResultHandler<? super BindResult> handler)
       {
         final boolean useInvalidPassword;
 
@@ -380,28 +378,20 @@
           }
         }
 
-        return connection.bind(br, handler);
+        return connection.bindAsync(br, null, handler);
       }
     }
 
 
 
     private final AtomicLong searchWaitRecentTime = new AtomicLong();
-
     private final AtomicInteger invalidCredRecentCount = new AtomicInteger();
-
     private String filter;
-
     private String baseDN;
-
     private SearchScope scope;
-
     private DereferenceAliasesPolicy dereferencesAliasesPolicy;
-
     private String[] attributes;
-
     private BindRequest bindRequest;
-
     private int invalidCredPercent;
 
 
@@ -415,8 +405,7 @@
 
 
     @Override
-    WorkerThread newWorkerThread(
-        final AsynchronousConnection connection,
+    WorkerThread newWorkerThread(final Connection connection,
         final ConnectionFactory connectionFactory)
     {
       return new BindWorkerThread(connection, connectionFactory);
@@ -449,7 +438,6 @@
 
 
   private BooleanArgument verbose;
-
   private BooleanArgument scriptFriendly;
 
 
diff --git a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthenticatedConnectionFactory.java b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthenticatedConnectionFactory.java
index 9b673e6..c32379a 100644
--- a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthenticatedConnectionFactory.java
+++ b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthenticatedConnectionFactory.java
@@ -23,12 +23,14 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package com.forgerock.opendj.ldap.tools;
 
 
 
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
 import org.forgerock.opendj.ldap.*;
 import org.forgerock.opendj.ldap.requests.BindRequest;
 import org.forgerock.opendj.ldap.responses.BindResult;
@@ -57,16 +59,13 @@
  * the connection attempt will fail and an {@code ErrorResultException} will be
  * thrown.
  */
-final class AuthenticatedConnectionFactory extends AbstractConnectionFactory
-    implements ConnectionFactory
+final class AuthenticatedConnectionFactory implements ConnectionFactory
 {
 
   /**
-   * An authenticated asynchronous connection supports all operations except
-   * Bind operations.
+   * An authenticated connection supports all operations except Bind operations.
    */
-  public static final class AuthenticatedAsynchronousConnection extends
-      AsynchronousConnectionDecorator
+  public static final class AuthenticatedConnection extends ConnectionDecorator
   {
 
     private final BindRequest request;
@@ -75,9 +74,8 @@
 
 
 
-    private AuthenticatedAsynchronousConnection(
-        final AsynchronousConnection connection, final BindRequest request,
-        final BindResult result)
+    private AuthenticatedConnection(final Connection connection,
+        final BindRequest request, final BindResult result)
     {
       super(connection);
       this.request = request;
@@ -90,10 +88,13 @@
      * Bind operations are not supported by pre-authenticated connections. This
      * method will always throw {@code UnsupportedOperationException}.
      */
-    public FutureResult<BindResult> bind(final BindRequest request,
-        final ResultHandler<? super BindResult> handler)
-        throws UnsupportedOperationException, IllegalStateException,
-        NullPointerException
+
+    /**
+     * {@inheritDoc}
+     */
+    public BindResult bind(BindRequest request) throws ErrorResultException,
+        InterruptedException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
     {
       throw new UnsupportedOperationException();
     }
@@ -101,12 +102,24 @@
 
 
     /**
-     * Bind operations are not supported by pre-authenticated connections. This
-     * method will always throw {@code UnsupportedOperationException}.
+     * {@inheritDoc}
      */
-    public FutureResult<BindResult> bind(final BindRequest request,
-        final ResultHandler<? super BindResult> resultHandler,
-        final IntermediateResponseHandler intermediateResponseHandler)
+    public BindResult bind(String name, char[] password)
+        throws ErrorResultException, InterruptedException,
+        LocalizedIllegalArgumentException, UnsupportedOperationException,
+        IllegalStateException, NullPointerException
+    {
+      throw new UnsupportedOperationException();
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public FutureResult<BindResult> bindAsync(BindRequest request,
+        IntermediateResponseHandler intermediateResponseHandler,
+        ResultHandler<? super BindResult> resultHandler)
         throws UnsupportedOperationException, IllegalStateException,
         NullPointerException
     {
@@ -144,7 +157,7 @@
      *           If this connection has already been closed, i.e. if
      *           {@code isClosed() == true}.
      */
-    public FutureResult<BindResult> rebind(
+    public FutureResult<BindResult> rebindAsync(
         final ResultHandler<? super BindResult> handler)
         throws UnsupportedOperationException, IllegalStateException
     {
@@ -177,7 +190,7 @@
         public void handleResult(final BindResult result)
         {
           // Save the result.
-          AuthenticatedAsynchronousConnection.this.result = result;
+          AuthenticatedConnection.this.result = result;
 
           if (clientHandler != null)
           {
@@ -187,7 +200,7 @@
 
       };
 
-      return connection.bind(request, handlerWrapper);
+      return connection.bindAsync(request, null, handlerWrapper);
     }
 
 
@@ -208,115 +221,20 @@
 
 
 
-  /**
-   * An authenticated synchronous connection supports all operations except Bind
-   * operations.
-   */
-  public static final class AuthenticatedConnection extends
-      SynchronousConnection
-  {
-    private final AuthenticatedAsynchronousConnection connection;
-
-
-
-    private AuthenticatedConnection(
-        final AuthenticatedAsynchronousConnection connection)
-    {
-      super(connection);
-      this.connection = connection;
-    }
-
-
-
-    /**
-     * Bind operations are not supported by pre-authenticated connections. This
-     * method will always throw {@code UnsupportedOperationException}.
-     */
-    @Override
-    public BindResult bind(final BindRequest request)
-        throws UnsupportedOperationException
-    {
-      throw new UnsupportedOperationException();
-    }
-
-
-
-    /**
-     * Bind operations are not supported by pre-authenticated connections. This
-     * method will always throw {@code UnsupportedOperationException}.
-     */
-    @Override
-    public BindResult bind(final String name, final char[] password)
-        throws UnsupportedOperationException
-    {
-      throw new UnsupportedOperationException();
-    }
-
-
-
-    /**
-     * Returns an unmodifiable view of the Bind result which was returned from
-     * the server after authentication.
-     *
-     * @return The Bind result which was returned from the server after
-     *         authentication.
-     */
-    public BindResult getAuthenticatedBindResult()
-    {
-      return connection.getAuthenticatedBindResult();
-    }
-
-
-
-    /**
-     * Re-authenticates to the Directory Server using the bind request
-     * associated with this connection. If re-authentication fails for some
-     * reason then this connection will be automatically closed.
-     *
-     * @return The result of the operation.
-     * @throws ErrorResultException
-     *           If the result code indicates that the request failed for some
-     *           reason.
-     * @throws InterruptedException
-     *           If the current thread was interrupted while waiting.
-     * @throws UnsupportedOperationException
-     *           If this connection does not support rebind operations.
-     * @throws IllegalStateException
-     *           If this connection has already been closed, i.e. if
-     *           {@code isClosed() == true}.
-     */
-    public BindResult rebind() throws ErrorResultException,
-        InterruptedException, UnsupportedOperationException,
-        IllegalStateException
-    {
-
-      if (connection.request == null)
-      {
-        throw new UnsupportedOperationException();
-      }
-      return super.bind(connection.request);
-    }
-  }
-
-
-
   private static final class FutureResultImpl
   {
-    private final FutureResultTransformer<BindResult, AsynchronousConnection> futureBindResult;
-
-    private final RecursiveFutureResult<AsynchronousConnection, BindResult> futureConnectionResult;
-
+    private final FutureResultTransformer<BindResult, Connection> futureBindResult;
+    private final RecursiveFutureResult<Connection, BindResult> futureConnectionResult;
     private final BindRequest bindRequest;
-
-    private AsynchronousConnection connection;
+    private Connection connection;
 
 
 
     private FutureResultImpl(final BindRequest request,
-        final ResultHandler<? super AsynchronousConnection> handler)
+        final ResultHandler<? super Connection> handler)
     {
       this.bindRequest = request;
-      this.futureBindResult = new FutureResultTransformer<BindResult, AsynchronousConnection>(
+      this.futureBindResult = new FutureResultTransformer<BindResult, Connection>(
           handler)
       {
 
@@ -340,27 +258,26 @@
 
 
         @Override
-        protected AuthenticatedAsynchronousConnection transformResult(
+        protected AuthenticatedConnection transformResult(
             final BindResult result) throws ErrorResultException
         {
           // FIXME: should make the result unmodifiable.
-          return new AuthenticatedAsynchronousConnection(connection,
-              bindRequest, result);
+          return new AuthenticatedConnection(connection, bindRequest, result);
         }
 
       };
-      this.futureConnectionResult = new RecursiveFutureResult<AsynchronousConnection, BindResult>(
+      this.futureConnectionResult = new RecursiveFutureResult<Connection, BindResult>(
           futureBindResult)
       {
 
         @Override
         protected FutureResult<? extends BindResult> chainResult(
-            final AsynchronousConnection innerResult,
+            final Connection innerResult,
             final ResultHandler<? super BindResult> handler)
             throws ErrorResultException
         {
           connection = innerResult;
-          return connection.bind(bindRequest, handler);
+          return connection.bindAsync(bindRequest, null, handler);
         }
       };
       futureBindResult.setFutureResult(futureConnectionResult);
@@ -371,9 +288,7 @@
 
 
   private final BindRequest request;
-
   private final ConnectionFactory parentFactory;
-
   private boolean allowRebinds = false;
 
 
@@ -403,13 +318,41 @@
 
 
 
-  @Override
-  public FutureResult<AsynchronousConnection> getAsynchronousConnection(
-      final ResultHandler<? super AsynchronousConnection> handler)
+  /**
+   * {@inheritDoc}
+   */
+  public Connection getConnection() throws ErrorResultException,
+      InterruptedException
+  {
+    final Connection connection = parentFactory.getConnection();
+    BindResult bindResult = null;
+    try
+    {
+      bindResult = connection.bind(request);
+    }
+    finally
+    {
+      if (bindResult == null)
+      {
+        connection.close();
+      }
+    }
+    // If the bind didn't succeed then an exception will have been thrown and
+    // this line will not be reached.
+    return new AuthenticatedConnection(connection, request, bindResult);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public FutureResult<Connection> getConnectionAsync(
+      final ResultHandler<? super Connection> handler)
   {
     final FutureResultImpl future = new FutureResultImpl(request, handler);
     future.futureConnectionResult.setFutureResult(parentFactory
-        .getAsynchronousConnection(future.futureConnectionResult));
+        .getConnectionAsync(future.futureConnectionResult));
     return future.futureBindResult;
   }
 
diff --git a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ModRate.java b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ModRate.java
index a6c668a..2bbb066 100644
--- a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ModRate.java
+++ b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ModRate.java
@@ -57,7 +57,7 @@
 
 
 
-      private ModifyWorkerThread(final AsynchronousConnection connection,
+      private ModifyWorkerThread(final Connection connection,
           final ConnectionFactory connectionFactory)
       {
         super(connection, connectionFactory);
@@ -66,8 +66,7 @@
 
 
       @Override
-      public FutureResult<?> performOperation(
-          final AsynchronousConnection connection,
+      public FutureResult<?> performOperation(final Connection connection,
           final DataSource[] dataSources, final long startTime)
       {
         if (dataSources != null)
@@ -75,7 +74,7 @@
           data = DataSource.generateData(dataSources, data);
         }
         mr = newModifyRequest(data);
-        return connection.modify(mr,
+        return connection.modifyAsync(mr, null,
             new UpdateStatsResultHandler<Result>(startTime));
       }
 
@@ -119,7 +118,6 @@
 
 
     private String baseDN;
-
     private String[] modStrings;
 
 
@@ -133,8 +131,7 @@
 
 
     @Override
-    WorkerThread newWorkerThread(
-        final AsynchronousConnection connection,
+    WorkerThread newWorkerThread(final Connection connection,
         final ConnectionFactory connectionFactory)
     {
       return new ModifyWorkerThread(connection, connectionFactory);
@@ -167,7 +164,6 @@
 
 
   private BooleanArgument verbose;
-
   private BooleanArgument scriptFriendly;
 
 
diff --git a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java
index 0ee2525..1637257 100644
--- a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java
+++ b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/PerformanceRunner.java
@@ -23,6 +23,7 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
+ *      Portions copyright 2011 ForgeRock AS.
  */
 
 package com.forgerock.opendj.ldap.tools;
@@ -458,14 +459,12 @@
   abstract class WorkerThread extends Thread
   {
     private int count;
-
-    private final AsynchronousConnection connection;
-
+    private final Connection connection;
     private final ConnectionFactory connectionFactory;
 
 
 
-    WorkerThread(final AsynchronousConnection connection,
+    WorkerThread(final Connection connection,
         final ConnectionFactory connectionFactory)
     {
       super("Worker Thread");
@@ -475,9 +474,8 @@
 
 
 
-    public abstract FutureResult<?> performOperation(
-        AsynchronousConnection connection, DataSource[] dataSources,
-        long startTime);
+    public abstract FutureResult<?> performOperation(Connection connection,
+        DataSource[] dataSources, long startTime);
 
 
 
@@ -485,10 +483,10 @@
     public void run()
     {
       FutureResult<?> future;
-      AsynchronousConnection connection;
+      Connection connection;
 
-      final double targetTimeInMS =
-        (1000.0 / (targetThroughput / (double) (numThreads * numConnections)));
+      final double targetTimeInMS = (1000.0 / (targetThroughput /
+          (double) (numThreads * numConnections)));
       double sleepTimeInMS = 0;
       long start;
       while (!stopRequested && !(maxIterations > 0 && count >= maxIterations))
@@ -497,8 +495,7 @@
         {
           try
           {
-            connection = connectionFactory.getAsynchronousConnection(null)
-                .get();
+            connection = connectionFactory.getConnectionAsync(null).get();
           }
           catch (final InterruptedException e)
           {
@@ -520,14 +517,12 @@
         else
         {
           connection = this.connection;
-          if (!noRebind
-              && connection instanceof AuthenticatedAsynchronousConnection)
+          if (!noRebind && connection instanceof AuthenticatedConnection)
           {
-            final AuthenticatedAsynchronousConnection ac =
-              (AuthenticatedAsynchronousConnection) connection;
+            final AuthenticatedConnection ac = (AuthenticatedConnection) connection;
             try
             {
-              ac.rebind(null).get();
+              ac.rebindAsync(null).get();
             }
             catch (final InterruptedException e)
             {
@@ -869,10 +864,9 @@
       throws ArgumentException
   {
     this.app = app;
-    numThreadsArgument = new IntegerArgument("numThreads", 't',
-        "numThreads", false, false, true,
-        LocalizableMessage.raw("{numThreads}"), 1, null, true, 1,
-        false, 0,
+    numThreadsArgument = new IntegerArgument("numThreads", 't', "numThreads",
+        false, false, true, LocalizableMessage.raw("{numThreads}"), 1, null,
+        true, 1, false, 0,
         LocalizableMessage.raw("Number of worker threads per connection"));
     numThreadsArgument.setPropertyName("numThreads");
     if (!alwaysSingleThreaded)
@@ -1003,8 +997,8 @@
   {
     numConnections = numConnectionsArgument.getIntValue();
     numThreads = numThreadsArgument.getIntValue();
-    maxIterations = maxIterationsArgument.getIntValue()
-        / numConnections / numThreads;
+    maxIterations = maxIterationsArgument.getIntValue() / numConnections
+        / numThreads;
     statsInterval = statsIntervalArgument.getIntValue() * 1000;
     targetThroughput = targetThroughputArgument.getIntValue();
 
@@ -1042,8 +1036,7 @@
 
 
 
-  abstract WorkerThread newWorkerThread(
-      final AsynchronousConnection connection,
+  abstract WorkerThread newWorkerThread(final Connection connection,
       final ConnectionFactory connectionFactory);
 
 
@@ -1055,17 +1048,16 @@
   final int run(final ConnectionFactory connectionFactory)
   {
     final List<Thread> threads = new ArrayList<Thread>();
-    final List<AsynchronousConnection> connections =
-      new ArrayList<AsynchronousConnection>();
+    final List<Connection> connections = new ArrayList<Connection>();
 
-    AsynchronousConnection connection = null;
+    Connection connection = null;
     try
     {
       for (int i = 0; i < numConnections; i++)
       {
         if (keepConnectionsOpen.isPresent() || noRebindArgument.isPresent())
         {
-          connection = connectionFactory.getAsynchronousConnection(null).get();
+          connection = connectionFactory.getConnectionAsync(null).get();
           connection.addConnectionEventListener(this);
           connections.add(connection);
         }
@@ -1098,7 +1090,7 @@
     }
     finally
     {
-      for (final AsynchronousConnection c : connections)
+      for (final Connection c : connections)
       {
         c.close();
       }
diff --git a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java
index 6c07efa..5a7a566 100644
--- a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java
+++ b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java
@@ -121,12 +121,11 @@
     private final class SearchWorkerThread extends WorkerThread
     {
       private SearchRequest sr;
-
       private Object[] data;
 
 
 
-      private SearchWorkerThread(final AsynchronousConnection connection,
+      private SearchWorkerThread(final Connection connection,
           final ConnectionFactory connectionFactory)
       {
         super(connection, connectionFactory);
@@ -135,8 +134,7 @@
 
 
       @Override
-      public FutureResult<?> performOperation(
-          final AsynchronousConnection connection,
+      public FutureResult<?> performOperation(final Connection connection,
           final DataSource[] dataSources, final long startTime)
       {
         if (sr == null)
@@ -159,20 +157,17 @@
           sr.setFilter(String.format(filter, data));
           sr.setName(String.format(baseDN, data));
         }
-        return connection.search(sr, new SearchStatsHandler(startTime));
+        return connection.searchAsync(sr, null, new SearchStatsHandler(
+            startTime));
       }
     }
 
 
 
     private String filter;
-
     private String baseDN;
-
     private SearchScope scope;
-
     private DereferenceAliasesPolicy dereferencesAliasesPolicy;
-
     private String[] attributes;
 
 
@@ -186,8 +181,7 @@
 
 
     @Override
-    WorkerThread newWorkerThread(
-        final AsynchronousConnection connection,
+    WorkerThread newWorkerThread(final Connection connection,
         final ConnectionFactory connectionFactory)
     {
       return new SearchWorkerThread(connection, connectionFactory);

--
Gitblit v1.10.0