From 41a1efcbe052305b1d542e74bd86756a8a953c37 Mon Sep 17 00:00:00 2001
From: Mark Craig <mark.craig@forgerock.com>
Date: Wed, 12 Aug 2015 12:04:14 +0000
Subject: [PATCH] CR-7880 OPENDJ-1608 Provide asynchronous examples

---
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/PasswordResetForAD.java       |    6 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ReadSchema.java               |    4 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SASLAuth.java                 |    4 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLifeAsync.java           |  227 +++++++++
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchema.java                |    2 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/RewriterProxy.java            |    4 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseGenericControl.java        |   10 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ProxyBackend.java             |   13 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Modify.java                   |    4 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBindAsync.java          |  183 +++++++
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Proxy.java                    |    6 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBind.java               |    4 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Search.java                   |    6 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLife.java                |    4 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchemaAsync.java           |  183 +++++++
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchAsync.java              |    7 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ModifyAsync.java              |  177 +++++++
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UpdateGroupAsync.java         |  233 +++++++++
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Server.java                   |    4 
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SimpleAuthAsync.java          |  268 +++++++++++
 opendj-sdk/opendj-ldap-sdk-examples/src/site/xdoc/index.xml.vm                                                |   75 ++
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/GetADChangeNotifications.java |    4 
 22 files changed, 1,372 insertions(+), 56 deletions(-)

diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/GetADChangeNotifications.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/GetADChangeNotifications.java
index 215e805..2ace9cc 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/GetADChangeNotifications.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/GetADChangeNotifications.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2014 ForgeRock AS
+ *      Portions Copyright 2011-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.examples;
@@ -55,7 +55,7 @@
  * <p>This example takes the following command line parameters:
  *
  * <pre>
- *  &lt;host> &lt;port> &lt;username> &lt;password> &lt;baseDN>
+ *  {@code <host> <port> <username> <password> <baseDN>}
  * </pre>
  *
  * <p>The {@code baseDN} must be the root of a naming context in this example.
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Modify.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Modify.java
index 35adca5..0a6af91 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Modify.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Modify.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2014 ForgeRock AS
+ *      Portions Copyright 2011-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.examples;
@@ -47,7 +47,7 @@
  * parameters (it will read from stdin if no LDIF file is provided):
  *
  * <pre>
- *  &lt;host> &lt;port> &lt;username> &lt;password> [&lt;ldifFile>]
+ *  {@code <host> <port> <username> <password> [<ldifFile>]}
  * </pre>
  */
 public final class Modify {
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ModifyAsync.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ModifyAsync.java
new file mode 100644
index 0000000..f834ce1
--- /dev/null
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ModifyAsync.java
@@ -0,0 +1,177 @@
+/*
+ * 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 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 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 2015 ForgeRock AS.
+ */
+
+package org.forgerock.opendj.examples;
+
+import static org.forgerock.util.Utils.closeSilently;
+import org.forgerock.opendj.ldap.Connection;
+import org.forgerock.opendj.ldap.LDAPConnectionFactory;
+import org.forgerock.opendj.ldap.LdapException;
+import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.requests.Requests;
+import org.forgerock.opendj.ldap.responses.BindResult;
+import org.forgerock.opendj.ldap.responses.Result;
+import org.forgerock.util.AsyncFunction;
+import org.forgerock.util.promise.ExceptionHandler;
+import org.forgerock.util.promise.Promise;
+import org.forgerock.util.promise.ResultHandler;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * An example client application which applies update operations to a directory server
+ * using the asynchronous APIs.
+ * The update operations are read from an LDIF file, or stdin if no filename is provided.
+ * This example takes the following command line parameters,
+ * reading from stdin if no LDIF file is provided:
+ *
+ * <pre>
+ *  {@code <host> <port> <username> <password> [<ldifFile>]}
+ * </pre>
+ */
+public final class ModifyAsync {
+    /** Connection to the LDAP server. */
+    private static Connection connection;
+    /** Result for the modify operation. */
+    private static int resultCode;
+    /** Count down latch to wait for modify operation to complete. */
+    private static final CountDownLatch COMPLETION_LATCH = new CountDownLatch(1);
+
+    /**
+     * Main method.
+     *
+     * @param args
+     *            The command line arguments: host, port, username, password,
+     *            LDIF file name containing the update operations.
+     *            Stdin is used if no LDIF file name is provided.
+     */
+    public static void main(final String[] args) {
+        if (args.length < 4 || args.length > 5) {
+            System.err.println("Usage: host port username password [ldifFileName]");
+            System.exit(1);
+        }
+
+        // Parse command line arguments.
+        final String hostName = args[0];
+        final int port = Integer.parseInt(args[1]);
+        final String userName = args[2];
+        final char[] password = args[3].toCharArray();
+
+        // Create the LDIF reader using either the named file, if provided, or stdin.
+        InputStream ldif;
+        if (args.length > 4) {
+            try {
+                ldif = new FileInputStream(args[4]);
+            } catch (final FileNotFoundException e) {
+                System.err.println(e.getMessage());
+                System.exit(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
+                return;
+            }
+        } else {
+            ldif = System.in;
+        }
+        final String[] ldifLines = getInputLines(ldif);
+
+        // Connect to the server, bind, and request the modifications.
+        new LDAPConnectionFactory(hostName, port)
+                .getConnectionAsync()
+                .thenAsync(new AsyncFunction<Connection, BindResult, LdapException>() {
+                    @Override
+                    public Promise<BindResult, LdapException> apply(Connection connection)
+                            throws LdapException {
+                        ModifyAsync.connection = connection;
+                        return connection.bindAsync(
+                                Requests.newSimpleBindRequest(userName, password));
+                    }
+                })
+                .thenAsync(new AsyncFunction<BindResult, Result, LdapException>() {
+                    @Override
+                    public Promise<Result, LdapException> apply(BindResult bindResult)
+                            throws LdapException {
+                        return connection.modifyAsync(
+                                Requests.newModifyRequest(ldifLines));
+                    }
+                })
+                .thenOnResult(new ResultHandler<Result>() {
+                    @Override
+                    public void handleResult(Result result) {
+                        resultCode = result.getResultCode().intValue();
+                        COMPLETION_LATCH.countDown();
+                    }
+                })
+                .thenOnException(new ExceptionHandler<LdapException>() {
+                    @Override
+                    public void handleException(LdapException e) {
+                        System.err.println(e.getMessage());
+                        resultCode = e.getResult().getResultCode().intValue();
+                        COMPLETION_LATCH.countDown();
+                    }
+                });
+
+        try {
+            COMPLETION_LATCH.await();
+        } catch (InterruptedException e) {
+            System.err.println(e.getMessage());
+            System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
+            return;
+        }
+
+        closeSilently(connection);
+        System.exit(resultCode);
+    }
+
+    /**
+     * Returns the lines from the input stream.
+     * @param in    The input stream.
+     * @return The lines from the input stream.
+     */
+    private static String[] getInputLines(final InputStream in) {
+        String line;
+        final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+        final List<String> lines = new ArrayList<>();
+        try {
+            while ((line = reader.readLine()) != null) {
+                lines.add(line);
+            }
+        } catch (IOException e) {
+            System.err.println(e.getMessage());
+            System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
+        }
+        return lines.toArray(new String[lines.size()]);
+    }
+
+    private ModifyAsync() {
+        // Not used.
+    }
+}
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/PasswordResetForAD.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/PasswordResetForAD.java
index 6e7a79d..3b75ce3 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/PasswordResetForAD.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/PasswordResetForAD.java
@@ -20,7 +20,7 @@
  *
  * CDDL HEADER END
  *
- *      Copyright 2013-2014 ForgeRock AS
+ *      Copyright 2013-2015 ForgeRock AS.
  *
  */
 
@@ -45,7 +45,7 @@
 /**
  * This command-line client demonstrates how to reset a user password in
  * Microsoft Active Directory.
- * <p>
+ * <br>
  * The client takes as arguments the host and port of the Active Directory
  * server, a flag indicating whether this is a self-reset (user changing own
  * password) or an administrative reset (administrator changing a password),
@@ -56,7 +56,7 @@
 
     /**
      * Reset a user password in Microsoft Active Directory.
-     * <p>
+     * <br>
      * The connection should be LDAPS, not LDAP, in order to perform the
      * modification.
      *
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Proxy.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Proxy.java
index c7da549..41c413f 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Proxy.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Proxy.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS
+ *      Portions Copyright 2011-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.examples;
@@ -57,8 +57,8 @@
  * This example takes the following command line parameters:
  *
  * <pre>
- *  &lt;listenAddress> &lt;listenPort> &lt;proxyDN> &ltproxyPassword> &lt;remoteAddress1> &lt;remotePort1>
- *      [&lt;remoteAddress2> &lt;remotePort2> ...]
+ *     {@code <listenAddress> <listenPort> <proxyDN> <proxyPassword> <remoteAddress1> <remotePort1>
+ *      [<remoteAddress2> <remotePort2> ...]}
  * </pre>
  */
 public final class Proxy {
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ProxyBackend.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ProxyBackend.java
index 56ad3af..b9dfdf9 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ProxyBackend.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ProxyBackend.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS
+ *      Portions Copyright 2011-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.examples;
@@ -78,15 +78,16 @@
  * client connection. The following code illustrates how this may be achieved:
  *
  * <pre>
- * final RequestHandlerFactory&lt;LDAPClientContext, RequestContext&gt; proxyFactory =
- *     new RequestHandlerFactory&lt;LDAPClientContext, RequestContext&gt;() {
- *         &#064;Override
+ *     {@code
+ * final RequestHandlerFactory<LDAPClientContext, RequestContext> proxyFactory =
+ *     new RequestHandlerFactory<LDAPClientContext, RequestContext>() {
+ *         @Override
  *         public ProxyBackend handleAccept(LDAPClientContext clientContext) throws LdapException {
  *             return new ProxyBackend(factory, bindFactory);
  *         }
  *     };
- * final ServerConnectionFactory&lt;LDAPClientContext, Integer&gt; connectionHandler = Connections
- *     .newServerConnectionFactory(proxyFactory);
+ * final ServerConnectionFactory<LDAPClientContext, Integer> connectionHandler = Connections
+ *     .newServerConnectionFactory(proxyFactory);}
  * </pre>
  */
 final class ProxyBackend implements RequestHandler<RequestContext> {
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ReadSchema.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ReadSchema.java
index a3c29f9..592b728 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ReadSchema.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ReadSchema.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2014 ForgeRock AS
+ *      Portions Copyright 2011-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.examples;
@@ -44,7 +44,7 @@
  * This example takes the following command line parameters:
  *
  * <pre>
- *  &lt;host> &lt;port> &lt;username> &lt;password>
+ *  {@code <host> <port> <username> <password>}
  * </pre>
  */
 public final class ReadSchema {
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/RewriterProxy.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/RewriterProxy.java
index 0f5a780..8efd1dc 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/RewriterProxy.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/RewriterProxy.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS
+ *      Portions Copyright 2011-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.examples;
@@ -98,7 +98,7 @@
  * This example takes the following command line parameters:
  *
  * <pre>
- *  &lt;localAddress> &lt;localPort> &lt;proxyDN> &lt;proxyPassword> &lt;serverAddress> &lt;serverPort>
+ *  {@code <localAddress> <localPort> <proxyDN> <proxyPassword> <serverAddress> <serverPort>}
  * </pre>
  *
  * If you have imported the users from <a
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SASLAuth.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SASLAuth.java
index 50ae094..7567ff8 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SASLAuth.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SASLAuth.java
@@ -21,7 +21,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2011-2014 ForgeRock AS
+ *      Copyright 2011-2015 ForgeRock AS.
  */
 
 /**
@@ -52,7 +52,7 @@
  * command line parameters:
  * <ul>
  * <li>host - host name of the directory server</li>
- * <li>port - port number of the directory server for StartTLS, e.g. 1389</li>
+ * <li>port - port number of the directory server for StartTLS</li>
  * <li>authzid - (Optional) Authorization identity</li>
  * <li>authcid - Authentication identity</li>
  * <li>passwd - Password of the user to authenticate</li>
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Search.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Search.java
index 9a70944..e4ff1f5 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Search.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Search.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2014 ForgeRock AS
+ *      Portions Copyright 2011-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.examples;
@@ -45,8 +45,8 @@
  * takes the following command line parameters:
  *
  * <pre>
- *  &lt;host> &lt;port> &lt;username> &lt;password>
- *      &lt;baseDN> &lt;scope> &lt;filter> [&lt;attibute> &lt;attribute> ...]
+ *  {@code <host> <port> <username> <password>
+ *      <baseDN> <scope> <filter> [<attribute> <attribute> ...]}
  * </pre>
  */
 public final class Search {
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchAsync.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchAsync.java
index 9825710..8ab1d6a 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchAsync.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchAsync.java
@@ -21,8 +21,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2014 ForgeRock AS
+ *      Copyright 2015 ForgeRock AS.
  */
 package org.forgerock.opendj.examples;
 
@@ -55,8 +54,8 @@
  * asynchronous APIs. This example takes the following command line parameters:
  *
  * <pre>
- *  &lt;host> &lt;port> &lt;username> &lt;password>
- *      &lt;baseDN> &lt;scope> &lt;filter> [&lt;attibute> &lt;attribute> ...]
+ *  {@code <host> <port> <username> <password>
+ *      <baseDN> <scope> <filter> [<attribute> <attribute> ...]}
  * </pre>
  */
 public final class SearchAsync {
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBind.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBind.java
index 67db44b..07ae6e8 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBind.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBind.java
@@ -20,7 +20,7 @@
  *
  * CDDL HEADER END
  *
- *      Copyright 2012-2014 ForgeRock AS
+ *      Copyright 2012-2015 ForgeRock AS.
  *
  */
 
@@ -44,7 +44,7 @@
  * entry.
  * <ul>
  * <li>host - host name of the directory server</li>
- * <li>port - port number of the directory server, e.g. 1389, 1636</li>
+ * <li>port - port number of the directory server</li>
  * <li>base-dn - base DN for the search, e.g. dc=example,dc=com</li>
  * </ul>
  * All arguments are required.
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBindAsync.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBindAsync.java
new file mode 100644
index 0000000..c226616
--- /dev/null
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SearchBindAsync.java
@@ -0,0 +1,183 @@
+/*
+ * 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 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 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 2015 ForgeRock AS.
+ *
+ */
+
+package org.forgerock.opendj.examples;
+
+import static org.forgerock.util.Utils.closeSilently;
+import org.forgerock.opendj.ldap.Connection;
+import org.forgerock.opendj.ldap.Filter;
+import org.forgerock.opendj.ldap.LDAPConnectionFactory;
+import org.forgerock.opendj.ldap.LdapException;
+import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.SearchScope;
+import org.forgerock.opendj.ldap.requests.Requests;
+import org.forgerock.opendj.ldap.responses.BindResult;
+import org.forgerock.opendj.ldap.responses.Result;
+import org.forgerock.opendj.ldap.responses.SearchResultEntry;
+import org.forgerock.util.AsyncFunction;
+import org.forgerock.util.promise.ExceptionHandler;
+import org.forgerock.util.promise.Promise;
+import org.forgerock.util.promise.ResultHandler;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * An interactive command-line client that performs a search and simple bind
+ * using the asynchronous APIs.
+ * <br>
+ * The client prompts for email address and for a password,
+ * and then searches based on the email address,
+ * to bind as the user with the password.
+ * <br>
+ * If successful, the client displays the common name from the user's entry.
+ * <ul>
+ * <li>host - host name of the directory server</li>
+ * <li>port - port number of the directory server</li>
+ * <li>base-dn - base DN for the search, e.g. dc=example,dc=com</li>
+ * </ul>
+ * All arguments are required.
+ */
+public final class SearchBindAsync {
+    /** Connection to the LDAP server. */
+    private static Connection connection;
+    /** Email address provided by user. */
+    private static String mail;
+    /** Password provided by user. */
+    private static char[] password;
+    /** Bind DN returned by the search. */
+    private static String bindDn;
+    /** Result for the operation. */
+    private static int resultCode;
+    /** Count down latch to wait for modify operation to complete. */
+    private static final CountDownLatch COMPLETION_LATCH = new CountDownLatch(1);
+
+    /**
+     * Prompts for email and password, search and bind, then display message.
+     *
+     * @param args
+     *            The command line arguments: host, port, base-dn.
+     */
+    public static void main(final String[] args) {
+        if (args.length != 3) {
+            System.err.println("Usage: host port base-dn");
+            System.err.println("For example: localhost 1389 dc=example,dc=com");
+            System.exit(1);
+        }
+        final String host   = args[0];
+        final int    port   = Integer.parseInt(args[1]);
+        final String baseDn = args[2];
+
+        // Prompt for email address and password.
+        try {
+            mail = getInputLine("Email address:");
+            password = getInputLine("Password:").toCharArray();
+        } catch (IOException e) {
+            System.err.println(e.getMessage());
+            System.exit(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
+            return;
+        }
+
+        // Connect to the server, search for the user entry based on email address, and bind.
+        new LDAPConnectionFactory(host, port)
+                .getConnectionAsync()
+                .thenAsync(new AsyncFunction<Connection, SearchResultEntry, LdapException>() {
+                    @Override
+                    public Promise<SearchResultEntry, LdapException> apply(Connection connection)
+                            throws LdapException {
+                        SearchBindAsync.connection = connection;
+                        return connection.searchSingleEntryAsync(
+                                Requests.newSingleEntrySearchRequest(
+                                        baseDn,
+                                        SearchScope.WHOLE_SUBTREE,
+                                        Filter.equality("mail", mail).toString(),
+                                        "cn"));
+                    }
+                })
+                .thenAsync(new AsyncFunction<SearchResultEntry, BindResult, LdapException>() {
+                    @Override
+                    public Promise<BindResult, LdapException> apply(SearchResultEntry searchResultEntry)
+                            throws LdapException {
+                        SearchBindAsync.bindDn = searchResultEntry.getName().toString();
+                        return SearchBindAsync.connection.bindAsync(
+                                Requests.newSimpleBindRequest(bindDn, password));
+                    }
+                })
+                .thenOnResult(new ResultHandler<Result>() {
+                    @Override
+                    public void handleResult(Result result) {
+                        if (result.getResultCode() == ResultCode.SUCCESS) {
+                            System.out.println("Authenticated as " + SearchBindAsync.bindDn + ".");
+                        }
+                        resultCode = result.getResultCode().intValue();
+                        COMPLETION_LATCH.countDown();
+                    }
+                })
+                .thenOnException(new ExceptionHandler<LdapException>() {
+                    @Override
+                    public void handleException(LdapException e) {
+                        System.err.println(e.getMessage());
+                        resultCode = e.getResult().getResultCode().intValue();
+                        COMPLETION_LATCH.countDown();
+                    }
+                });
+
+        try {
+            COMPLETION_LATCH.await();
+        }  catch (InterruptedException e) {
+            System.err.println(e.getMessage());
+            System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
+            return;
+        }
+
+        closeSilently(connection);
+        System.exit(resultCode);
+    }
+
+    /**
+     * Returns an input string from System.in, after prompting on System.out.
+     * <br>
+     * Note: The input is echoed to the display.
+     *
+     * @param prompt    The prompt asking for input.
+     * @return An input string from System.in.
+     * @throws IOException Failed to read from System.in.
+     */
+    private static String getInputLine(final String prompt) throws IOException {
+        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+        System.out.print(prompt + " ");
+        return reader.readLine();
+    }
+
+    /**
+     * Constructor not used.
+     */
+    private SearchBindAsync() {
+        // Not used
+    }
+}
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Server.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Server.java
index 746d594..64ef308 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Server.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Server.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2015 ForgeRock AS
+ *      Portions Copyright 2011-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.examples;
@@ -57,7 +57,7 @@
  * This example takes the following command line parameters:
  *
  * <pre>
- *  &lt;listenAddress> &lt;listenPort> &lt;ldifFile> [&lt;keyStoreFile> &lt;keyStorePassword> &lt;certNickname>]
+ *  {@code <listenAddress> <listenPort> <ldifFile> [<keyStoreFile> <keyStorePassword> <certNickname>]}
  * </pre>
  */
 public final class Server {
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLife.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLife.java
index 6c5d881..831ab65 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLife.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLife.java
@@ -20,7 +20,7 @@
  *
  * CDDL HEADER END
  *
- *      Copyright 2012-2014 ForgeRock AS
+ *      Copyright 2012-2015 ForgeRock AS.
  *
  */
 
@@ -49,7 +49,7 @@
  *
  * <ul>
  * <li>host - host name of the directory server</li>
- * <li>port - port number of the directory server, e.g. 1389, 1636</li>
+ * <li>port - port number of the directory server</li>
  * </ul>
  * All arguments are required.
  */
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLifeAsync.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLifeAsync.java
new file mode 100644
index 0000000..c0c82a3
--- /dev/null
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/ShortLifeAsync.java
@@ -0,0 +1,227 @@
+/*
+ * 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 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 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 2015 ForgeRock AS.
+ *
+ */
+
+package org.forgerock.opendj.examples;
+
+import static org.forgerock.util.Utils.closeSilently;
+import org.forgerock.opendj.ldap.Connection;
+import org.forgerock.opendj.ldap.Entries;
+import org.forgerock.opendj.ldap.Entry;
+import org.forgerock.opendj.ldap.LDAPConnectionFactory;
+import org.forgerock.opendj.ldap.LdapException;
+import org.forgerock.opendj.ldap.LinkedHashMapEntry;
+import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.TreeMapEntry;
+import org.forgerock.opendj.ldap.requests.ModifyRequest;
+import org.forgerock.opendj.ldap.requests.Requests;
+import org.forgerock.opendj.ldap.responses.BindResult;
+import org.forgerock.opendj.ldap.responses.Result;
+import org.forgerock.opendj.ldif.LDIFEntryWriter;
+import org.forgerock.util.AsyncFunction;
+import org.forgerock.util.promise.ExceptionHandler;
+import org.forgerock.util.promise.Promise;
+import org.forgerock.util.promise.ResultHandler;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * A command-line client that creates, updates, renames, and deletes a
+ * short-lived entry in order to demonstrate LDAP write operations
+ * using the asynchronous APIs.
+ * <br>
+ * The client takes as arguments the host and port for the directory server,
+ * and expects to find the entries and access control instructions as defined in
+ * <a href="http://opendj.forgerock.org/Example.ldif">Example.ldif</a>.
+ *
+ * <ul>
+ * <li>host - host name of the directory server</li>
+ * <li>port - port number of the directory server</li>
+ * </ul>
+ *
+ * All arguments are required.
+ */
+public final class ShortLifeAsync {
+    /** The short-lived entry. */
+    private static Entry entry;
+    /** Writer for displaying LDIF to System.out. */
+    private static LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
+    /** Connection to the LDAP server. */
+    private static Connection connection;
+    /** Result for the operation. */
+    private static int resultCode;
+    /** Count down latch to wait for modify operation to complete. */
+    private static final CountDownLatch COMPLETION_LATCH = new CountDownLatch(1);
+
+    /**
+     * Adds, modifies, renames, and deletes an entry.
+     *
+     * @param args
+     *            The command line arguments: host, port
+     */
+    public static void main(final String[] args) {
+        if (args.length != 2) {
+            System.err.println("Usage: host port");
+            System.err.println("For example: localhost 1389");
+            System.exit(1);
+        }
+        final String host = args[0];
+        final int    port = Integer.parseInt(args[1]);
+
+        // User credentials of a "Directory Administrators" group member.
+        // Kirsten Vaughan is authorized to create, update, and delete entries.
+        //
+        // Alternatively, prompt an administrator user for credentials,
+        // or get the application its own account with access to update data.
+        final String adminDn  = "uid=kvaughan,ou=people,dc=example,dc=com";
+        final char[] adminPwd = "bribery".toCharArray();
+
+        // Prepare an entry to add to the directory.
+        final String entryDn = "cn=Bob,ou=People,dc=example,dc=com";
+        entry = new LinkedHashMapEntry(entryDn)
+            .addAttribute("cn", "Bob")
+            .addAttribute("objectclass", "top")
+            .addAttribute("objectclass", "person")
+            .addAttribute("objectclass", "organizationalPerson")
+            .addAttribute("objectclass", "inetOrgPerson")
+            .addAttribute("mail", "subgenius@example.com")
+            .addAttribute("sn", "Dobbs");
+
+        new LDAPConnectionFactory(host, port)
+                .getConnectionAsync()
+                .thenAsync(new AsyncFunction<Connection, BindResult, LdapException>() {
+                    @Override
+                    public Promise<BindResult, LdapException> apply(Connection connection)
+                            throws LdapException {
+                        ShortLifeAsync.connection = connection;
+                        return connection.bindAsync(
+                                Requests.newSimpleBindRequest(adminDn, adminPwd));
+                    }
+                })
+                .thenAsync(new AsyncFunction<BindResult, Result, LdapException>() {
+                    @Override
+                    public Promise<Result, LdapException> apply(BindResult bindResult)
+                            throws LdapException {
+                        log("Adding the entry...");
+                        log(entry);
+                        return connection.addAsync(Requests.newAddRequest(entry));
+                    }
+                })
+                .thenAsync(new AsyncFunction<Result, Result, LdapException>() {
+                    @Override
+                    public Promise<Result, LdapException> apply(Result result)
+                            throws LdapException {
+                        Entry old = TreeMapEntry.deepCopyOfEntry(entry);
+                        entry = entry
+                                .replaceAttribute("mail", "spammer@example.com")
+                                .addAttribute("description", "Good user gone bad");
+                        log("Updating mail address, adding description...");
+                        log(entry);
+                        ModifyRequest request = Entries.diffEntries(old, entry);
+                        return connection.modifyAsync(request);
+                    }
+                })
+                .thenAsync(new AsyncFunction<Result, Result, LdapException>() {
+                    @Override
+                    public Promise<Result, LdapException> apply(Result result)
+                            throws LdapException {
+                        entry = entry.setName("cn=Renamed,ou=People,dc=example,dc=com");
+                        log("Renaming the entry...");
+                        log(entry);
+                        return connection.modifyDNAsync(
+                                Requests.newModifyDNRequest(entryDn, "cn=Renamed"));
+                    }
+                })
+                .thenAsync(new AsyncFunction<Result, Result, LdapException>() {
+                    @Override
+                    public Promise<Result, LdapException> apply(Result result)
+                            throws LdapException {
+                        final String newDn = entryDn.replace("Bob", "Renamed");
+                        log("Deleting " + newDn + "...");
+                        return connection.deleteAsync(
+                                Requests.newDeleteRequest(newDn));
+                    }
+                })
+                .thenOnResult(new ResultHandler<Result>() {
+                    @Override
+                    public void handleResult(Result result) {
+                        resultCode = result.getResultCode().intValue();
+                        log("... done.");
+                        COMPLETION_LATCH.countDown();
+                    }
+                })
+                .thenOnException(new ExceptionHandler<LdapException>() {
+                    @Override
+                    public void handleException(LdapException e) {
+                        System.err.println(e.getMessage());
+                        resultCode = e.getResult().getResultCode().intValue();
+                        COMPLETION_LATCH.countDown();
+                    }
+                });
+
+        try {
+            COMPLETION_LATCH.await();
+        }  catch (InterruptedException e) {
+            System.err.println(e.getMessage());
+            System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
+            return;
+        }
+
+        closeSilently(connection);
+        System.exit(resultCode);
+    }
+
+    /**
+     * Log a message to System.out.
+     *
+     * @param message   The message to write to the console.
+     */
+    private static void log(final String message) {
+        System.out.println(message);
+    }
+
+    /**
+     * Log an entry in LDIF form.
+     *
+     * @param entry     The entry to log.
+     */
+    private static void log(final Entry entry) {
+        try {
+            writer.writeEntry(entry);
+            writer.flush();
+        } catch (IOException e) {
+            System.err.println(e.getMessage());
+            System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
+        }
+    }
+
+    /**
+     * Constructor not used.
+     */
+    private ShortLifeAsync() {
+        // Not used.
+    }
+}
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SimpleAuthAsync.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SimpleAuthAsync.java
new file mode 100644
index 0000000..c82c3d6
--- /dev/null
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/SimpleAuthAsync.java
@@ -0,0 +1,268 @@
+/*
+ * 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 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 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 2015 ForgeRock AS.
+ */
+
+package org.forgerock.opendj.examples;
+
+import static org.forgerock.util.Utils.closeSilently;
+import org.forgerock.opendj.ldap.Connection;
+import org.forgerock.opendj.ldap.LDAPConnectionFactory;
+import org.forgerock.opendj.ldap.LDAPOptions;
+import org.forgerock.opendj.ldap.LdapException;
+import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.SSLContextBuilder;
+import org.forgerock.opendj.ldap.TrustManagers;
+import org.forgerock.opendj.ldap.requests.Requests;
+import org.forgerock.opendj.ldap.responses.BindResult;
+import org.forgerock.opendj.ldap.responses.Result;
+import org.forgerock.util.AsyncFunction;
+import org.forgerock.util.promise.ExceptionHandler;
+import org.forgerock.util.promise.Promise;
+import org.forgerock.util.promise.ResultHandler;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import java.io.File;
+import java.security.GeneralSecurityException;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * An example client application which performs simple authentication to a
+ * directory server using the asynchronous APIs.
+ * <br>
+ * This example takes the following command line parameters:
+ * <ul>
+ * <li>host - host name of the directory server</li>
+ * <li>port - port number of the directory server</li>
+ * <li>bind-dn - DN of the user to authenticate</li>
+ * <li>bind-password - Password of the user to authenticate</li>
+ * <li>use-starttls - (Optional) connect with StartTLS</li>
+ * <li>use-ssl - (Optional) connect over SSL</li>
+ * </ul>
+ * The host, port, bind-dn, and bind-password arguments are required.
+ * The use-starttls and use-ssl arguments are optional and mutually exclusive.
+ * <br>
+ * If the server certificate is self-signed,
+ * or otherwise not trusted out-of-the-box,
+ * then set the trust store by using the JSSE system property
+ * {@code -Djavax.net.ssl.trustStore=/path/to/opendj/config/keystore}
+ * and the trust store password if necessary by using the JSSE system property
+ * {@code -Djavax.net.ssl.trustStorePassword=`cat /path/to/opendj/config/keystore.pin`}.
+ */
+public final class SimpleAuthAsync {
+    /** Connection to the LDAP server. */
+    private static Connection connection;
+    /** Result for the modify operation. */
+    private static int resultCode;
+    /** Count down latch to wait for modify operation to complete. */
+    private static final CountDownLatch COMPLETION_LATCH = new CountDownLatch(1);
+
+    /**
+     * Authenticate to the directory either over LDAP, over LDAPS, or using
+     * StartTLS.
+     *
+     * @param args
+     *            The command line arguments
+     */
+    public static void main(final String[] args) {
+        parseArgs(args);
+
+        // Connect and bind.
+        // Pass getTrustAllOptions() instead of getTrustOptions()
+        // to the connection factory constructor
+        // if you want to trust all certificates blindly.
+        new LDAPConnectionFactory(host, port, getTrustOptions(host, keystore, storepass))
+                .getConnectionAsync()
+                .thenAsync(new AsyncFunction<Connection, BindResult, LdapException>() {
+                    @Override
+                    public Promise<BindResult, LdapException> apply(Connection connection)
+                            throws LdapException {
+                        SimpleAuthAsync.connection = connection;
+                        return connection.bindAsync(
+                                Requests.newSimpleBindRequest(bindDN, bindPassword.toCharArray()));
+                    }
+                })
+                .thenOnResult(new ResultHandler<Result>() {
+                    @Override
+                    public void handleResult(Result result) {
+                        resultCode = result.getResultCode().intValue();
+                        System.out.println("Authenticated as " + bindDN + ".");
+                        COMPLETION_LATCH.countDown();
+                    }
+                })
+                .thenOnException(new ExceptionHandler<LdapException>() {
+                    @Override
+                    public void handleException(LdapException e) {
+                        System.err.println(e.getMessage());
+                        resultCode = e.getResult().getResultCode().intValue();
+                        COMPLETION_LATCH.countDown();
+                    }
+                });
+
+        try {
+            COMPLETION_LATCH.await();
+        }  catch (InterruptedException e) {
+            System.err.println(e.getMessage());
+            System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
+            return;
+        }
+
+        closeSilently(connection);
+        System.exit(resultCode);
+    }
+
+    /**
+     * For StartTLS and SSL the connection factory needs SSL context options.
+     * In the general case, a trust manager in the SSL context serves
+     * to check server certificates, and a key manager handles client keys
+     * when the server checks certificates from our client.
+     * <br>
+     * This sample checks the server certificate,
+     * verifying that the certificate is currently valid,
+     * and that the host name of the server matches that of the certificate,
+     * based on a Java Key Store-format trust store.
+     * This sample does not present a client certificate.
+     *
+     * @param hostname      Host name expected in the server certificate
+     * @param truststore    Path to trust store file for the trust manager
+     * @param storepass     Password for the trust store
+     * @return SSL context options if SSL or StartTLS is used.
+     */
+    private static LDAPOptions getTrustOptions(final String hostname,
+                                               final String truststore,
+                                               final String storepass) {
+        LDAPOptions lo = new LDAPOptions();
+        if (useSSL || useStartTLS) {
+            TrustManager trustManager = null;
+            try {
+                trustManager = TrustManagers.checkValidityDates(
+                        TrustManagers.checkHostName(hostname,
+                                TrustManagers.checkUsingTrustStore(
+                                        truststore, storepass.toCharArray(), null)));
+                if (trustManager != null) {
+                    SSLContext sslContext = new SSLContextBuilder()
+                            .setTrustManager(trustManager).getSSLContext();
+                    lo.setSSLContext(sslContext);
+                }
+            } catch (Exception e) {
+                System.err.println(e.getMessage());
+                System.exit(ResultCode.CLIENT_SIDE_CONNECT_ERROR.intValue());
+            }
+            lo.setUseStartTLS(useStartTLS);
+        }
+        return lo;
+    }
+
+    /**
+     * For StartTLS and SSL the connection factory needs SSL context options. In
+     * the general case, a trust manager in the SSL context serves to check
+     * server certificates, and a key manager handles client keys when the
+     * server checks certificates from our client.
+     * <br>
+     * OpenDJ directory server lets you install by default with a self-signed
+     * certificate that is not in the system trust store. To simplify this
+     * implementation trusts all server certificates.
+     *
+     * @return SSL context options to trust all certificates without checking.
+     */
+    private static LDAPOptions getTrustAllOptions() {
+        LDAPOptions lo = new LDAPOptions();
+        try {
+            SSLContext sslContext =
+                    new SSLContextBuilder().setTrustManager(TrustManagers.trustAll())
+                            .getSSLContext();
+            lo.setSSLContext(sslContext);
+            lo.setUseStartTLS(useStartTLS);
+        } catch (GeneralSecurityException e) {
+            System.err.println(e.getMessage());
+            System.exit(ResultCode.CLIENT_SIDE_CONNECT_ERROR.intValue());
+        }
+        return lo;
+    }
+
+    private static String  host;
+    private static int     port;
+    private static String  bindDN;
+    private static String  bindPassword;
+    private static boolean useStartTLS;
+    private static boolean useSSL;
+    private static String  keystore;
+    private static String  storepass;
+
+    /**
+     * Parse command line arguments.
+     *
+     * @param args
+     *            host port bind-dn bind-password [ use-starttls | use-ssl ]
+     */
+    private static void parseArgs(String[] args) {
+        if (args.length < 4 || args.length > 5) {
+            giveUp();
+        }
+
+        host = args[0];
+        port = Integer.parseInt(args[1]);
+        bindDN = args[2];
+        bindPassword = args[3];
+
+        if (args.length == 5) {
+            if ("use-starttls".equals(args[4].toLowerCase())) {
+                useStartTLS = true;
+                useSSL = false;
+            } else if ("use-ssl".equals(args[4].toLowerCase())) {
+                useStartTLS = false;
+                useSSL = true;
+            } else {
+                giveUp();
+            }
+        }
+
+        keystore = System.getProperty("javax.net.ssl.trustStore");
+        storepass = System.getProperty("javax.net.ssl.trustStorePassword");
+        if (keystore == null) { // Try to use Java's cacerts trust store.
+            keystore = System.getProperty("java.home") + File.separator
+                    + "lib" + File.separator
+                    + "security" + File.separator
+                    + "cacerts";
+            storepass = "changeit"; // Default password
+        }
+    }
+
+    private static void giveUp() {
+        printUsage();
+        System.exit(1);
+    }
+
+    private static void printUsage() {
+        System.err.println("Usage: host port bind-dn bind-password [ use-starttls | use-ssl ]");
+        System.err.println("\thost, port, bind-dn, and bind-password arguments are required.");
+        System.err.println("\tuse-starttls and use-ssl are optional and mutually exclusive.");
+        System.err.println("\tOptionally set javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword.");
+    }
+
+    private SimpleAuthAsync() {
+        // Not used.
+    }
+}
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UpdateGroupAsync.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UpdateGroupAsync.java
new file mode 100644
index 0000000..0233413
--- /dev/null
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UpdateGroupAsync.java
@@ -0,0 +1,233 @@
+/*
+ * 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 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 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 2015 ForgeRock AS.
+ *
+ */
+
+package org.forgerock.opendj.examples;
+
+import static org.forgerock.util.Utils.closeSilently;
+import org.forgerock.opendj.ldap.Connection;
+import org.forgerock.opendj.ldap.LDAPConnectionFactory;
+import org.forgerock.opendj.ldap.LdapException;
+import org.forgerock.opendj.ldap.ModificationType;
+import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.RootDSE;
+import org.forgerock.opendj.ldap.controls.PermissiveModifyRequestControl;
+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.Responses;
+import org.forgerock.opendj.ldap.responses.Result;
+import org.forgerock.util.AsyncFunction;
+import org.forgerock.util.promise.ExceptionHandler;
+import org.forgerock.util.promise.Promise;
+import org.forgerock.util.promise.Promises;
+import org.forgerock.util.promise.ResultHandler;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * This command-line client demonstrates adding and removing a member from a
+ * (potentially large) static group using the asynchronous APIs.
+ *
+ * The client takes as arguments the host and port of the directory server, the
+ * group DN, the member DN, and whether to "add" or "del" the specified member
+ * from the group. The client uses the Permissive Modify control if it is
+ * available to avoid having to check whether the member belongs to the group or
+ * not.
+ *
+ * This client expects a group that is a <code>groupOfNames</code> such as:
+ *
+ * <pre>
+ * dn: cn=My Static Group,ou=Groups,dc=example,dc=com
+ * cn: My Static Group
+ * objectClass: groupOfNames
+ * objectClass: top
+ * ou: Groups
+ * member: uid=ahunter,ou=People,dc=example,dc=com
+ * member: uid=bjensen,ou=People,dc=example,dc=com
+ * member: uid=tmorris,ou=People,dc=example,dc=com
+ * </pre>
+ *
+ * This client connects as <code>cn=Directory Manager</code> with password
+ * <code>password</code>. Not a best practice; in real code use application
+ * specific credentials to connect, and ensure that your application has access
+ * to use the Permissive Modify control if your directory server supports it.
+ */
+public final class UpdateGroupAsync {
+    /** Connection to the LDAP server. */
+    private static Connection connection;
+    /** Result for the operation. */
+    private static int resultCode;
+    /** Count down latch to wait for modify operation to complete. */
+    private static final CountDownLatch COMPLETION_LATCH = new CountDownLatch(1);
+
+    /**
+     * Updates the group as necessary.
+     *
+     * @param args
+     *            The command line arguments: host, port, group-dn, member-dn, (add|del)
+     */
+    public static void main(String[] args) {
+        if (args.length != 5) {
+            printUsage();
+        }
+        final String host              = args[0];
+        final int port                 = Integer.parseInt(args[1]);
+        final String groupDn           = args[2];
+        final String memberDn          = args[3];
+        final ModificationType modType = getModificationType(args[4]);
+
+        // Connect, bind, update group.
+        new LDAPConnectionFactory(host, port)
+                .getConnectionAsync()
+                .thenAsync(new AsyncFunction<Connection, BindResult, LdapException>() {
+                    @Override
+                    public Promise<BindResult, LdapException> apply(Connection connection)
+                            throws LdapException {
+                        UpdateGroupAsync.connection = connection;
+                        return connection.bindAsync(
+                                Requests.newSimpleBindRequest("cn=Directory Manager", "password".toCharArray()));
+                    }
+                })
+                .thenAsync(new AsyncFunction<BindResult, RootDSE, LdapException>() {
+                    @Override
+                    public Promise<RootDSE, LdapException> apply(BindResult bindResult)
+                            throws LdapException {
+                        return RootDSE.readRootDSEAsync(connection, null);
+                    }
+                })
+                .thenAsync(new AsyncFunction<RootDSE, Result, LdapException>() {
+                    @Override
+                    public Promise<Result, LdapException> apply(RootDSE rootDSE) throws LdapException {
+                        // If the directory supports the Permissive Modify request control,
+                        // then the modification type does not matter.
+                        if (rootDSE.getSupportedControls().contains(PermissiveModifyRequestControl.OID)) {
+                            log("Updating group membership.");
+                            return connection.modifyAsync(
+                                    Requests.newModifyRequest(groupDn)
+                                            .addControl(PermissiveModifyRequestControl.newControl(true))
+                                            .addModification(modType, "member", memberDn));
+                        } else {
+                            return connection
+                                    // Check whether the member is present.
+                                    .compareAsync(Requests.newCompareRequest(groupDn, "member", memberDn))
+                                    .thenAsync(new AsyncFunction<CompareResult, Result, LdapException>() {
+                                        @Override
+                                        public Promise<Result, LdapException> apply(CompareResult compareResult)
+                                                throws LdapException {
+                                            ResultCode rc = compareResult.getResultCode();
+                                            // Only add the member if missing from the group.
+                                            if (modType.equals(ModificationType.ADD)
+                                                    && rc.equals(ResultCode.COMPARE_FALSE)) {
+                                                log("Adding " + memberDn + " to " + groupDn + ".");
+                                                return connection.modifyAsync(
+                                                        Requests.newModifyRequest(groupDn)
+                                                                .addModification(modType, "member", memberDn));
+                                            // Only delete if present in the group.
+                                            } else if (modType.equals(ModificationType.DELETE)
+                                                    && rc.equals(ResultCode.COMPARE_TRUE)) {
+                                                log("Deleting " + memberDn + " from " + groupDn + ".");
+                                                return connection.modifyAsync(
+                                                        Requests.newModifyRequest(groupDn)
+                                                                .addModification(modType, "member", memberDn));
+                                            } else {
+                                                return Promises.newResultPromise(
+                                                        Responses.newResult(ResultCode.SUCCESS));
+                                            }
+                                        }
+                                    });
+                        }
+                    }
+                })
+                .thenOnResult(new ResultHandler<Result>() {
+                    @Override
+                    public void handleResult(Result result) {
+                        final String op = (modType == ModificationType.ADD) ? "added to" : "deleted from";
+                        log(memberDn + " has been " + op + " the group " + groupDn + ".");
+                        resultCode = result.getResultCode().intValue();
+                        COMPLETION_LATCH.countDown();
+                    }
+                })
+                .thenOnException(new ExceptionHandler<LdapException>() {
+                    @Override
+                    public void handleException(LdapException e) {
+                        System.err.println(e.getMessage());
+                        resultCode = e.getResult().getResultCode().intValue();
+                        COMPLETION_LATCH.countDown();
+                    }
+                });
+
+        try {
+            COMPLETION_LATCH.await();
+        } catch (InterruptedException e) {
+            System.err.println(e.getMessage());
+            System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
+            return;
+        }
+
+        closeSilently(connection);
+        System.exit(resultCode);
+    }
+
+    /**
+     * Print usage then exit.
+     */
+    private static void printUsage() {
+        System.err.println("Usage: host port group-dn member-dn {add|del}");
+        System.err.println("For example: localhost 1389 "
+                + "cn=Static,ou=Groups,dc=example,dc=com "
+                + "uid=user.5150,ou=People,dc=example,dc=com "
+                + "del");
+        System.exit(1);
+    }
+
+    /**
+     * Return the modification type for the update operation.
+     * @param operation Operation specified as an argument (add or del).
+     */
+    private static ModificationType getModificationType(String operation) {
+        final boolean isAdd = "add".equalsIgnoreCase(operation);
+        if (!isAdd && !"del".equalsIgnoreCase(operation)) {
+            printUsage();
+        }
+        return isAdd ? ModificationType.ADD : ModificationType.DELETE;
+    }
+
+    /**
+     * Log a message to System.out.
+     *
+     * @param message   The message to write to the console.
+     */
+    private static void log(final String message) {
+        System.out.println(message);
+    }
+
+    /**
+     * Constructor not used.
+     */
+    private UpdateGroupAsync() {
+        // Not used.
+    }
+}
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseGenericControl.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseGenericControl.java
index 2ccdf53..be5993d 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseGenericControl.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseGenericControl.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2014 ForgeRock AS
+ *      Portions Copyright 2011-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.examples;
@@ -54,14 +54,14 @@
  * pre-read request control from <a href="http://tools.ietf.org/html/rfc4527"
  * >RFC 4527 - Lightweight Directory Access Protocol (LDAP) Read Entry Controls</a>.
  *
- * <p>This example takes the following command line parameters:
+ * <br>This example takes the following command line parameters:
  *
  * <pre>
- *  &lt;host> &lt;port> &lt;username> &lt;password> &lt;userDN>
+ *  {@code <host> <port> <username> <password> <userDN>}
  * </pre>
  *
- * <p>This example modifies the description attribute of an entry that
- * you specify in the &lt;userDN> command line parameter.
+ * <br>This example modifies the description attribute of an entry that
+ * you specify in the {@code <userDN>} command line parameter.
  */
 public final class UseGenericControl {
     /**
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchema.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchema.java
index b25a370..e9563b1 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchema.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchema.java
@@ -53,7 +53,7 @@
  * This example takes the following command line parameters:
  *
  * <pre>
- *  &lt;host> &lt;port> &lt;bindDN> &lt;bindPassword>
+ *  {@code <host> <port> <bindDN> <bindPassword>}
  * </pre>
  *
  * Then it reads an entry to add from System.in.
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchemaAsync.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchemaAsync.java
new file mode 100644
index 0000000..6666da9
--- /dev/null
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseSchemaAsync.java
@@ -0,0 +1,183 @@
+/*
+ * 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 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 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 2015 ForgeRock AS.
+ */
+
+package org.forgerock.opendj.examples;
+
+import static org.forgerock.util.Utils.closeSilently;
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.opendj.ldap.Connection;
+import org.forgerock.opendj.ldap.DN;
+import org.forgerock.opendj.ldap.Entry;
+import org.forgerock.opendj.ldap.LDAPConnectionFactory;
+import org.forgerock.opendj.ldap.LdapException;
+import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.requests.Requests;
+import org.forgerock.opendj.ldap.responses.BindResult;
+import org.forgerock.opendj.ldap.responses.Result;
+import org.forgerock.opendj.ldap.schema.Schema;
+import org.forgerock.opendj.ldap.schema.SchemaValidationPolicy;
+import org.forgerock.opendj.ldif.LDIFEntryReader;
+import org.forgerock.util.AsyncFunction;
+import org.forgerock.util.promise.ExceptionHandler;
+import org.forgerock.util.promise.Promise;
+import org.forgerock.util.promise.Promises;
+import org.forgerock.util.promise.ResultHandler;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * This example command-line client application validates an entry
+ * against the directory server schema before adding it
+ * using the asynchronous APIs.
+ *
+ * <br>
+ *
+ * This example takes the following command line parameters:
+ *
+ * <pre>
+ *  {@code <host> <port> <bindDN> <bindPassword>}
+ * </pre>
+ *
+ * Then it reads an entry to add from System.in.
+ * If the entry is valid according to the directory schema,
+ * it tries to add the entry to the directory.
+ */
+public final class UseSchemaAsync {
+    /** Connection to the LDAP server. */
+    private static Connection connection;
+    /** Result for the operation. */
+    private static int resultCode;
+    /** Count down latch to wait for modify operation to complete. */
+    private static final CountDownLatch COMPLETION_LATCH = new CountDownLatch(1);
+
+    /**
+     * Main method.
+     *
+     * @param args
+     *            The command line arguments: host, port, bindDN, bindPassword.
+     */
+    public static void main(final String[] args) {
+        if (args.length != 4) {
+            System.err.println("Usage: host port bindDN bindPassword");
+            System.exit(1);
+        }
+
+        // Parse command line arguments.
+        final String host         = args[0];
+        final int    port         = Integer.parseInt(args[1]);
+        final String bindDn       = args[2];
+        final char[] bindPassword = args[3].toCharArray();
+
+        // Read an entry from System.in.
+        final Entry entry;
+        try {
+            System.out.println("Enter entry to add in LDIF format:");
+            entry = new LDIFEntryReader(System.in).readEntry();
+        } catch (IOException e) {
+            System.err.println(e.getMessage());
+            System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
+            return;
+        }
+        final String entryDn = entry.getName().toString();
+
+        // Connect, bind, read schema, and add entry if valid according to schema.
+        new LDAPConnectionFactory(host, port)
+                .getConnectionAsync()
+                .thenAsync(new AsyncFunction<Connection, BindResult, LdapException>() {
+                    @Override
+                    public Promise<BindResult, LdapException> apply(Connection connection)
+                            throws LdapException {
+                        UseSchemaAsync.connection = connection;
+                        return connection.bindAsync(
+                                Requests.newSimpleBindRequest(bindDn, bindPassword));
+                    }
+                })
+                .thenAsync(new AsyncFunction<BindResult, Schema, LdapException>() {
+                    @Override
+                    public Promise<Schema, LdapException> apply(BindResult bindResult)
+                            throws LdapException {
+                        return Schema.readSchemaForEntryAsync(connection, DN.rootDN());
+                    }
+                })
+                .thenAsync(new AsyncFunction<Schema, Result, LdapException>() {
+                    @Override
+                    public Promise<Result, LdapException> apply(Schema schema)
+                            throws LdapException {
+                        final List<LocalizableMessage> schemaErrors = new LinkedList<>();
+                        boolean isValid = schema.validateEntry(
+                                entry,
+                                SchemaValidationPolicy.defaultPolicy(),
+                                schemaErrors);
+                        if (isValid) {
+                            System.out.println("Processing ADD request for " + entryDn);
+                            return connection.addAsync(Requests.newAddRequest(entry));
+                        } else {
+                            for (LocalizableMessage error : schemaErrors) {
+                                System.err.println(error);
+                            }
+                            return Promises.newExceptionPromise(
+                                    LdapException.newLdapException(
+                                            ResultCode.CLIENT_SIDE_PARAM_ERROR,
+                                            "Entry does not conform to schema."));
+                        }
+                    }
+                })
+                .thenOnResult(new ResultHandler<Result>() {
+                    @Override
+                    public void handleResult(Result result) {
+                        System.out.println("ADD operation successful for DN " + entryDn);
+                        resultCode = result.getResultCode().intValue();
+                        COMPLETION_LATCH.countDown();
+                    }
+                })
+                .thenOnException(new ExceptionHandler<LdapException>() {
+                    @Override
+                    public void handleException(LdapException e) {
+                        System.err.println(e.getMessage());
+                        resultCode = e.getResult().getResultCode().intValue();
+                        COMPLETION_LATCH.countDown();
+                    }
+                });
+
+        try {
+            COMPLETION_LATCH.await();
+        }  catch (InterruptedException e) {
+            System.err.println(e.getMessage());
+            System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
+            return;
+        }
+
+        closeSilently(connection);
+        System.exit(resultCode);
+    }
+
+    private UseSchemaAsync() {
+        // Not used.
+    }
+}
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/site/xdoc/index.xml.vm b/opendj-sdk/opendj-ldap-sdk-examples/src/site/xdoc/index.xml.vm
index 70b7509..4f8a072 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/site/xdoc/index.xml.vm
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/site/xdoc/index.xml.vm
@@ -31,7 +31,12 @@
   <body>
     <section name="About ${project.name}">
       <p>This module contains example LDAP applications implemented using the
-        OpenDJ LDAP SDK:</p>
+        OpenDJ LDAP SDK.</p>
+
+      <p>
+        The following examples use the synchronous APIs:
+      </p>
+
       <ul>
         <li>
           <a href="xref/org/forgerock/opendj/examples/Search.html">LDAP search</a>
@@ -39,11 +44,6 @@
           synchronous APIs
         </li>
         <li>
-          <a href="xref/org/forgerock/opendj/examples/SearchAsync.html">LDAP asynchronous search</a>
-          - illustrates how to perform an LDAP search operation using the
-          asynchronous APIs
-        </li>
-        <li>
           <a href="xref/org/forgerock/opendj/examples/Modify.html">LDAP modify</a>
           - illustrates how to perform an LDAP modify operation using the
           synchronous APIs
@@ -53,12 +53,8 @@
           - illustrates how to implement a very simple LDAP server
         </li>
         <li>
-          <a href="xref/org/forgerock/opendj/examples/Proxy.html">LDAP proxy</a>
-          - illustrates how to implement a very simple LDAP proxy
-        </li>
-        <li>
           <a href="xref/org/forgerock/opendj/examples/SimpleAuth.html">LDAP bind</a>
-          - illustrates how to bind to an LDAP server
+          - illustrates how to bind to an LDAP server using the synchronous APIs
         </li>
         <li>
           <a href="xref/org/forgerock/opendj/examples/SASLAuth.html">LDAP SASL bind</a>
@@ -79,14 +75,17 @@
         <li>
           <a href="xref/org/forgerock/opendj/examples/SearchBind.html">Search &amp; bind</a>
           - illustrates how to authenticate given a mail address and a password
+          using the synchronous APIs
         </li>
         <li>
           <a href="xref/org/forgerock/opendj/examples/ShortLife.html">Short life</a>
           - illustrates how to create, update, rename, and delete an entry
+          using the synchronous APIs
         </li>
         <li>
           <a href="xref/org/forgerock/opendj/examples/UseSchema.html">Use LDAP Schema</a>
           - illustrates how to validate an entry using the directory server LDAP schema
+          using the synchronous APIs
         </li>
         <li>
           <a href="xref/org/forgerock/opendj/examples/Controls.html">Use LDAP Controls</a>
@@ -98,12 +97,9 @@
           operations
         </li>
         <li>
-          <a href="xref/org/forgerock/opendj/examples/RewriterProxy.html">Rewrite proxy</a>
-          - illustrates how to rewrite DNs and attribute names in a proxy layer
-        </li>
-        <li>
           <a href="xref/org/forgerock/opendj/examples/UpdateGroup.html">Update group</a>
           - illustrates how to add or remove a member from a static group
+          using the synchronous APIs
         </li>
         <li>
           <a href="xref/org/forgerock/opendj/examples/UseGenericControl.html">Use <code>GenericControl</code></a>
@@ -119,6 +115,55 @@
             or change the password as the user
         </li>
       </ul>
+
+      <p>
+        The following examples use the asynchronous APIs:
+      </p>
+
+      <ul>
+        <li>
+          <a href="xref/org/forgerock/opendj/examples/SearchAsync.html">LDAP search (async)</a>
+          - illustrates how to perform an LDAP search operation using the
+          asynchronous APIs
+        </li>
+        <li>
+          <a href="xref/org/forgerock/opendj/examples/ModifyAsync.html">LDAP modify (async)</a>
+          - illustrates how to perform an LDAP modify operation using the
+          asynchronous APIs
+        </li>
+        <li>
+          <a href="xref/org/forgerock/opendj/examples/Proxy.html">LDAP proxy</a>
+          - illustrates how to implement a very simple LDAP proxy
+        </li>
+        <li>
+          <a href="xref/org/forgerock/opendj/examples/SimpleAuthAsync.html">LDAP bind (async)</a>
+          - illustrates how to bind to an LDAP server using the asynchronous APIs
+        </li>
+        <li>
+          <a href="xref/org/forgerock/opendj/examples/SearchBindAsync.html">Search &amp; bind (async)</a>
+          - illustrates how to authenticate given a mail address and a password
+          using the asynchronous APIs
+        </li>
+        <li>
+          <a href="xref/org/forgerock/opendj/examples/ShortLifeAsync.html">Short life (async)</a>
+          - illustrates how to create, update, rename, and delete an entry
+          using the asynchronous APIs
+        </li>
+        <li>
+          <a href="xref/org/forgerock/opendj/examples/UseSchemaAsync.html">Use LDAP Schema (async)</a>
+          - illustrates how to validate an entry using the directory server LDAP schema
+          using the asynchronous APIs
+        </li>
+        <li>
+          <a href="xref/org/forgerock/opendj/examples/RewriterProxy.html">Rewrite proxy</a>
+          - illustrates how to rewrite DNs and attribute names in a proxy layer
+        </li>
+        <li>
+          <a href="xref/org/forgerock/opendj/examples/UpdateGroupAsync.html">Update group (async)</a>
+          - illustrates how to add or remove a member from a static group
+          using the asynchronous APIs
+        </li>
+      </ul>
     </section>
     <section name="Documentation for ${project.name}">
       <p>

--
Gitblit v1.10.0