From 89debdc4f4f38e0d973c9f4f37e1c34002deeeb4 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Tue, 22 May 2007 14:35:47 +0000
Subject: [PATCH] Various improvements and refactorings of the admin framework client API, including:

---
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfg.java                               |   21 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthenticationException.java                                      |   90 
 opendj-sdk/opends/resource/admin/metaMO.xsl                                                                                   |   84 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java                                   |  109 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java                            |  251 ++
 opendj-sdk/opends/src/server/org/opends/server/admin/ManagedObjectAlreadyExistsException.java                                 |   27 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgClient.java                          |   22 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthenticationNotSupportedException.java                          |   91 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/OperationRejectedException.java                                   |   94 +
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/IntegerPropertyDefinitionTest.java               |    2 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockLDAPConnection.java              |  358 +++
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/CreateEntryMockLDAPConnection.java   |  137 +
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfg.java                                |   10 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java                                   |  239 ++
 opendj-sdk/opends/src/server/org/opends/server/admin/client/AdminClientException.java                                         |   99 +
 opendj-sdk/opends/src/server/org/opends/server/admin/client/ConcurrentModificationException.java                              |   95 +
 opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthorizationException.java                                       |   91 
 opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java                                           |   98 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/CommunicationException.java                                       |   92 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java                           |  391 ++++
 opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java                                          |  140 +
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/SizePropertyDefinitionTest.java                  |    2 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/AdminSecurityException.java                                       |   84 
 opendj-sdk/opends/resource/admin/clientMO.xsl                                                                                 |  351 ++-
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java                             |   35 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java                                         |   37 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/ModifyEntryMockLDAPConnection.java   |  139 +
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationPropertyDefinitionTest.java              |    2 
 /dev/null                                                                                                                     |   65 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/ExampleClient.java                                                |   11 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/LDAPClientTest.java                  |  625 ++++++
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DNBuilderTest.java                        |    7 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/DeleteSubtreeMockLDAPConnection.java |   87 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgClient.java                         |  214 ++
 opendj-sdk/opends/src/server/org/opends/server/admin/LDAPProfile.java                                                         |   26 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/InitialManagedObject.java                                         |   39 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java                                       |  610 +++---
 opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagedObject.java                                                |  457 +++-
 opendj-sdk/opends/resource/admin/java-utilities.xsl                                                                           |  148 +
 opendj-sdk/opends/src/server/org/opends/server/admin/ConfigurationClient.java                                                 |   25 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockPropertyProvider.java            |  111 +
 41 files changed, 4,778 insertions(+), 838 deletions(-)

diff --git a/opendj-sdk/opends/resource/admin/clientMO.xsl b/opendj-sdk/opends/resource/admin/clientMO.xsl
index bfaf653..3db6324 100644
--- a/opendj-sdk/opends/resource/admin/clientMO.xsl
+++ b/opendj-sdk/opends/resource/admin/clientMO.xsl
@@ -97,84 +97,138 @@
     </xsl:variable>
     <xsl:choose>
       <xsl:when test="adm:one-to-one">
+        <xsl:call-template name="add-java-comment2">
+          <xsl:with-param name="indent" select="2" />
+          <xsl:with-param name="content"
+            select="concat(
+                       'Gets the ', $ufn,'.&#xa;',
+                       '&#xa;',
+                       '@return Returns the ', $ufn,'.&#xa;',
+                       '@throws DefinitionDecodingException&#xa;',
+                       '          If the ', $ufn, ' was found but its type could not be determined.&#xa;',
+                       '@throws ManagedObjectDecodingException&#xa;',
+                       '          If the ', $ufn, ' was found but one or more of its properties could not be decoded.&#xa;',
+                       '@throws ManagedObjectNotFoundException&#xa;',
+                       '          If the ', $ufn, ' could not be found on the server.&#xa;',
+                       '@throws ConcurrentModificationException&#xa;',
+                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
+                       '@throws AuthorizationException&#xa;',
+                       '          If the server refuses to retrieve the ', $ufn, ' because the client does not have the correct privileges.&#xa;',
+                       '@throws CommunicationException&#xa;',
+                       '          If the client cannot contact the server due to an underlying communication problem.')" />
+        </xsl:call-template>
         <xsl:value-of
-          select="concat('  /**&#xa;',
-                       '   * Gets the ', $ufn,'.&#xa;',
-                       '   *&#xa;',
-                       '   * @return Returns the ', $ufn,'.&#xa;',
-                       '   * @throws OperationsException&#xa;',
-                       '   *           If the ', $ufn,' could not be read due to some&#xa;',
-                       '   *           underlying communication problem.&#xa;',
-                       '   */&#xa;')" />
-        <xsl:value-of
-          select="concat('  ', $java-class-name, 'CfgClient get',
-                       $java-relation-name, '() throws OperationsException;&#xa;')" />
+          select="concat('  ', $java-class-name, 'CfgClient get', $java-relation-name, '()&#xa;',
+                       '      throws DefinitionDecodingException, ManagedObjectDecodingException,&#xa;',
+                       '      ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
+                       '      AuthorizationException, CommunicationException;&#xa;')" />
       </xsl:when>
       <xsl:when test="adm:one-to-zero-or-one">
-        <xsl:value-of
-          select="concat('  /**&#xa;',
-                       '   * Determines whether or not the ', $ufn,' exists.&#xa;',
-                       '   *&#xa;',
-                       '   * @return Returns &lt;true&gt; if the ', $ufn,' exists.&#xa;',
-                       '   * @throws OperationsException&#xa;',
-                       '   *           If the determination could not be made&#xa;',
-                       '   *           due to some underlying communication problem.&#xa;',
-                       '   */&#xa;')" />
+        <xsl:call-template name="add-java-comment2">
+          <xsl:with-param name="indent" select="2" />
+          <xsl:with-param name="content"
+            select="concat('Determines whether or not the ', $ufn,' exists.&#xa;',
+                       '&#xa;',
+                       '@return Returns &lt;true&gt; if the ', $ufn,' exists.&#xa;',
+                       '@throws ConcurrentModificationException&#xa;',
+                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
+                       '@throws AuthorizationException&#xa;',
+                       '          If the server refuses to make the determination because the client does not have the correct privileges.&#xa;',
+                       '@throws CommunicationException&#xa;',
+                       '          If the client cannot contact the server due to an underlying communication problem.')" />
+        </xsl:call-template>
         <xsl:value-of
           select="concat('  boolean has',
-                       $java-relation-name, '() throws OperationsException;&#xa;')" />
+                       $java-relation-name, '() throws ConcurrentModificationException,&#xa;',
+                       '      AuthorizationException, CommunicationException;&#xa;')" />
         <xsl:text>&#xa;</xsl:text>
         <xsl:text>&#xa;</xsl:text>
         <xsl:text>&#xa;</xsl:text>
+        <xsl:call-template name="add-java-comment2">
+          <xsl:with-param name="indent" select="2" />
+          <xsl:with-param name="content"
+            select="concat(
+                       'Gets the ', $ufn,' if it is present.&#xa;',
+                       '&#xa;',
+                       '@return Returns the ', $ufn, ' if it is present.&#xa;',
+                       '@throws DefinitionDecodingException&#xa;',
+                       '          If the ', $ufn, ' was found but its type could not be determined.&#xa;',
+                       '@throws ManagedObjectDecodingException&#xa;',
+                       '          If the ', $ufn, ' was found but one or more of its properties could not be decoded.&#xa;',
+                       '@throws ManagedObjectNotFoundException&#xa;',
+                       '          If the ', $ufn, ' is not present.&#xa;',
+                       '@throws ConcurrentModificationException&#xa;',
+                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
+                       '@throws AuthorizationException&#xa;',
+                       '          If the server refuses to retrieve the ', $ufn, ' because the client does not have the correct privileges.&#xa;',
+                       '@throws CommunicationException&#xa;',
+                       '          If the client cannot contact the server due to an underlying communication problem.')" />
+        </xsl:call-template>
         <xsl:value-of
-          select="concat('  /**&#xa;',
-                       '   * Gets the ', $ufn,' if it is present.&#xa;',
-                       '   *&#xa;',
-                       '   * @return Returns the ', $ufn,' if it is present.&#xa;',
-                       '   * @throws OperationsException&#xa;',
-                       '   *           If the ', $ufn,' does not exist or could not be read&#xa;',
-                       '   *           due to some underlying communication problem.&#xa;',
-                       '   */&#xa;')" />
-        <xsl:value-of
-          select="concat('  ', $java-class-name, 'CfgClient get',
-                       $java-relation-name, '() throws OperationsException;&#xa;')" />
+          select="concat('  ', $java-class-name, 'CfgClient get', $java-relation-name, '()&#xa;',
+                       '      throws DefinitionDecodingException, ManagedObjectDecodingException,&#xa;',
+                       '      ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
+                       '      AuthorizationException, CommunicationException;&#xa;')" />
         <xsl:text>&#xa;</xsl:text>
         <xsl:text>&#xa;</xsl:text>
         <xsl:text>&#xa;</xsl:text>
-        <xsl:value-of
-          select="concat('  /**&#xa;',
-                       '   * Creates the ', $ufn,' if it does not exist yet.&#xa;',
-                       '   *&#xa;',
-                       '   * @param &lt;C&gt;&#xa;',
-                       '   *          The type of the ', $ufn,' being added.&#xa;',
-                       '   * @param d&#xa;',
-                       '   *          The definition of the ', $ufn,' to be created.&#xa;',
-                       '   * @param p&#xa;',
-                       '   *          A property provider which can be used to initialize&#xa;',
-                       '   *          the property values of the new ', $ufn,'.&#xa;',
-                       '   * @return Returns the ', $ufn,' instance representing the&#xa;',
-                       '   *         ', $ufn,' that was created.&#xa;',
-                       '   * @throws OperationsException&#xa;',
-                       '   *           If the ', $ufn,' already exists or could not be created&#xa;',
-                       '   *           due to some underlying communication problem.&#xa;',
-                       '   */&#xa;')" />
+        <xsl:call-template name="add-java-comment2">
+          <xsl:with-param name="indent" select="2" />
+          <xsl:with-param name="content"
+            select="concat(
+                       'Creates the ', $ufn,' if it does not exist yet.&#xa;',
+                       '&#xa;',
+                       '@param &lt;C&gt;&#xa;',
+                       '         The type of the ', $ufn,' being added.&#xa;',
+                       '@param d&#xa;',
+                       '         The definition of the ', $ufn,' to be created.&#xa;',
+                       '@param p&#xa;',
+                       '         A property provider which can be used to initialize the property values of the new ', $ufn,'.&#xa;',
+                       '@return Returns the ', $ufn,' instance representing the ', $ufn,' that was created.&#xa;',
+                       '@throws ManagedObjectDecodingException&#xa;',
+                       '          If the ', $ufn,' could not be created because one or more of its properties are invalid.&#xa;',
+                       '@throws ManagedObjectAlreadyExistsException&#xa;',
+                       '          If the ', $ufn,' cannot be created because it already exists on the server.&#xa;',
+                       '@throws ConcurrentModificationException&#xa;',
+                       '          If this ', $ufn,' has been removed from the server by another client.&#xa;',
+                       '@throws OperationRejectedException&#xa;',
+                       '          If the server refuses to create the ', $ufn,' due to some server-side constraint which cannot be satisfied.&#xa;',
+                       '@throws AuthorizationException&#xa;',
+                       '          If the server refuses to create the ', $ufn,' because the client does not have the correct privileges.&#xa;',
+                       '@throws CommunicationException&#xa;',
+                       '          If the client cannot contact the server due to an underlying communication problem.&#xa;')" />
+        </xsl:call-template>
         <xsl:value-of
           select="concat('  &lt;C extends ', $java-class-name,'CfgClient&gt; C create', $java-relation-name, '(&#xa;',
-                           '      ManagedObjectDefinition&lt;C, ?&gt; d, PropertyProvider p) throws OperationsException;&#xa;')" />
+                           '      ManagedObjectDefinition&lt;C, ?&gt; d, PropertyProvider p)&#xa;',
+                           '      throws ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,&#xa;',
+                           '      ConcurrentModificationException, OperationRejectedException,&#xa;',
+                           '      AuthorizationException, CommunicationException;&#xa;')" />
         <xsl:text>&#xa;</xsl:text>
         <xsl:text>&#xa;</xsl:text>
         <xsl:text>&#xa;</xsl:text>
+        <xsl:call-template name="add-java-comment2">
+          <xsl:with-param name="indent" select="2" />
+          <xsl:with-param name="content"
+            select="concat(
+                       'Removes the ', $ufn,' if it exists.&#xa;',
+                       '&#xa;',
+                       '@throws ManagedObjectNotFoundException&#xa;',
+                       '          If the ', $ufn, ' does not exist.&#xa;',
+                       '@throws OperationRejectedException&#xa;',
+                       '          If the server refuses to remove the ', $ufn, ' due to some server-side constraint which cannot be satisfied (for example, if it is referenced by another managed object).&#xa;',
+                       '@throws ConcurrentModificationException&#xa;',
+                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
+                       '@throws AuthorizationException&#xa;',
+                       '          If the server refuses to remove the ', $ufn, ' because the client does not have the correct privileges.&#xa;',
+                       '@throws CommunicationException&#xa;',
+                       '          If the client cannot contact the server due to an underlying communication problem.')" />
+        </xsl:call-template>
         <xsl:value-of
-          select="concat('  /**&#xa;',
-                       '   * Removes the ', $ufn,' if it exists.&#xa;',
-                       '   *&#xa;',
-                       '   * @throws OperationsException&#xa;',
-                       '   *           If the ', $ufn,' does not exist or could not be removed&#xa;',
-                       '   *           due to some underlying communication problem.&#xa;',
-                       '   */&#xa;')" />
-        <xsl:value-of
-          select="concat('  void remove',
-                       $java-relation-name, '() throws OperationsException;&#xa;')" />
+          select="concat('  void remove', $java-relation-name, '()&#xa;',
+                         '      throws ManagedObjectNotFoundException, OperationRejectedException,&#xa;',
+                         '      ConcurrentModificationException, AuthorizationException,&#xa;',
+                         '      CommunicationException;&#xa;')" />
       </xsl:when>
       <xsl:when test="adm:one-to-many">
         <xsl:variable name="plural-name"
@@ -189,77 +243,117 @@
             <xsl:with-param name="value" select="$plural-name" />
           </xsl:call-template>
         </xsl:variable>
-        <xsl:value-of
-          select="concat('  /**&#xa;',
-                       '   * Lists the ', $ufpn,'.&#xa;',
-                       '   *&#xa;',
-                       '   * @return Returns an array containing the names of the&#xa;',
-                       '   *         ', $ufpn,'.&#xa;',
-                       '   * @throws OperationsException&#xa;',
-                       '   *           If the ', $ufpn,' could not be listed due to some&#xa;',
-                       '   *           underlying communication problem.&#xa;',
-                       '   */&#xa;')" />
+        <xsl:call-template name="add-java-comment2">
+          <xsl:with-param name="indent" select="2" />
+          <xsl:with-param name="content"
+            select="concat('Lists the ', $ufpn,'.&#xa;',
+                       '&#xa;',
+                       '@return Returns an array containing the names of the ', $ufpn,'.&#xa;',
+                       '@throws ConcurrentModificationException&#xa;',
+                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
+                       '@throws AuthorizationException&#xa;',
+                       '          If the server refuses to list the ', $ufpn, ' because the client does not have the correct privileges.&#xa;',
+                       '@throws CommunicationException&#xa;',
+                       '          If the client cannot contact the server due to an underlying communication problem.')" />
+        </xsl:call-template>
         <xsl:value-of
           select="concat('  String[] list',
-                       $java-relation-plural-name, '() throws OperationsException;&#xa;')" />
+                       $java-relation-plural-name, '() throws ConcurrentModificationException,&#xa;',
+                       '      AuthorizationException, CommunicationException;&#xa;')" />
         <xsl:text>&#xa;</xsl:text>
         <xsl:text>&#xa;</xsl:text>
         <xsl:text>&#xa;</xsl:text>
+        <xsl:call-template name="add-java-comment2">
+          <xsl:with-param name="indent" select="2" />
+          <xsl:with-param name="content"
+            select="concat(
+                       'Gets the named ', $ufn, '.&#xa;',
+                       '&#xa;',
+                       '@param name&#xa;',
+                       '          The name of the ', $ufn,' to retrieve.&#xa;',
+                       '@return Returns the named ', $ufn, '.&#xa;',
+                       '@throws DefinitionDecodingException&#xa;',
+                       '          If the named ', $ufn, ' was found but its type could not be determined.&#xa;',
+                       '@throws ManagedObjectDecodingException&#xa;',
+                       '          If the named ', $ufn, ' was found but one or more of its properties could not be decoded.&#xa;',
+                       '@throws ManagedObjectNotFoundException&#xa;',
+                       '          If the named ', $ufn, ' was not found on the server.&#xa;',
+                       '@throws ConcurrentModificationException&#xa;',
+                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
+                       '@throws AuthorizationException&#xa;',
+                       '          If the server refuses to retrieve the named ', $ufn, ' because the client does not have the correct privileges.&#xa;',
+                       '@throws CommunicationException&#xa;',
+                       '          If the client cannot contact the server due to an underlying communication problem.')" />
+        </xsl:call-template>
         <xsl:value-of
-          select="concat('  /**&#xa;',
-                       '   * Gets the named ', $ufn,'.&#xa;',
-                       '   *&#xa;',
-                       '   * @param name&#xa;',
-                       '   *          The name of the ', $ufn,' to retrieve.&#xa;',
-                       '   * @return Returns the named ', $ufn,'.&#xa;',
-                       '   * @throws OperationsException&#xa;',
-                       '   *           If the ', $ufn,' does not exist or could not be read&#xa;',
-                       '   *           due to some underlying communication problem.&#xa;',
-                       '   */&#xa;')" />
-        <xsl:value-of
-          select="concat('  ', $java-class-name, 'CfgClient get',
-                       $java-relation-name, '(String name) throws OperationsException;&#xa;')" />
+          select="concat('  ', $java-class-name, 'CfgClient get', $java-relation-name, '(String name)&#xa;',
+                       '      throws DefinitionDecodingException, ManagedObjectDecodingException,&#xa;',
+                       '      ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
+                       '      AuthorizationException, CommunicationException;&#xa;')" />
         <xsl:text>&#xa;</xsl:text>
         <xsl:text>&#xa;</xsl:text>
         <xsl:text>&#xa;</xsl:text>
-        <xsl:value-of
-          select="concat('  /**&#xa;',
-                       '   * Creates a new ', $ufn,'.&#xa;',
-                       '   *&#xa;',
-                       '   * @param &lt;C&gt;&#xa;',
-                       '   *          The type of the ', $ufn,' being added.&#xa;',
-                       '   * @param d&#xa;',
-                       '   *          The definition of the ', $ufn,' to be created.&#xa;',
-                       '   * @param name&#xa;',
-                       '   *          The name of the new ', $ufn,'.&#xa;',
-                       '   * @param p&#xa;',
-                       '   *          A property provider which can be used to initialize&#xa;',
-                       '   *          the property values of the new ', $ufn,'.&#xa;',
-                       '   * @return Returns a new ', $ufn,' instance representing the&#xa;',
-                       '   *         ', $ufn,' that was created.&#xa;',
-                       '   * @throws OperationsException&#xa;',
-                       '   *           If the ', $ufn,' already exists or could not be created&#xa;',
-                       '   *           due to some underlying communication problem.&#xa;',
-                       '   */&#xa;')" />
+        <xsl:call-template name="add-java-comment2">
+          <xsl:with-param name="indent" select="2" />
+          <xsl:with-param name="content"
+            select="concat(
+                       'Creates a new ', $ufn,'.&#xa;',
+                       '&#xa;',
+                       '@param &lt;C&gt;&#xa;',
+                       '         The type of the ', $ufn,' being added.&#xa;',
+                       '@param d&#xa;',
+                       '         The definition of the ', $ufn,' to be created.&#xa;',
+                       '@param name&#xa;',
+                       '         The name of the new ', $ufn,'.&#xa;',
+                       '@param p&#xa;',
+                       '         A property provider which can be used to initialize the property values of the new ', $ufn,'.&#xa;',
+                       '@return Returns a new ', $ufn,' instance representing the ', $ufn,' that was created.&#xa;',
+                       '@throws ManagedObjectDecodingException&#xa;',
+                       '          If the ', $ufn,' could not be created because one or more of its properties are invalid.&#xa;',
+                       '@throws ManagedObjectAlreadyExistsException&#xa;',
+                       '          If the ', $ufn,' cannot be created because it already exists on the server.&#xa;',
+                       '@throws ConcurrentModificationException&#xa;',
+                       '          If this ', $ufn,' has been removed from the server by another client.&#xa;',
+                       '@throws OperationRejectedException&#xa;',
+                       '          If the server refuses to create the ', $ufn,' due to some server-side constraint which cannot be satisfied.&#xa;',
+                       '@throws AuthorizationException&#xa;',
+                       '          If the server refuses to create the ', $ufn,' because the client does not have the correct privileges.&#xa;',
+                       '@throws CommunicationException&#xa;',
+                       '          If the client cannot contact the server due to an underlying communication problem.&#xa;')" />
+        </xsl:call-template>
         <xsl:value-of
           select="concat('  &lt;C extends ', $java-class-name,'CfgClient&gt; C create', $java-relation-name, '(&#xa;',
-                           '      ManagedObjectDefinition&lt;C, ?&gt; d, String name, PropertyProvider p) throws OperationsException;&#xa;')" />
+                           '      ManagedObjectDefinition&lt;C, ?&gt; d, String name, PropertyProvider p)&#xa;',
+                           '      throws ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,&#xa;',
+                           '      ConcurrentModificationException, OperationRejectedException,&#xa;',
+                           '      AuthorizationException, CommunicationException;&#xa;')" />
         <xsl:text>&#xa;</xsl:text>
         <xsl:text>&#xa;</xsl:text>
         <xsl:text>&#xa;</xsl:text>
+        <xsl:call-template name="add-java-comment2">
+          <xsl:with-param name="indent" select="2" />
+          <xsl:with-param name="content"
+            select="concat(
+                       'Removes the named ', $ufn,'.&#xa;',
+                       '&#xa;',
+                       '@param name&#xa;',
+                       '         The name of the ', $ufn,' to remove.&#xa;',
+                       '@throws ManagedObjectNotFoundException&#xa;',
+                       '          If the ', $ufn, ' does not exist.&#xa;',
+                       '@throws OperationRejectedException&#xa;',
+                       '          If the server refuses to remove the ', $ufn, ' due to some server-side constraint which cannot be satisfied (for example, if it is referenced by another managed object).&#xa;',
+                       '@throws ConcurrentModificationException&#xa;',
+                       '          If this ', $this-ufn, ' has been removed from the server by another client.&#xa;',
+                       '@throws AuthorizationException&#xa;',
+                       '          If the server refuses to remove the ', $ufn, ' because the client does not have the correct privileges.&#xa;',
+                       '@throws CommunicationException&#xa;',
+                       '          If the client cannot contact the server due to an underlying communication problem.')" />
+        </xsl:call-template>
         <xsl:value-of
-          select="concat('  /**&#xa;',
-                       '   * Removes the named ', $ufn,'.&#xa;',
-                       '   *&#xa;',
-                       '   * @param name&#xa;',
-                       '   *          The name of the ', $ufn,' to remove.&#xa;',
-                       '   * @throws OperationsException&#xa;',
-                       '   *           If the ', $ufn,' does not exist or could not be removed&#xa;',
-                       '   *           due to some underlying communication problem.&#xa;',
-                       '   */&#xa;')" />
-        <xsl:value-of
-          select="concat('  void remove',
-                       $java-relation-name, '(String name) throws OperationsException;&#xa;')" />
+          select="concat('  void remove', $java-relation-name, '(String name)&#xa;',
+                         '      throws ManagedObjectNotFoundException, OperationRejectedException,&#xa;',
+                         '      ConcurrentModificationException, AuthorizationException,&#xa;',
+                         '      CommunicationException;&#xa;')" />
       </xsl:when>
       <xsl:otherwise>
         <xsl:message terminate="yes">
@@ -294,11 +388,34 @@
           </import>
         </xsl:if>
         <xsl:if test="$this-local-relations">
-          <import>org.opends.server.admin.OperationsException</import>
+          <import>
+            org.opends.server.admin.DefinitionDecodingException
+          </import>
+          <import>
+            org.opends.server.admin.ManagedObjectNotFoundException
+          </import>
+          <import>
+            org.opends.server.admin.client.ManagedObjectDecodingException
+          </import>
+          <import>
+            org.opends.server.admin.client.ConcurrentModificationException
+          </import>
+          <import>
+            org.opends.server.admin.client.AuthorizationException
+          </import>
+          <import>
+            org.opends.server.admin.client.CommunicationException
+          </import>
         </xsl:if>
         <xsl:if
           test="$this-local-relations/adm:one-to-zero-or-one|$this-local-relations/adm:one-to-many">
           <import>org.opends.server.admin.PropertyProvider</import>
+          <import>
+            org.opends.server.admin.ManagedObjectAlreadyExistsException
+          </import>
+          <import>
+            org.opends.server.admin.client.OperationRejectedException
+          </import>
         </xsl:if>
         <xsl:choose>
           <xsl:when test="$this/@extends">
diff --git a/opendj-sdk/opends/resource/admin/java-utilities.xsl b/opendj-sdk/opends/resource/admin/java-utilities.xsl
index 370b30d..8a61b62 100644
--- a/opendj-sdk/opends/resource/admin/java-utilities.xsl
+++ b/opendj-sdk/opends/resource/admin/java-utilities.xsl
@@ -143,6 +143,145 @@
     </xsl:call-template>
   </xsl:template>
   <!--
+    Add a Java comment at the specified indentation.
+    
+    This template handles embedded newline characters
+    and will also indent individual lines according to
+    the number of leading spaces they contain.
+    
+    @param indent
+    The indentation column for the comment.
+    
+    @param content
+    The content to be output in the comment.
+  -->
+  <xsl:template name="add-java-comment2">
+    <xsl:param name="indent" select="/.." />
+    <xsl:param name="content" select="/.." />
+    <!--  Compute the indentation string. -->
+    <xsl:variable name="indent-text">
+      <xsl:call-template name="add-indent">
+        <xsl:with-param name="indent" select="$indent + 1" />
+      </xsl:call-template>
+      <xsl:value-of select="'*'" />
+    </xsl:variable>
+    <!--  Output the comment header. -->
+    <xsl:call-template name="add-indent">
+      <xsl:with-param name="indent" select="$indent" />
+    </xsl:call-template>
+    <xsl:value-of select="'/**&#xa;'" />
+    <!--  Output the comment contents. -->
+    <xsl:call-template name="add-java-comment-line">
+      <xsl:with-param name="indent-text" select="$indent-text" />
+      <xsl:with-param name="content" select="$content" />
+    </xsl:call-template>
+    <!--  Output the header trailer. -->
+    <xsl:value-of select="concat($indent-text, '/&#xa;')" />
+  </xsl:template>
+  <!-- Creates a padding string of the required length. -->
+  <xsl:template name="add-indent">
+    <xsl:param name="indent" select="/.." />
+    <xsl:if test="$indent > 0">
+      <xsl:value-of select="' '" />
+      <xsl:call-template name="add-indent">
+        <xsl:with-param name="indent" select="$indent - 1" />
+      </xsl:call-template>
+    </xsl:if>
+  </xsl:template>
+  <xsl:template name="add-java-comment-line">
+    <xsl:param name="indent-text" select="/.." />
+    <xsl:param name="content" select="/.." />
+    <!--  Get the next line. -->
+    <xsl:variable name="head"
+      select="substring-before($content, '&#xa;')" />
+    <xsl:variable name="tail"
+      select="substring-after($content, '&#xa;')" />
+    <!--
+      Case #1 - content is empty
+      Case #2 - no newline
+      Case #3 - contains a new line
+      Case #3.1 - begins with newline
+      Case #3.2 - ends with newline
+    -->
+    <xsl:choose>
+      <xsl:when test="string-length($content) = 0">
+        <!-- Do nothing. -->
+      </xsl:when>
+      <xsl:when test="not(contains($content, '&#xa;'))">
+        <!-- Single line of text. -->
+        <xsl:call-template name="java-format-line">
+          <xsl:with-param name="indent-text" select="$indent-text" />
+          <xsl:with-param name="line" select="$content" />
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <!-- Output the first line and repeat for remaining lines. -->
+        <xsl:call-template name="java-format-line">
+          <xsl:with-param name="indent-text" select="$indent-text" />
+          <xsl:with-param name="line" select="$head" />
+        </xsl:call-template>
+        <xsl:call-template name="add-java-comment-line">
+          <xsl:with-param name="indent-text" select="$indent-text" />
+          <xsl:with-param name="content" select="$tail" />
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  <!-- Formats a line of comment text. -->
+  <xsl:template name="java-format-line">
+    <xsl:param name="indent-text" select="/.." />
+    <xsl:param name="line" select="/.." />
+    <!--  First count the number of leading spaces to determine the indent. -->
+    <xsl:variable name="leading-spaces">
+      <xsl:call-template name="java-format-line-help">
+        <xsl:with-param name="line" select="$line" />
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="content"
+      select="substring($line, $leading-spaces + 1)" />
+    <xsl:variable name="padding1">
+      <xsl:value-of select="$indent-text" />
+      <xsl:call-template name="add-indent">
+        <xsl:with-param name="indent" select="$leading-spaces" />
+      </xsl:call-template>
+    </xsl:variable>
+    <!-- We need to use indent2 for certain javadoc keywords. -->
+    <xsl:variable name="padding2">
+      <xsl:choose>
+        <xsl:when test="starts-with($content, '@return')">
+          <xsl:value-of select="concat($padding1, '        ')" />
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$padding1" />
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <!-- Now output the line, wrapping as necessary. -->
+    <xsl:call-template name="format-text">
+      <xsl:with-param name="indent-text" select="$padding1" />
+      <xsl:with-param name="indent-text2" select="$padding2" />
+      <xsl:with-param name="wrap-column" select="'70'" />
+      <xsl:with-param name="content" select="$content" />
+    </xsl:call-template>
+  </xsl:template>
+  <!--  Determines the number of leading spaces in the provided string. -->
+  <xsl:template name="java-format-line-help">
+    <xsl:param name="line" select="/.." />
+    <xsl:param name="count" select="0" />
+    <xsl:choose>
+      <xsl:when test="starts-with($line, ' ')">
+        <xsl:call-template name="java-format-line-help">
+          <xsl:with-param name="line"
+            select="substring-after($line, ' ')" />
+          <xsl:with-param name="count" select="$count + 1" />
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$count" />
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  <!--
     Utility template for removing duplicate values from a node-set.
     
     This template is based on the version published on the XSLT site.
@@ -168,13 +307,16 @@
           <xsl:when test="$distinct[. = $value]">
             <xsl:call-template name="_set-distinct">
               <xsl:with-param name="distinct" select="$distinct" />
-              <xsl:with-param name="nodes" select="$nodes[position() > 1]" />
+              <xsl:with-param name="nodes"
+                select="$nodes[position() > 1]" />
             </xsl:call-template>
           </xsl:when>
           <xsl:otherwise>
             <xsl:call-template name="_set-distinct">
-              <xsl:with-param name="distinct" select="$distinct | $nodes[1]" />
-              <xsl:with-param name="nodes" select="$nodes[position() > 1]" />
+              <xsl:with-param name="distinct"
+                select="$distinct | $nodes[1]" />
+              <xsl:with-param name="nodes"
+                select="$nodes[position() > 1]" />
             </xsl:call-template>
           </xsl:otherwise>
         </xsl:choose>
diff --git a/opendj-sdk/opends/resource/admin/metaMO.xsl b/opendj-sdk/opends/resource/admin/metaMO.xsl
index a8aa4e3..46a998d 100644
--- a/opendj-sdk/opends/resource/admin/metaMO.xsl
+++ b/opendj-sdk/opends/resource/admin/metaMO.xsl
@@ -387,7 +387,9 @@
       select="concat('    /**&#xa;',
                      '     * {@inheritDoc}&#xa;',
                      '     */&#xa;',
-                     '    public void commit() throws OperationsException {&#xa;',
+                     '    public void commit() throws ConcurrentModificationException,&#xa;',
+                     '        OperationRejectedException, AuthorizationException,&#xa;',
+                     '        CommunicationException {&#xa;',
                      '      impl.commit();&#xa;',
                      '    }&#xa;')" />
     <xsl:text>&#xa;</xsl:text>
@@ -1080,8 +1082,10 @@
           select="concat('    /**&#xa;',
                          '     * {@inheritDoc}&#xa;',
                          '     */&#xa;',
-                         '    public ', $java-class-name, 'CfgClient get',
-                         $java-relation-name, '() throws OperationsException {&#xa;',
+                         '    public ', $java-class-name, 'CfgClient get', $java-relation-name, '()&#xa;',
+                         '        throws DefinitionDecodingException, ManagedObjectDecodingException,&#xa;',
+                         '        ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
+                         '        AuthorizationException, CommunicationException {&#xa;',
                          '      return impl.getChild(INSTANCE.get', $java-relation-name,'RelationDefinition()).getConfiguration();&#xa;',
                          '    }&#xa;')" />
       </xsl:when>
@@ -1090,8 +1094,8 @@
           select="concat('    /**&#xa;',
                          '     * {@inheritDoc}&#xa;',
                          '     */&#xa;',
-                         '    public boolean has',
-                         $java-relation-name, '() throws OperationsException {&#xa;',
+                         '    public boolean has', $java-relation-name, '() throws ConcurrentModificationException,&#xa;',
+                         '        AuthorizationException, CommunicationException {&#xa;',
                          '      return impl.hasChild(INSTANCE.get', $java-relation-name,'RelationDefinition());&#xa;',
                          '    }&#xa;')" />
         <xsl:text>&#xa;</xsl:text>
@@ -1101,8 +1105,10 @@
           select="concat('    /**&#xa;',
                          '     * {@inheritDoc}&#xa;',
                          '     */&#xa;',
-                         '    public ', $java-class-name, 'CfgClient get',
-                         $java-relation-name, '() throws OperationsException {&#xa;',
+                         '    public ', $java-class-name, 'CfgClient get', $java-relation-name, '()&#xa;',
+                         '        throws DefinitionDecodingException, ManagedObjectDecodingException,&#xa;',
+                         '        ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
+                         '        AuthorizationException, CommunicationException {&#xa;',
                          '      return impl.getChild(INSTANCE.get', $java-relation-name,'RelationDefinition()).getConfiguration();&#xa;',
                          '    }&#xa;')" />
         <xsl:text>&#xa;</xsl:text>
@@ -1112,8 +1118,11 @@
           select="concat('    /**&#xa;',
                          '     * {@inheritDoc}&#xa;',
                          '     */&#xa;',
-                         '    public &lt;M extends ', $java-class-name, 'CfgClient&gt; M create',
-                         $java-relation-name, '(ManagedObjectDefinition&lt;M, ?&gt; d, PropertyProvider p) throws OperationsException {&#xa;',
+                         '    public &lt;M extends ', $java-class-name, 'CfgClient&gt; M create', $java-relation-name, '(&#xa;',
+                         '        ManagedObjectDefinition&lt;M, ?&gt; d, PropertyProvider p)&#xa;',
+                         '        throws ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,&#xa;',
+                         '        ConcurrentModificationException, OperationRejectedException,&#xa;',
+                         '        AuthorizationException, CommunicationException {&#xa;',
                          '      return impl.createChild(INSTANCE.get', $java-relation-name,'RelationDefinition(), d, p).getConfiguration();&#xa;',
                          '    }&#xa;')" />
         <xsl:text>&#xa;</xsl:text>
@@ -1123,8 +1132,9 @@
           select="concat('    /**&#xa;',
                          '     * {@inheritDoc}&#xa;',
                          '     */&#xa;',
-                         '    public void remove',
-                         $java-relation-name, '() throws OperationsException {&#xa;',
+                         '    public void remove', $java-relation-name, '()&#xa;',
+                         '        throws ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
+                         '        OperationRejectedException, AuthorizationException, CommunicationException {&#xa;',
                          '      impl.removeChild(INSTANCE.get', $java-relation-name,'RelationDefinition());&#xa;',
                          '    }&#xa;')" />
       </xsl:when>
@@ -1140,8 +1150,8 @@
           select="concat('    /**&#xa;',
                          '     * {@inheritDoc}&#xa;',
                          '     */&#xa;',
-                         '    public String[] list',
-                         $java-relation-plural-name, '() throws OperationsException {&#xa;',
+                         '    public String[] list', $java-relation-plural-name, '() throws ConcurrentModificationException,&#xa;',
+                         '        AuthorizationException, CommunicationException {&#xa;',
                          '      return impl.listChildren(INSTANCE.get', $java-relation-plural-name,'RelationDefinition());&#xa;',
                          '    }&#xa;')" />
         <xsl:text>&#xa;</xsl:text>
@@ -1151,8 +1161,10 @@
           select="concat('    /**&#xa;',
                          '     * {@inheritDoc}&#xa;',
                          '     */&#xa;',
-                         '    public ', $java-class-name, 'CfgClient get',
-                         $java-relation-name, '(String name) throws OperationsException {&#xa;',
+                         '    public ', $java-class-name, 'CfgClient get', $java-relation-name, '(String name)&#xa;',
+                         '        throws DefinitionDecodingException, ManagedObjectDecodingException,&#xa;',
+                         '        ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
+                         '        AuthorizationException, CommunicationException {&#xa;',
                          '      return impl.getChild(INSTANCE.get', $java-relation-plural-name,'RelationDefinition(), name).getConfiguration();&#xa;',
                          '    }&#xa;')" />
         <xsl:text>&#xa;</xsl:text>
@@ -1162,8 +1174,11 @@
           select="concat('    /**&#xa;',
                          '     * {@inheritDoc}&#xa;',
                          '     */&#xa;',
-                         '    public &lt;M extends ', $java-class-name, 'CfgClient&gt; M create',
-                         $java-relation-name, '(ManagedObjectDefinition&lt;M, ?&gt; d, String name, PropertyProvider p) throws OperationsException {&#xa;',
+                         '    public &lt;M extends ', $java-class-name, 'CfgClient&gt; M create', $java-relation-name, '(&#xa;',
+                         '        ManagedObjectDefinition&lt;M, ?&gt; d, String name, PropertyProvider p)&#xa;',
+                         '        throws ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,&#xa;',
+                         '        ConcurrentModificationException, OperationRejectedException,&#xa;',
+                         '        AuthorizationException, CommunicationException {&#xa;',
                          '      return impl.createChild(INSTANCE.get', $java-relation-plural-name,'RelationDefinition(), d, name, p).getConfiguration();&#xa;',
                          '    }&#xa;')" />
         <xsl:text>&#xa;</xsl:text>
@@ -1173,8 +1188,9 @@
           select="concat('    /**&#xa;',
                          '     * {@inheritDoc}&#xa;',
                          '     */&#xa;',
-                         '    public void remove',
-                         $java-relation-name, '(String name) throws OperationsException {&#xa;',
+                         '    public void remove', $java-relation-name, '(String name)&#xa;',
+                         '        throws ManagedObjectNotFoundException, ConcurrentModificationException,&#xa;',
+                         '        OperationRejectedException, AuthorizationException, CommunicationException {&#xa;',
                          '      impl.removeChild(INSTANCE.get', $java-relation-plural-name,'RelationDefinition(), name);&#xa;',
                          '    }&#xa;')" />
       </xsl:when>
@@ -1638,7 +1654,18 @@
               org.opends.server.admin.ManagedObjectDefinition
             </import>
             <import>org.opends.server.admin.PropertyProvider</import>
-            <import>org.opends.server.admin.OperationsException</import>
+            <import>
+              org.opends.server.admin.client.AuthorizationException
+            </import>
+            <import>
+              org.opends.server.admin.client.CommunicationException
+            </import>
+            <import>
+              org.opends.server.admin.client.ConcurrentModificationException
+            </import>
+            <import>
+              org.opends.server.admin.client.OperationRejectedException
+            </import>
             <import>
               org.opends.server.admin.client.ManagedObject
             </import>
@@ -1653,8 +1680,22 @@
                 name="generate-change-listener-import-statements" />
             </xsl:if>
             <import>org.opends.server.types.DN</import>
+            <xsl:if test="$this-all-relations">
+              <import>
+                org.opends.server.admin.DefinitionDecodingException
+              </import>
+              <import>
+                org.opends.server.admin.ManagedObjectNotFoundException
+              </import>
+              <import>
+                org.opends.server.admin.client.ManagedObjectDecodingException
+              </import>
+            </xsl:if>
             <xsl:if test="$this-all-relations/adm:one-to-many">
               <import>
+                org.opends.server.admin.ManagedObjectAlreadyExistsException
+              </import>
+              <import>
                 org.opends.server.admin.server.ConfigurationAddListener
               </import>
               <import>
@@ -1664,6 +1705,9 @@
             </xsl:if>
             <xsl:if test="$this-all-relations/adm:one-to-zero-or-one">
               <import>
+                org.opends.server.admin.ManagedObjectAlreadyExistsException
+              </import>
+              <import>
                 org.opends.server.admin.server.ConfigurationAddListener
               </import>
               <import>
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/AbstractPropertyDefinitionVisitor.java b/opendj-sdk/opends/src/server/org/opends/server/admin/AbstractPropertyDefinitionVisitor.java
deleted file mode 100644
index 7876ca4..0000000
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/AbstractPropertyDefinitionVisitor.java
+++ /dev/null
@@ -1,172 +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/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
- *
- *
- *      Portions Copyright 2007 Sun Microsystems, Inc.
- */
-
-package org.opends.server.admin;
-
-
-
-/**
- * A skeletal implementation of a property definition visitor. Each
- * <code>visitXXX</code> method is provided with a default
- * implementation which calls
- * {@link #visitUnknown(PropertyDefinition, Object)}. Sub-classes can
- * override any or all of the methods to provide their own
- * type-specific behavior.
- *
- * @param <R>
- *          The return type of this visitor's methods. Use
- *          {@link java.lang.Void} for visitors that do not need to
- *          return results.
- * @param <P>
- *          The type of the additional parameter to this visitor's
- *          methods. Use {@link java.lang.Void} for visitors that do
- *          not need an additional parameter.
- */
-public abstract class AbstractPropertyDefinitionVisitor<R, P>
-    implements PropertyDefinitionVisitor<R, P> {
-
-  /**
-   * Default constructor.
-   */
-  protected AbstractPropertyDefinitionVisitor() {
-    // No implementation required.
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public R visitAttributeType(AttributeTypePropertyDefinition d, P p) {
-    return visitUnknown(d, p);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public R visitBoolean(BooleanPropertyDefinition d, P p) {
-    return visitUnknown(d, p);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public R visitClass(ClassPropertyDefinition d, P p) {
-    return visitUnknown(d, p);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public R visitDN(DNPropertyDefinition d, P p) {
-    return visitUnknown(d, p);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public R visitDuration(DurationPropertyDefinition d, P p) {
-    return visitUnknown(d, p);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public R visitInteger(IntegerPropertyDefinition d, P p) {
-    return visitUnknown(d, p);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public R visitIPAddress(IPAddressPropertyDefinition d, P p) {
-    return visitUnknown(d, p);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public R visitIPAddressMask(IPAddressMaskPropertyDefinition d, P p) {
-    return visitUnknown(d, p);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public R visitSize(SizePropertyDefinition d, P p) {
-    return visitUnknown(d, p);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public R visitString(StringPropertyDefinition d, P p) {
-    return visitUnknown(d, p);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   * <p>
-   * The default implementation of this method is throw an
-   * {@link UnknownPropertyDefinitionException}. Sub-classes can
-   * override this method with their own default behavior.
-   */
-  public R visitUnknown(PropertyDefinition d, P p)
-      throws UnknownPropertyDefinitionException {
-    throw new UnknownPropertyDefinitionException(d, p);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public R visitEnum(EnumPropertyDefinition<?> d, P p) {
-    return visitUnknown(d, p);
-  }
-
-}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/ConfigurationClient.java b/opendj-sdk/opends/src/server/org/opends/server/admin/ConfigurationClient.java
index f84e67b..b5e5ba5 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/ConfigurationClient.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/ConfigurationClient.java
@@ -27,6 +27,11 @@
 
 package org.opends.server.admin;
 
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ConcurrentModificationException;
+import org.opends.server.admin.client.OperationRejectedException;
+
 
 
 /**
@@ -59,11 +64,21 @@
   /**
    * Commit any changes made to this configuration client.
    *
-   * @throws OperationsException
-   *           If the changes to this configuration client could not
-   *           be committed due to some underlying communication
-   *           problem.
+   * @throws ConcurrentModificationException
+   *           If this configuration has been removed from the server
+   *           by another client.
+   * @throws OperationRejectedException
+   *           If the server refuses to apply the changes due to some
+   *           server-side constraint which cannot be satisfied.
+   * @throws AuthorizationException
+   *           If the server refuses to apply the changes because the
+   *           client does not have the correct privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
+   *           underlying communication problem.
    */
-  void commit() throws OperationsException;
+  void commit() throws ConcurrentModificationException,
+      OperationRejectedException, AuthorizationException,
+      CommunicationException;
 
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/LDAPProfile.java b/opendj-sdk/opends/src/server/org/opends/server/admin/LDAPProfile.java
index 3fb8c8b..5d0d807 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/LDAPProfile.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/LDAPProfile.java
@@ -123,19 +123,6 @@
     /**
      * {@inheritDoc}
      */
-    public String getFilter(AbstractManagedObjectDefinition<?, ?> d) {
-      StringBuilder builder = new StringBuilder();
-      builder.append("(ObjectClass=");
-      builder.append(getObjectClass(d));
-      builder.append(')');
-      return builder.toString();
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
     public String getObjectClass(
         AbstractManagedObjectDefinition<?, ?> d) {
       return resource.getString(d, "objectclass");
@@ -225,19 +212,6 @@
 
 
   /**
-   * Get an LDAP filter string which can be used to search for entries
-   * matching the specified definition.
-   *
-   * @param d
-   *          The managed object definition.
-   * @return Returns the LDAP filter.
-   */
-  public abstract String getFilter(
-      AbstractManagedObjectDefinition<?, ?> d);
-
-
-
-  /**
    * Get the principle object class associated with the specified
    * definition.
    *
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/ManagedObjectAlreadyExistsException.java b/opendj-sdk/opends/src/server/org/opends/server/admin/ManagedObjectAlreadyExistsException.java
index 08ca020..f5450b7 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/ManagedObjectAlreadyExistsException.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/ManagedObjectAlreadyExistsException.java
@@ -30,8 +30,8 @@
 
 
 /**
- * A managed object could not be created because there is an existing managed
- * object with the same name.
+ * A managed object could not be created because there is an existing
+ * managed object with the same name.
  */
 public final class ManagedObjectAlreadyExistsException extends
     OperationsException {
@@ -45,31 +45,12 @@
   private static final String MSG = "A managed object could not be created"
       + " because there is an existing managed object with the same name";
 
-  // The name of the managed object that could not be created.
-  private final String name;
-
 
 
   /**
-   * Create a managed object already exists exception with the duplicate name.
-   *
-   * @param name
-   *          The name of the managed object that could not be created.
+   * Create a managed object already exists exception.
    */
-  public ManagedObjectAlreadyExistsException(String name) {
+  public ManagedObjectAlreadyExistsException() {
     super(MSG);
-
-    this.name = name;
-  }
-
-
-
-  /**
-   * Get the name of the managed object that could not be created.
-   *
-   * @return Returns the name of the managed object that could not be created.
-   */
-  public String getName() {
-    return name;
   }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java b/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java
index b0cfdf1..86900db 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java
@@ -37,6 +37,12 @@
  * passed to a property definition's accept method, the corresponding
  * visit method most applicable to that property definition is
  * invoked.
+ * <p>
+ * Each <code>visitXXX</code> method is provided with a default
+ * implementation which calls
+ * {@link #visitUnknown(PropertyDefinition, Object)}. Sub-classes can
+ * override any or all of the methods to provide their own
+ * type-specific behavior.
  *
  * @param <R>
  *          The return type of this visitor's methods. Use
@@ -47,7 +53,16 @@
  *          methods. Use {@link java.lang.Void} for visitors that do
  *          not need an additional parameter.
  */
-public interface PropertyDefinitionVisitor<R, P> {
+public abstract class PropertyDefinitionVisitor<R, P> {
+
+  /**
+   * Default constructor.
+   */
+  protected PropertyDefinitionVisitor() {
+    // No implementation required.
+  }
+
+
 
   /**
    * Visit an attribute type property definition.
@@ -58,7 +73,9 @@
    *          A visitor specified parameter.
    * @return Returns a visitor specified result.
    */
-  R visitAttributeType(AttributeTypePropertyDefinition d, P p);
+  public R visitAttributeType(AttributeTypePropertyDefinition d, P p) {
+    return visitUnknown(d, p);
+  }
 
 
 
@@ -71,7 +88,9 @@
    *          A visitor specified parameter.
    * @return Returns a visitor specified result.
    */
-  R visitBoolean(BooleanPropertyDefinition d, P p);
+  public R visitBoolean(BooleanPropertyDefinition d, P p) {
+    return visitUnknown(d, p);
+  }
 
 
 
@@ -84,7 +103,9 @@
    *          A visitor specified parameter.
    * @return Returns a visitor specified result.
    */
-  R visitClass(ClassPropertyDefinition d, P p);
+  public R visitClass(ClassPropertyDefinition d, P p) {
+    return visitUnknown(d, p);
+  }
 
 
 
@@ -97,7 +118,9 @@
    *          A visitor specified parameter.
    * @return Returns a visitor specified result.
    */
-  R visitDN(DNPropertyDefinition d, P p);
+  public R visitDN(DNPropertyDefinition d, P p) {
+    return visitUnknown(d, p);
+  }
 
 
 
@@ -110,7 +133,27 @@
    *          A visitor specified parameter.
    * @return Returns a visitor specified result.
    */
-  R visitDuration(DurationPropertyDefinition d, P p);
+  public R visitDuration(DurationPropertyDefinition d, P p) {
+    return visitUnknown(d, p);
+  }
+
+
+
+  /**
+   * Visit an enumeration property definition.
+   *
+   * @param <E>
+   *          The enumeration that should be used for values of the
+   *          property definition.
+   * @param d
+   *          The enumeration property definition to visit.
+   * @param p
+   *          A visitor specified parameter.
+   * @return Returns a visitor specified result.
+   */
+  public <E extends Enum<E>> R visitEnum(EnumPropertyDefinition<E> d, P p) {
+    return visitUnknown(d, p);
+  }
 
 
 
@@ -123,7 +166,9 @@
    *          A visitor specified parameter.
    * @return Returns a visitor specified result.
    */
-  R visitInteger(IntegerPropertyDefinition d, P p);
+  public R visitInteger(IntegerPropertyDefinition d, P p) {
+    return visitUnknown(d, p);
+  }
 
 
 
@@ -136,7 +181,9 @@
    *          A visitor specified parameter.
    * @return Returns a visitor specified result.
    */
-  R visitIPAddress(IPAddressPropertyDefinition d, P p);
+  public R visitIPAddress(IPAddressPropertyDefinition d, P p) {
+    return visitUnknown(d, p);
+  }
 
 
 
@@ -149,7 +196,9 @@
    *          A visitor specified parameter.
    * @return Returns a visitor specified result.
    */
-  R visitIPAddressMask(IPAddressMaskPropertyDefinition d, P p);
+  public R visitIPAddressMask(IPAddressMaskPropertyDefinition d, P p) {
+    return visitUnknown(d, p);
+  }
 
 
 
@@ -162,7 +211,9 @@
    *          A visitor specified parameter.
    * @return Returns a visitor specified result.
    */
-  R visitSize(SizePropertyDefinition d, P p);
+  public R visitSize(SizePropertyDefinition d, P p) {
+    return visitUnknown(d, p);
+  }
 
 
 
@@ -175,7 +226,9 @@
    *          A visitor specified parameter.
    * @return Returns a visitor specified result.
    */
-  R visitString(StringPropertyDefinition d, P p);
+  public R visitString(StringPropertyDefinition d, P p) {
+    return visitUnknown(d, p);
+  }
 
 
 
@@ -183,6 +236,10 @@
    * Visit an unknown type of property definition. Implementations of
    * this method can provide default behavior for unknown property
    * definition types.
+   * <p>
+   * The default implementation of this method throws an
+   * {@link UnknownPropertyDefinitionException}. Sub-classes can
+   * override this method with their own default behavior.
    *
    * @param d
    *          The property definition to visit.
@@ -193,20 +250,9 @@
    *           Visitor implementations may optionally throw this
    *           exception.
    */
-  R visitUnknown(PropertyDefinition d, P p)
-      throws UnknownPropertyDefinitionException;
-
-
-
-  /**
-   * Visit an enumeration property definition.
-   *
-   * @param d
-   *          The enumeration property definition to visit.
-   * @param p
-   *          A visitor specified parameter.
-   * @return Returns a visitor specified result.
-   */
-  R visitEnum(EnumPropertyDefinition<?> d, P p);
+  public R visitUnknown(PropertyDefinition d, P p)
+      throws UnknownPropertyDefinitionException {
+    throw new UnknownPropertyDefinitionException(d, p);
+  }
 
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/AdminClientException.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/AdminClientException.java
new file mode 100644
index 0000000..0542c07
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/AdminClientException.java
@@ -0,0 +1,99 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.admin.client;
+
+
+
+import org.opends.server.admin.AdminException;
+
+
+
+/**
+ * Administration client exceptions represent non-operational problems
+ * which occur whilst interacting with the administration framework.
+ * They provide clients with a transport independent interface for
+ * handling transport related exceptions.
+ * <p>
+ * Client exceptions represent communications problems, security
+ * problems, and service related problems.
+ */
+public class AdminClientException extends AdminException {
+
+  /**
+   * Serialization ID.
+   */
+  private static final long serialVersionUID = 4044747533980824456L;
+
+
+
+  /**
+   * Create an administration client exception.
+   */
+  public AdminClientException() {
+    // No implementation required.
+  }
+
+
+
+  /**
+   * Create an administration client exception with a cause.
+   *
+   * @param cause
+   *          The cause.
+   */
+  public AdminClientException(Throwable cause) {
+    super(cause);
+  }
+
+
+
+  /**
+   * Create an administration client exception with a message and
+   * cause.
+   *
+   * @param message
+   *          The message.
+   * @param cause
+   *          The cause.
+   */
+  public AdminClientException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+
+
+  /**
+   * Create an administration client exception with a message.
+   *
+   * @param message
+   *          The message.
+   */
+  public AdminClientException(String message) {
+    super(message);
+  }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/AdminSecurityException.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/AdminSecurityException.java
new file mode 100644
index 0000000..138f75e
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/AdminSecurityException.java
@@ -0,0 +1,84 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.admin.client;
+
+
+
+/**
+ * This exception is thrown when a security related problem occurs
+ * whilst interacting with the Directory Server. These fall broadly
+ * into two categories: authentication problems and authorization
+ * problems.
+ */
+public abstract class AdminSecurityException extends AdminClientException {
+
+  /**
+   * Create a security exception.
+   */
+  protected AdminSecurityException() {
+    // No implementation required.
+  }
+
+
+
+  /**
+   * Create a security exception with a cause.
+   *
+   * @param cause
+   *          The cause.
+   */
+  protected AdminSecurityException(Throwable cause) {
+    super(cause);
+  }
+
+
+
+  /**
+   * Create a security exception with a message and cause.
+   *
+   * @param message
+   *          The message.
+   * @param cause
+   *          The cause.
+   */
+  protected AdminSecurityException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+
+
+  /**
+   * Create a security exception with a message.
+   *
+   * @param message
+   *          The message.
+   */
+  protected AdminSecurityException(String message) {
+    super(message);
+  }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthenticationException.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthenticationException.java
new file mode 100644
index 0000000..936d041
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthenticationException.java
@@ -0,0 +1,90 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.admin.client;
+
+
+
+/**
+ * This exception is thrown when an authentication error occurs while
+ * connecting to the Directory Server. An authentication error can
+ * happen, for example, when the client credentials are invalid.
+ */
+public class AuthenticationException extends AdminSecurityException {
+
+  /**
+   * Serialization ID.
+   */
+  private static final long serialVersionUID = 3544797197747686958L;
+
+
+
+  /**
+   * Create an authentication exception.
+   */
+  public AuthenticationException() {
+    // No implementation required.
+  }
+
+
+
+  /**
+   * Create an authentication exception with a cause.
+   *
+   * @param cause
+   *          The cause.
+   */
+  public AuthenticationException(Throwable cause) {
+    super(cause);
+  }
+
+
+
+  /**
+   * Create an authentication exception with a message and cause.
+   *
+   * @param message
+   *          The message.
+   * @param cause
+   *          The cause.
+   */
+  public AuthenticationException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+
+
+  /**
+   * Create an authentication exception with a message.
+   *
+   * @param message
+   *          The message.
+   */
+  public AuthenticationException(String message) {
+    super(message);
+  }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthenticationNotSupportedException.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthenticationNotSupportedException.java
new file mode 100644
index 0000000..d70c51a
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthenticationNotSupportedException.java
@@ -0,0 +1,91 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.admin.client;
+
+
+
+/**
+ * This exception is thrown when the particular flavor of
+ * authentication requested is not supported by the Directory Server.
+ */
+public class AuthenticationNotSupportedException
+    extends AdminSecurityException {
+
+  /**
+   * Serialization ID.
+   */
+  private static final long serialVersionUID = 7387834052676291793L;
+
+
+
+  /**
+   * Create an authentication not supported exception.
+   */
+  public AuthenticationNotSupportedException() {
+    // No implementation required.
+  }
+
+
+
+  /**
+   * Create an authentication not supported exception with a cause.
+   *
+   * @param cause
+   *          The cause.
+   */
+  public AuthenticationNotSupportedException(Throwable cause) {
+    super(cause);
+  }
+
+
+
+  /**
+   * Create an authentication not supported exception with a message
+   * and cause.
+   *
+   * @param message
+   *          The message.
+   * @param cause
+   *          The cause.
+   */
+  public AuthenticationNotSupportedException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+
+
+  /**
+   * Create an authentication not supported exception with a message.
+   *
+   * @param message
+   *          The message.
+   */
+  public AuthenticationNotSupportedException(String message) {
+    super(message);
+  }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthorizationException.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthorizationException.java
new file mode 100644
index 0000000..ef16fcd
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/AuthorizationException.java
@@ -0,0 +1,91 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.admin.client;
+
+
+
+/**
+ * This exception is thrown when an authorization error occurs while
+ * interacting with the Directory Server. Authorization errors can
+ * occur when a client attempts to perform an administrative operation
+ * which they are not permitted to perform.
+ */
+public class AuthorizationException extends AdminSecurityException {
+
+  /**
+   * Serialization ID.
+   */
+  private static final long serialVersionUID = 8414248362572933814L;
+
+
+
+  /**
+   * Create an authorization exception.
+   */
+  public AuthorizationException() {
+    // No implementation required.
+  }
+
+
+
+  /**
+   * Create an authorization exception with a cause.
+   *
+   * @param cause
+   *          The cause.
+   */
+  public AuthorizationException(Throwable cause) {
+    super(cause);
+  }
+
+
+
+  /**
+   * Create an authorization exception with a message and cause.
+   *
+   * @param message
+   *          The message.
+   * @param cause
+   *          The cause.
+   */
+  public AuthorizationException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+
+
+  /**
+   * Create an authorization exception with a message.
+   *
+   * @param message
+   *          The message.
+   */
+  public AuthorizationException(String message) {
+    super(message);
+  }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/CommunicationException.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/CommunicationException.java
new file mode 100644
index 0000000..e13bdce
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/CommunicationException.java
@@ -0,0 +1,92 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.admin.client;
+
+
+
+/**
+ * This exception is thrown when a communications related problem
+ * occurs whilst interacting with the Directory Server. This may be
+ * caused by problems such as network partitioning, the unavailability
+ * of the Directory Server, or other failures on the client or server
+ * side.
+ */
+public class CommunicationException extends AdminClientException {
+
+  /**
+   * Serialization ID.
+   */
+  private static final long serialVersionUID = 9093195928501281027L;
+
+
+
+  /**
+   * Create a communication exception.
+   */
+  public CommunicationException() {
+    // No implementation required.
+  }
+
+
+
+  /**
+   * Create a communication exception with a cause.
+   *
+   * @param cause
+   *          The cause.
+   */
+  public CommunicationException(Throwable cause) {
+    super(cause);
+  }
+
+
+
+  /**
+   * Create a communication exception with a message and cause.
+   *
+   * @param message
+   *          The message.
+   * @param cause
+   *          The cause.
+   */
+  public CommunicationException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+
+
+  /**
+   * Create a communication exception with a message.
+   *
+   * @param message
+   *          The message.
+   */
+  public CommunicationException(String message) {
+    super(message);
+  }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ConcurrentModificationException.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ConcurrentModificationException.java
new file mode 100644
index 0000000..9438989
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ConcurrentModificationException.java
@@ -0,0 +1,95 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.admin.client;
+
+
+
+import org.opends.server.admin.OperationsException;
+
+
+
+/**
+ * This exception is thrown when a critical concurrent modification is
+ * detected by the client. This may be caused by another client
+ * application removing a managed object whilst it is being managed.
+ */
+public class ConcurrentModificationException extends OperationsException {
+
+  /**
+   * Serialization ID.
+   */
+  private static final long serialVersionUID = -1467024486347612820L;
+
+
+
+  /**
+   * Create a concurrent modification exception.
+   */
+  public ConcurrentModificationException() {
+    // No implementation required.
+  }
+
+
+
+  /**
+   * Create a concurrent modification exception with a cause.
+   *
+   * @param cause
+   *          The cause.
+   */
+  public ConcurrentModificationException(Throwable cause) {
+    super(cause);
+  }
+
+
+
+  /**
+   * Create a concurrent modification exception with a message and
+   * cause.
+   *
+   * @param message
+   *          The message.
+   * @param cause
+   *          The cause.
+   */
+  public ConcurrentModificationException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+
+
+  /**
+   * Create a concurrent modification exception with a message.
+   *
+   * @param message
+   *          The message.
+   */
+  public ConcurrentModificationException(String message) {
+    super(message);
+  }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ExampleClient.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ExampleClient.java
index 1f37a19..67c9055 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ExampleClient.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ExampleClient.java
@@ -30,13 +30,15 @@
 
 
 import static org.opends.server.loggers.ErrorLogger.*;
-import static org.opends.server.util.ServerConstants.PROPERTY_SERVER_ROOT;
+import static org.opends.server.util.ServerConstants.*;
 
 import java.io.File;
 
-import org.opends.server.admin.ClassLoaderProvider;
 import org.opends.server.admin.AttributeTypePropertyDefinition;
+import org.opends.server.admin.ClassLoaderProvider;
 import org.opends.server.admin.ClassPropertyDefinition;
+import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
+import org.opends.server.admin.client.ldap.LDAPConnection;
 import org.opends.server.admin.client.ldap.LDAPManagementContext;
 import org.opends.server.admin.std.client.ConnectionHandlerCfgClient;
 import org.opends.server.admin.std.client.GlobalCfgClient;
@@ -128,8 +130,9 @@
    * Perform the client operations.
    */
   private void run() throws Exception {
-    ManagementContext ctx = LDAPManagementContext.createLDAPContext(
-        "localhost", 1389, "cn=directory manager", "password");
+    LDAPConnection connection = JNDIDirContextAdaptor.simpleBind("localhost",
+        1389, "cn=directory manager", "password");
+    ManagementContext ctx = LDAPManagementContext.createFromContext(connection);
 
     RootCfgClient root = ctx.getRootConfiguration();
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/InitialManagedObject.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/InitialManagedObject.java
index aa478dc..b5a7c64 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/InitialManagedObject.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/InitialManagedObject.java
@@ -92,9 +92,9 @@
     /**
      * {@inheritDoc}
      */
-    public Collection<?> getDefaultPropertyValues(
-        ManagedObjectPath path, String propertyName)
-        throws OperationsException, PropertyNotFoundException {
+    public Collection<?> getDefaultPropertyValues(ManagedObjectPath path,
+        String propertyName) throws OperationsException,
+        PropertyNotFoundException {
       throw new PropertyNotFoundException(propertyName);
     }
 
@@ -142,7 +142,7 @@
    * This implementation throws an
    * {@link UnsupportedOperationException}.
    */
-  public void commit() throws OperationsException {
+  public void commit() throws UnsupportedOperationException {
     throw new UnsupportedOperationException();
   }
 
@@ -156,9 +156,8 @@
    */
   public <M extends ConfigurationClient, N extends M>
       ManagedObject<N> createChild(
-      InstantiableRelationDefinition<M, ?> r,
-      ManagedObjectDefinition<N, ?> d, String name, PropertyProvider p)
-      throws IllegalArgumentException, OperationsException {
+      InstantiableRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
+      String name, PropertyProvider p) throws UnsupportedOperationException {
     throw new UnsupportedOperationException();
   }
 
@@ -172,9 +171,8 @@
    */
   public <M extends ConfigurationClient, N extends M>
       ManagedObject<N> createChild(
-      OptionalRelationDefinition<M, ?> r,
-      ManagedObjectDefinition<N, ?> d, PropertyProvider p)
-      throws IllegalArgumentException, OperationsException {
+      OptionalRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
+      PropertyProvider p) throws UnsupportedOperationException {
     throw new UnsupportedOperationException();
   }
 
@@ -188,7 +186,7 @@
    */
   public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
       InstantiableRelationDefinition<M, ?> d, String name)
-      throws IllegalArgumentException, OperationsException {
+      throws UnsupportedOperationException {
     throw new UnsupportedOperationException();
   }
 
@@ -201,8 +199,7 @@
    * {@link UnsupportedOperationException}.
    */
   public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
-      OptionalRelationDefinition<M, ?> d)
-      throws IllegalArgumentException, OperationsException {
+      OptionalRelationDefinition<M, ?> d) throws UnsupportedOperationException {
     throw new UnsupportedOperationException();
   }
 
@@ -216,7 +213,7 @@
    */
   public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
       SingletonRelationDefinition<M, ?> d)
-      throws IllegalArgumentException, OperationsException {
+      throws UnsupportedOperationException {
     throw new UnsupportedOperationException();
   }
 
@@ -279,7 +276,7 @@
    * {@link UnsupportedOperationException}.
    */
   public boolean hasChild(OptionalRelationDefinition<?, ?> d)
-      throws IllegalArgumentException, OperationsException {
+      throws UnsupportedOperationException {
     throw new UnsupportedOperationException();
   }
 
@@ -292,7 +289,7 @@
    * {@link UnsupportedOperationException}.
    */
   public String[] listChildren(InstantiableRelationDefinition<?, ?> d)
-      throws IllegalArgumentException, OperationsException {
+      throws UnsupportedOperationException {
     throw new UnsupportedOperationException();
   }
 
@@ -306,7 +303,7 @@
    */
   public <M extends ConfigurationClient> void removeChild(
       InstantiableRelationDefinition<M, ?> d, String name)
-      throws IllegalArgumentException, OperationsException {
+      throws UnsupportedOperationException {
     throw new UnsupportedOperationException();
   }
 
@@ -319,8 +316,7 @@
    * {@link UnsupportedOperationException}.
    */
   public <M extends ConfigurationClient> void removeChild(
-      OptionalRelationDefinition<M, ?> d)
-      throws IllegalArgumentException, OperationsException {
+      OptionalRelationDefinition<M, ?> d) throws UnsupportedOperationException {
     throw new UnsupportedOperationException();
 
   }
@@ -331,9 +327,8 @@
    * {@inheritDoc}
    */
   public <T> void setPropertyValue(PropertyDefinition<T> d, T value)
-      throws IllegalPropertyValueException,
-      PropertyIsReadOnlyException, PropertyIsMandatoryException,
-      IllegalArgumentException {
+      throws IllegalPropertyValueException, PropertyIsReadOnlyException,
+      PropertyIsMandatoryException, IllegalArgumentException {
     properties.setPropertyValue(d, value);
   }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagedObject.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagedObject.java
index 2fc4148..63694e0 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagedObject.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ManagedObject.java
@@ -32,12 +32,14 @@
 import java.util.Collection;
 import java.util.SortedSet;
 
+import org.opends.server.admin.DefinitionDecodingException;
 import org.opends.server.admin.IllegalPropertyValueException;
 import org.opends.server.admin.InstantiableRelationDefinition;
+import org.opends.server.admin.ManagedObjectAlreadyExistsException;
 import org.opends.server.admin.ManagedObjectDefinition;
 import org.opends.server.admin.ConfigurationClient;
+import org.opends.server.admin.ManagedObjectNotFoundException;
 import org.opends.server.admin.ManagedObjectPath;
-import org.opends.server.admin.OperationsException;
 import org.opends.server.admin.OptionalRelationDefinition;
 import org.opends.server.admin.PropertyDefinition;
 import org.opends.server.admin.PropertyIsMandatoryException;
@@ -89,117 +91,6 @@
     PropertyProvider {
 
   /**
-   * Get the effective value of the specified property.
-   * <p>
-   * See the class description for more information about how the
-   * effective property value is derived.
-   *
-   * @param <T>
-   *          The type of the property to be retrieved.
-   * @param d
-   *          The property to be retrieved.
-   * @return Returns the property's effective value, or
-   *         <code>null</code> if there is no effective value
-   *         defined.
-   * @throws IllegalArgumentException
-   *           If the property definition is not associated with this
-   *           managed object's definition.
-   */
-  public <T> T getPropertyValue(PropertyDefinition<T> d)
-      throws IllegalArgumentException;
-
-
-
-  /**
-   * Get the effective values of the specified property.
-   * <p>
-   * See the class description for more information about how the
-   * effective property values are derived.
-   *
-   * @param <T>
-   *          The type of the property to be retrieved.
-   * @param d
-   *          The property to be retrieved.
-   * @return Returns the property's effective values, or an empty set
-   *         if there are no effective values defined.
-   * @throws IllegalArgumentException
-   *           If the property definition is not associated with this
-   *           managed object's definition.
-   */
-  public <T> SortedSet<T> getPropertyValues(PropertyDefinition<T> d)
-      throws IllegalArgumentException;
-
-
-
-  /**
-   * Set a new pending value for the specified property.
-   * <p>
-   * See the class description for more information regarding pending
-   * values.
-   *
-   * @param <T>
-   *          The type of the property to be modified.
-   * @param d
-   *          The property to be modified.
-   * @param value
-   *          The new pending value for the property, or
-   *          <code>null</code> if the property should be reset to
-   *          its default behavior.
-   * @throws IllegalPropertyValueException
-   *           If the new pending value is deemed to be invalid
-   *           according to the property definition.
-   * @throws PropertyIsReadOnlyException
-   *           If an attempt was made to modify a read-only property.
-   * @throws PropertyIsMandatoryException
-   *           If an attempt was made to remove a mandatory property.
-   * @throws IllegalArgumentException
-   *           If the specified property definition is not associated
-   *           with this managed object.
-   */
-  public <T> void setPropertyValue(PropertyDefinition<T> d, T value)
-      throws IllegalPropertyValueException,
-      PropertyIsReadOnlyException, PropertyIsMandatoryException,
-      IllegalArgumentException;
-
-
-
-  /**
-   * Set a new pending values for the specified property.
-   * <p>
-   * See the class description for more information regarding pending
-   * values.
-   *
-   * @param <T>
-   *          The type of the property to be modified.
-   * @param d
-   *          The property to be modified.
-   * @param values
-   *          A non-<code>null</code> set of new pending values for
-   *          the property (an empty set indicates that the property
-   *          should be reset to its default behavior). The set will
-   *          not be referenced by this managed object.
-   * @throws IllegalPropertyValueException
-   *           If a new pending value is deemed to be invalid
-   *           according to the property definition.
-   * @throws PropertyIsSingleValuedException
-   *           If an attempt was made to add multiple pending values
-   *           to a single-valued property.
-   * @throws PropertyIsReadOnlyException
-   *           If an attempt was made to modify a read-only property.
-   * @throws PropertyIsMandatoryException
-   *           If an attempt was made to remove a mandatory property.
-   * @throws IllegalArgumentException
-   *           If the specified property definition is not associated
-   *           with this managed object.
-   */
-  public <T> void setPropertyValues(PropertyDefinition<T> d,
-      Collection<T> values) throws IllegalPropertyValueException,
-      PropertyIsSingleValuedException, PropertyIsReadOnlyException,
-      PropertyIsMandatoryException, IllegalArgumentException;
-
-
-
-  /**
    * Commit any changes made to this managed object. Pending property
    * values will be committed to the managed object. If successful,
    * the pending values will become active values.
@@ -207,11 +98,22 @@
    * See the class description for more information regarding pending
    * and active values.
    *
-   * @throws OperationsException
-   *           If the changes to this managed object could not be
-   *           committed due to some underlying communication problem.
+   * @throws ConcurrentModificationException
+   *           If this managed object has been removed from the server
+   *           by another client.
+   * @throws OperationRejectedException
+   *           If the server refuses to apply the changes due to some
+   *           server-side constraint which cannot be satisfied.
+   * @throws AuthorizationException
+   *           If the server refuses to apply the changes because the
+   *           client does not have the correct privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
+   *           underlying communication problem.
    */
-  void commit() throws OperationsException;
+  void commit() throws ConcurrentModificationException,
+      OperationRejectedException, AuthorizationException,
+      CommunicationException;
 
 
 
@@ -242,14 +144,33 @@
    * @throws IllegalArgumentException
    *           If the relation definition is not associated with this
    *           managed object's definition.
-   * @throws OperationsException
-   *           If the managed object could not be created due to some
+   * @throws ManagedObjectDecodingException
+   *           If the managed object could not be create because one
+   *           or more of its properties are invalid.
+   * @throws ManagedObjectAlreadyExistsException
+   *           If the managed object cannot be created because it
+   *           already exists on the server.
+   * @throws ConcurrentModificationException
+   *           If this managed object has been removed from the server
+   *           by another client.
+   * @throws OperationRejectedException
+   *           If the server refuses to create the managed object due
+   *           to some server-side constraint which cannot be
+   *           satisfied.
+   * @throws AuthorizationException
+   *           If the server refuses to create the managed object
+   *           because the client does not have the correct
+   *           privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
    *           underlying communication problem.
    */
   <M extends ConfigurationClient, N extends M> ManagedObject<N> createChild(
-      InstantiableRelationDefinition<M, ?> r,
-      ManagedObjectDefinition<N, ?> d, String name, PropertyProvider p)
-      throws IllegalArgumentException, OperationsException;
+      InstantiableRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
+      String name, PropertyProvider p) throws IllegalArgumentException,
+      ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,
+      ConcurrentModificationException, OperationRejectedException,
+      AuthorizationException, CommunicationException;
 
 
 
@@ -278,14 +199,33 @@
    * @throws IllegalArgumentException
    *           If the relation definition is not associated with this
    *           managed object's definition.
-   * @throws OperationsException
-   *           If the managed object could not be created due to some
+   * @throws ManagedObjectDecodingException
+   *           If the managed object could not be created because one
+   *           or more of its properties are invalid.
+   * @throws ManagedObjectAlreadyExistsException
+   *           If the managed object cannot be created because it
+   *           already exists on the server.
+   * @throws ConcurrentModificationException
+   *           If this managed object has been removed from the server
+   *           by another client.
+   * @throws OperationRejectedException
+   *           If the server refuses to create the managed object due
+   *           to some server-side constraint which cannot be
+   *           satisfied.
+   * @throws AuthorizationException
+   *           If the server refuses to create the managed object
+   *           because the client does not have the correct
+   *           privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
    *           underlying communication problem.
    */
   <M extends ConfigurationClient, N extends M> ManagedObject<N> createChild(
-      OptionalRelationDefinition<M, ?> r,
-      ManagedObjectDefinition<N, ?> d, PropertyProvider p)
-      throws IllegalArgumentException, OperationsException;
+      OptionalRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
+      PropertyProvider p) throws IllegalArgumentException,
+      ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,
+      ConcurrentModificationException, OperationRejectedException,
+      AuthorizationException, CommunicationException;
 
 
 
@@ -303,13 +243,32 @@
    * @throws IllegalArgumentException
    *           If the relation definition is not associated with this
    *           managed object's definition.
-   * @throws OperationsException
-   *           If the managed object could not be read due to some
+   * @throws DefinitionDecodingException
+   *           If the managed object was found but its type could not
+   *           be determined.
+   * @throws ManagedObjectDecodingException
+   *           If the managed object was found but one or more of its
+   *           properties could not be decoded.
+   * @throws ManagedObjectNotFoundException
+   *           If the requested managed object could not be found on
+   *           the server.
+   * @throws ConcurrentModificationException
+   *           If this managed object has been removed from the server
+   *           by another client.
+   * @throws AuthorizationException
+   *           If the server refuses to retrieve the managed object
+   *           because the client does not have the correct
+   *           privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
    *           underlying communication problem.
    */
   <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
       InstantiableRelationDefinition<M, ?> d, String name)
-      throws IllegalArgumentException, OperationsException;
+      throws IllegalArgumentException, DefinitionDecodingException,
+      ManagedObjectDecodingException, ManagedObjectNotFoundException,
+      ConcurrentModificationException, AuthorizationException,
+      CommunicationException;
 
 
 
@@ -325,13 +284,31 @@
    * @throws IllegalArgumentException
    *           If the relation definition is not associated with this
    *           managed object's definition.
-   * @throws OperationsException
-   *           If the managed object could not be read due to some
+   * @throws DefinitionDecodingException
+   *           If the managed object was found but its type could not
+   *           be determined.
+   * @throws ManagedObjectDecodingException
+   *           If the managed object was found but one or more of its
+   *           properties could not be decoded.
+   * @throws ManagedObjectNotFoundException
+   *           If the requested managed object could not be found on
+   *           the server.
+   * @throws ConcurrentModificationException
+   *           If this managed object has been removed from the server
+   *           by another client.
+   * @throws AuthorizationException
+   *           If the server refuses to retrieve the managed object
+   *           because the client does not have the correct
+   *           privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
    *           underlying communication problem.
    */
   <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
-      OptionalRelationDefinition<M, ?> d)
-      throws IllegalArgumentException, OperationsException;
+      OptionalRelationDefinition<M, ?> d) throws IllegalArgumentException,
+      DefinitionDecodingException, ManagedObjectDecodingException,
+      ManagedObjectNotFoundException, ConcurrentModificationException,
+      AuthorizationException, CommunicationException;
 
 
 
@@ -347,13 +324,31 @@
    * @throws IllegalArgumentException
    *           If the relation definition is not associated with this
    *           managed object's definition.
-   * @throws OperationsException
-   *           If the managed object could not be read due to some
+   * @throws DefinitionDecodingException
+   *           If the managed object was found but its type could not
+   *           be determined.
+   * @throws ManagedObjectDecodingException
+   *           If the managed object was found but one or more of its
+   *           properties could not be decoded.
+   * @throws ManagedObjectNotFoundException
+   *           If the requested managed object could not be found on
+   *           the server.
+   * @throws ConcurrentModificationException
+   *           If this managed object has been removed from the server
+   *           by another client.
+   * @throws AuthorizationException
+   *           If the server refuses to retrieve the managed object
+   *           because the client does not have the correct
+   *           privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
    *           underlying communication problem.
    */
   <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
-      SingletonRelationDefinition<M, ?> d)
-      throws IllegalArgumentException, OperationsException;
+      SingletonRelationDefinition<M, ?> d) throws IllegalArgumentException,
+      DefinitionDecodingException, ManagedObjectDecodingException,
+      ManagedObjectNotFoundException, ConcurrentModificationException,
+      AuthorizationException, CommunicationException;
 
 
 
@@ -389,6 +384,49 @@
 
 
   /**
+   * Get the effective value of the specified property.
+   * <p>
+   * See the class description for more information about how the
+   * effective property value is derived.
+   *
+   * @param <T>
+   *          The type of the property to be retrieved.
+   * @param d
+   *          The property to be retrieved.
+   * @return Returns the property's effective value, or
+   *         <code>null</code> if there is no effective value
+   *         defined.
+   * @throws IllegalArgumentException
+   *           If the property definition is not associated with this
+   *           managed object's definition.
+   */
+  <T> T getPropertyValue(PropertyDefinition<T> d)
+      throws IllegalArgumentException;
+
+
+
+  /**
+   * Get the effective values of the specified property.
+   * <p>
+   * See the class description for more information about how the
+   * effective property values are derived.
+   *
+   * @param <T>
+   *          The type of the property to be retrieved.
+   * @param d
+   *          The property to be retrieved.
+   * @return Returns the property's effective values, or an empty set
+   *         if there are no effective values defined.
+   * @throws IllegalArgumentException
+   *           If the property definition is not associated with this
+   *           managed object's definition.
+   */
+  <T> SortedSet<T> getPropertyValues(PropertyDefinition<T> d)
+      throws IllegalArgumentException;
+
+
+
+  /**
    * Determines whether or not the optional managed object associated
    * with the specified optional relations exists.
    *
@@ -399,13 +437,19 @@
    * @throws IllegalArgumentException
    *           If the relation definition is not associated with this
    *           managed object's definition.
-   * @throws OperationsException
-   *           If the existance of the optional managed object could
-   *           not be determined due to some underlying communication
-   *           problem.
+   * @throws ConcurrentModificationException
+   *           If this managed object has been removed from the server
+   *           by another client.
+   * @throws AuthorizationException
+   *           If the server refuses to make the determination because
+   *           the client does not have the correct privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
+   *           underlying communication problem.
    */
   boolean hasChild(OptionalRelationDefinition<?, ?> d)
-      throws IllegalArgumentException, OperationsException;
+      throws IllegalArgumentException, ConcurrentModificationException,
+      AuthorizationException, CommunicationException;
 
 
 
@@ -419,12 +463,20 @@
    * @throws IllegalArgumentException
    *           If the relation definition is not associated with this
    *           managed object's definition.
-   * @throws OperationsException
-   *           If the managed objects could not be listed due to some
+   * @throws ConcurrentModificationException
+   *           If this managed object has been removed from the server
+   *           by another client.
+   * @throws AuthorizationException
+   *           If the server refuses to list the managed objects
+   *           because the client does not have the correct
+   *           privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
    *           underlying communication problem.
    */
   String[] listChildren(InstantiableRelationDefinition<?, ?> d)
-      throws IllegalArgumentException, OperationsException;
+      throws IllegalArgumentException, ConcurrentModificationException,
+      AuthorizationException, CommunicationException;
 
 
 
@@ -441,13 +493,30 @@
    * @throws IllegalArgumentException
    *           If the relation definition is not associated with this
    *           managed object's definition.
-   * @throws OperationsException
-   *           If the managed object could not be removed due to some
+   * @throws ManagedObjectNotFoundException
+   *           If the managed object could not be removed because it
+   *           could not found on the server.
+   * @throws OperationRejectedException
+   *           If the server refuses to remove the managed object due
+   *           to some server-side constraint which cannot be
+   *           satisfied (for example, if it is referenced by another
+   *           managed object).
+   * @throws ConcurrentModificationException
+   *           If this managed object has been removed from the server
+   *           by another client.
+   * @throws AuthorizationException
+   *           If the server refuses to make the list the managed
+   *           objects because the client does not have the correct
+   *           privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
    *           underlying communication problem.
    */
   <M extends ConfigurationClient> void removeChild(
       InstantiableRelationDefinition<M, ?> d, String name)
-      throws IllegalArgumentException, OperationsException;
+      throws IllegalArgumentException, ManagedObjectNotFoundException,
+      OperationRejectedException, ConcurrentModificationException,
+      AuthorizationException, CommunicationException;
 
 
 
@@ -462,12 +531,96 @@
    * @throws IllegalArgumentException
    *           If the relation definition is not associated with this
    *           managed object's definition.
-   * @throws OperationsException
-   *           If the managed object could not be removed due to some
+   * @throws ManagedObjectNotFoundException
+   *           If the managed object could not be removed because it
+   *           could not found on the server.
+   * @throws OperationRejectedException
+   *           If the server refuses to remove the managed object due
+   *           to some server-side constraint which cannot be
+   *           satisfied (for example, if it is referenced by another
+   *           managed object).
+   * @throws ConcurrentModificationException
+   *           If this managed object has been removed from the server
+   *           by another client.
+   * @throws AuthorizationException
+   *           If the server refuses to make the list the managed
+   *           objects because the client does not have the correct
+   *           privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
    *           underlying communication problem.
    */
   <M extends ConfigurationClient> void removeChild(
-      OptionalRelationDefinition<M, ?> d)
-      throws IllegalArgumentException, OperationsException;
+      OptionalRelationDefinition<M, ?> d) throws IllegalArgumentException,
+      ManagedObjectNotFoundException, OperationRejectedException,
+      ConcurrentModificationException, AuthorizationException,
+      CommunicationException;
+
+
+
+  /**
+   * Set a new pending value for the specified property.
+   * <p>
+   * See the class description for more information regarding pending
+   * values.
+   *
+   * @param <T>
+   *          The type of the property to be modified.
+   * @param d
+   *          The property to be modified.
+   * @param value
+   *          The new pending value for the property, or
+   *          <code>null</code> if the property should be reset to
+   *          its default behavior.
+   * @throws IllegalPropertyValueException
+   *           If the new pending value is deemed to be invalid
+   *           according to the property definition.
+   * @throws PropertyIsReadOnlyException
+   *           If an attempt was made to modify a read-only property.
+   * @throws PropertyIsMandatoryException
+   *           If an attempt was made to remove a mandatory property.
+   * @throws IllegalArgumentException
+   *           If the specified property definition is not associated
+   *           with this managed object.
+   */
+  <T> void setPropertyValue(PropertyDefinition<T> d, T value)
+      throws IllegalPropertyValueException, PropertyIsReadOnlyException,
+      PropertyIsMandatoryException, IllegalArgumentException;
+
+
+
+  /**
+   * Set a new pending values for the specified property.
+   * <p>
+   * See the class description for more information regarding pending
+   * values.
+   *
+   * @param <T>
+   *          The type of the property to be modified.
+   * @param d
+   *          The property to be modified.
+   * @param values
+   *          A non-<code>null</code> set of new pending values for
+   *          the property (an empty set indicates that the property
+   *          should be reset to its default behavior). The set will
+   *          not be referenced by this managed object.
+   * @throws IllegalPropertyValueException
+   *           If a new pending value is deemed to be invalid
+   *           according to the property definition.
+   * @throws PropertyIsSingleValuedException
+   *           If an attempt was made to add multiple pending values
+   *           to a single-valued property.
+   * @throws PropertyIsReadOnlyException
+   *           If an attempt was made to modify a read-only property.
+   * @throws PropertyIsMandatoryException
+   *           If an attempt was made to remove a mandatory property.
+   * @throws IllegalArgumentException
+   *           If the specified property definition is not associated
+   *           with this managed object.
+   */
+  <T> void setPropertyValues(PropertyDefinition<T> d, Collection<T> values)
+      throws IllegalPropertyValueException, PropertyIsSingleValuedException,
+      PropertyIsReadOnlyException, PropertyIsMandatoryException,
+      IllegalArgumentException;
 
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/OperationRejectedException.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/OperationRejectedException.java
new file mode 100644
index 0000000..0c9a453
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/OperationRejectedException.java
@@ -0,0 +1,94 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.server.admin.client;
+
+
+
+/**
+ * This exception is thrown when the server refuses to create, delete,
+ * or modify a managed object due to some server-side constraint that
+ * cannot be satisified and which cannot be enforced by the client.
+ * <p>
+ * For example, the Directory Server might not be able perform an
+ * operation due to some OS related problem, such as lack of disk
+ * space, or missing files.
+ */
+public class OperationRejectedException extends AdminClientException {
+
+  /**
+   * Serialization ID.
+   */
+  private static final long serialVersionUID = 8547688890613079044L;
+
+
+
+  /**
+   * Create an operation rejected exception.
+   */
+  public OperationRejectedException() {
+    // No implementation required.
+  }
+
+
+
+  /**
+   * Create an operation rejected exception with a cause.
+   *
+   * @param cause
+   *          The cause.
+   */
+  public OperationRejectedException(Throwable cause) {
+    super(cause);
+  }
+
+
+
+  /**
+   * Create an operation rejected exception with a message and cause.
+   *
+   * @param message
+   *          The message.
+   * @param cause
+   *          The cause.
+   */
+  public OperationRejectedException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+
+
+  /**
+   * Create an operation rejected exception with a message.
+   *
+   * @param message
+   *          The message.
+   */
+  public OperationRejectedException(String message) {
+    super(message);
+  }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java
new file mode 100644
index 0000000..1200623
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java
@@ -0,0 +1,239 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.client.ldap;
+
+
+
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.naming.Context;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.InitialLdapContext;
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+
+import org.opends.server.admin.client.AuthenticationException;
+import org.opends.server.admin.client.AuthenticationNotSupportedException;
+import org.opends.server.admin.client.CommunicationException;
+
+
+
+/**
+ * An LDAP connection JNDI connection adaptor. This maps LDAP requests
+ * onto an underlying JNDI connection context.
+ */
+public final class JNDIDirContextAdaptor extends LDAPConnection {
+
+  /**
+   * Adapts the provided JNDI <code>DirContext</code>.
+   *
+   * @param dirContext
+   *          The JNDI connection.
+   * @return Returns a new JNDI connection adaptor.
+   */
+  public static JNDIDirContextAdaptor adapt(DirContext dirContext) {
+    return new JNDIDirContextAdaptor(dirContext);
+  }
+
+
+
+  /**
+   * Creates a new JNDI connection adaptor by performing a simple bind
+   * operation to the specified LDAP server.
+   *
+   * @param host
+   *          The host.
+   * @param port
+   *          The port.
+   * @param name
+   *          The LDAP bind DN.
+   * @param password
+   *          The LDAP bind password.
+   * @return Returns a new JNDI connection adaptor.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
+   *           underlying communication problem.
+   * @throws AuthenticationNotSupportedException
+   *           If the server does not support simple authentication.
+   * @throws AuthenticationException
+   *           If authentication failed for some reason, usually due
+   *           to invalid credentials.
+   */
+  public static JNDIDirContextAdaptor simpleBind(String host, int port,
+      String name, String password) throws CommunicationException,
+      AuthenticationNotSupportedException, AuthenticationException {
+    Hashtable<String, Object> env = new Hashtable<String, Object>();
+    env
+        .put(Context.INITIAL_CONTEXT_FACTORY,
+            "com.sun.jndi.ldap.LdapCtxFactory");
+    env.put(Context.PROVIDER_URL, "ldap://" + host + ":" + port);
+    env.put(Context.SECURITY_PRINCIPAL, name);
+    env.put(Context.SECURITY_CREDENTIALS, password);
+
+    DirContext ctx;
+    try {
+      ctx = new InitialLdapContext(env, null);
+    } catch (javax.naming.CommunicationException e) {
+      throw new CommunicationException(e);
+    } catch (javax.naming.AuthenticationException e) {
+      throw new AuthenticationException(e);
+    } catch (javax.naming.AuthenticationNotSupportedException e) {
+      throw new AuthenticationNotSupportedException(e);
+    } catch (NamingException e) {
+      // Assume some kind of communication problem.
+      throw new CommunicationException(e);
+    }
+
+    return new JNDIDirContextAdaptor(ctx);
+  }
+
+  // The JNDI connection context.
+  private final DirContext dirContext;
+
+
+
+  // Create a new JNDI connection adaptor using the provider JNDI
+  // DirContext.
+  private JNDIDirContextAdaptor(DirContext dirContext) {
+    this.dirContext = dirContext;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void createEntry(LdapName dn, Attributes attributes)
+      throws NamingException {
+    dirContext.createSubcontext(dn, attributes);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void deleteSubtree(LdapName dn) throws NamingException {
+    // Delete the children first.
+    for (LdapName child : listEntries(dn)) {
+      deleteSubtree(child);
+    }
+
+    // Delete the named entry.
+    dirContext.destroySubcontext(dn);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean entryExists(LdapName dn) throws NamingException {
+    String filter = "(objectClass=*)";
+    SearchControls controls = new SearchControls();
+    controls.setSearchScope(SearchControls.OBJECT_SCOPE);
+
+    try {
+      NamingEnumeration<SearchResult> results = dirContext.search(dn, filter,
+          controls);
+      if (results.hasMore()) {
+        return true;
+      }
+    } catch (NameNotFoundException e) {
+      // Fall through - entry not found.
+    }
+    return false;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Collection<LdapName> listEntries(LdapName dn) throws NamingException {
+    String filter = "(objectClass=*)";
+    SearchControls controls = new SearchControls();
+    controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+
+    List<LdapName> children = new LinkedList<LdapName>();
+    NamingEnumeration<SearchResult> results = dirContext.search(dn, filter,
+        controls);
+    while (results.hasMore()) {
+      SearchResult sr = results.next();
+      LdapName child = new LdapName(dn.getRdns());
+      child.add(new Rdn(sr.getName()));
+      children.add(child);
+    }
+
+    return children;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void modifyEntry(LdapName dn, Attributes mods) throws NamingException {
+    ModificationItem[] modList = new ModificationItem[mods.size()];
+    NamingEnumeration<? extends Attribute> ne = mods.getAll();
+    for (int i = 0; ne.hasMore(); i++) {
+      ModificationItem modItem = new ModificationItem(
+          DirContext.REPLACE_ATTRIBUTE, ne.next());
+      modList[i] = modItem;
+    }
+    dirContext.modifyAttributes(dn, modList);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Attributes readEntry(LdapName dn, Collection<String> attrIds)
+      throws NamingException {
+    String[] attrIdList = attrIds.toArray(new String[attrIds.size()]);
+    return dirContext.getAttributes(dn, attrIdList);
+  }
+
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPChangeBuilder.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPChangeBuilder.java
deleted file mode 100644
index 60f41d1..0000000
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPChangeBuilder.java
+++ /dev/null
@@ -1,183 +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/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
- *
- *
- *      Portions Copyright 2007 Sun Microsystems, Inc.
- */
-
-package org.opends.server.admin.client.ldap;
-
-
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-import javax.naming.NamingException;
-import javax.naming.directory.BasicAttribute;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.ModificationItem;
-import javax.naming.ldap.LdapName;
-
-import org.opends.server.admin.LDAPProfile;
-import org.opends.server.admin.ManagedObjectDefinition;
-import org.opends.server.admin.ManagedObjectPath;
-import org.opends.server.admin.OperationsException;
-import org.opends.server.admin.PropertyDefinition;
-import org.opends.server.admin.client.Property;
-
-
-
-/**
- * An LDAP managed object change builder.
- */
-final class LDAPChangeBuilder {
-
-  // The internal representation of the modified list.
-  private final List<ModificationItem> modList;
-
-  // The internal JNDI Dir context.
-  private final DirContext ctx;
-
-  // The managed object path.
-  private final ManagedObjectPath path;
-
-  // The managed object definition.
-  private final ManagedObjectDefinition<?, ?> definition;
-
-  // The LDAP profile to use for attribute name resolution.
-  private final LDAPProfile profile;
-
-
-
-  /**
-   * Create a new LDAP based change builder.
-   *
-   * @param ctx
-   *          The LDAP connection context.
-   * @param path
-   *          The managed object path.
-   * @param definition
-   *          The managed object definition.
-   */
-  public LDAPChangeBuilder(DirContext ctx, ManagedObjectPath path,
-      ManagedObjectDefinition<?, ?> definition) {
-    this.modList = new LinkedList<ModificationItem>();
-    this.ctx = ctx;
-    this.path = path;
-    this.definition = definition;
-    this.profile = LDAPProfile.getInstance();
-  }
-
-
-
-  /**
-   * Update this builder with the set of changes which have been made to the
-   * provided property.
-   *
-   * @param <T>
-   *          The underlying type of the property.
-   * @param property
-   *          The property.
-   */
-  public <T> void addChange(Property<T> property) {
-    PropertyDefinition<T> d = property.getPropertyDefinition();
-    if (property.wasEmpty()) {
-      // Property has been added.
-      addPropertyValues(d, property.getPendingValues());
-    } else if (property.isEmpty()) {
-      // Property has been deleted.
-      deletePropertyValues(d, property.getActiveValues());
-    } else {
-      // Property has been modified.
-      modifyPropertyValues(d, property.getActiveValues(), property
-          .getPendingValues());
-    }
-  }
-
-
-
-  // A property has been added.
-  private <T> void addPropertyValues(
-      PropertyDefinition<T> d, Set<T> newValues) {
-    String attrID = profile.getAttributeName(definition, d);
-    BasicAttribute att = new BasicAttribute(attrID);
-    for (T value : newValues) {
-      att.add(d.encodeValue(value));
-    }
-    ModificationItem mod = new ModificationItem(DirContext.ADD_ATTRIBUTE, att);
-    modList.add(mod);
-  }
-
-
-
-  // Property has been modified.
-  private <T> void modifyPropertyValues(PropertyDefinition<T> d,
-      Set<T> oldValues, Set<T> newValues) {
-    // FIXME: be more sensible here. Only remove the values that need removing,
-    // and only add the values that need adding.
-    String attrID = profile.getAttributeName(definition, d);
-    BasicAttribute att = new BasicAttribute(attrID);
-    for (T value : newValues) {
-      att.add(d.encodeValue(value));
-    }
-    ModificationItem mod = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
-        att);
-    modList.add(mod);
-  }
-
-
-
-  // Property has been deleted.
-  private <T> void deletePropertyValues(PropertyDefinition<T> d,
-      Set<T> oldValues) {
-    String attrID = profile.getAttributeName(definition, d);
-    BasicAttribute att = new BasicAttribute(attrID);
-    ModificationItem mod = new ModificationItem(DirContext.REMOVE_ATTRIBUTE,
-        att);
-    modList.add(mod);
-  }
-
-
-
-  /**
-   * Commit the changes.
-   *
-   * @throws OperationsException
-   *           If the changes to this managed object could not be committed due
-   *           to some underlying communication problem.
-   */
-  public void commit() throws OperationsException {
-    ModificationItem[] mods = modList.toArray(new ModificationItem[modList
-        .size()]);
-    try {
-      LdapName dn = LDAPNameBuilder.create(path);
-      ctx.modifyAttributes(dn, mods);
-    } catch (NamingException e) {
-      OperationsExceptionFactory oef = new OperationsExceptionFactory();
-      throw oef.createException(e);
-    }
-    return;
-  }
-
-}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java
new file mode 100644
index 0000000..8e2adc2
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java
@@ -0,0 +1,140 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.client.ldap;
+
+
+
+import java.util.Collection;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.ldap.LdapName;
+
+
+
+/**
+ * A client connection which is used to perform JNDI-based LDAP
+ * operations.
+ * <p>
+ * This interface is provided in order to make it easier to keep track
+ * of which JNDI DirContext methods we require and also to facilitate
+ * implementation of mock JNDI contexts for unit-testing.
+ */
+public abstract class LDAPConnection {
+
+  /**
+   * Create a new LDAP connection.
+   */
+  protected LDAPConnection() {
+    // No implementation required.
+  }
+
+
+
+  /**
+   * Creates a new entry with the specified set of attributes.
+   *
+   * @param dn
+   *          The name of the entry to be created.
+   * @param attributes
+   *          The set of attributes.
+   * @throws NamingException
+   *           If an error occurred whilst creating the entry.
+   */
+  public abstract void createEntry(LdapName dn, Attributes attributes)
+      throws NamingException;
+
+
+
+  /**
+   * Deletes the named subtree.
+   *
+   * @param dn
+   *          The name of the subtree to be deleted.
+   * @throws NamingException
+   *           If an error occurred whilst deleting the subtree.
+   */
+  public abstract void deleteSubtree(LdapName dn) throws NamingException;
+
+
+
+  /**
+   * Determines whether or not the named entry exists.
+   *
+   * @param dn
+   *          The name of the entry.
+   * @return Returns <code>true</code> if the entry exists.
+   * @throws NamingException
+   *           If an error occurred whilst making the determination.
+   */
+  public abstract boolean entryExists(LdapName dn) throws NamingException;
+
+
+
+  /**
+   * Lists the children of the named entry.
+   *
+   * @param dn
+   *          The name of the entry to list.
+   * @return Returns the names of the children.
+   * @throws NamingException
+   *           If an error occurred whilst listing the children.
+   */
+  public abstract Collection<LdapName> listEntries(LdapName dn)
+      throws NamingException;
+
+
+
+  /**
+   * Modifies the attributes of the named entry.
+   *
+   * @param dn
+   *          The name of the entry to be modified.
+   * @param mods
+   *          The list of attributes which need replacing.
+   * @throws NamingException
+   *           If an error occurred whilst applying the modifications.
+   */
+  public abstract void modifyEntry(LdapName dn, Attributes mods)
+      throws NamingException;
+
+
+
+  /**
+   * Reads the attributes of the named entry.
+   *
+   * @param dn
+   *          The name of the entry to be read.
+   * @param attrIds
+   *          The list of attributes to be retrievd.
+   * @return Returns the attributes of the requested entry.
+   * @throws NamingException
+   *           If an error occurred whilst reading the entry.
+   */
+  public abstract Attributes readEntry(LdapName dn, Collection<String> attrIds)
+      throws NamingException;
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
index d95a896..d2f3d56 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
@@ -31,22 +31,23 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 import java.util.SortedSet;
 
+import javax.naming.NameAlreadyBoundException;
 import javax.naming.NameNotFoundException;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
+import javax.naming.NoPermissionException;
+import javax.naming.OperationNotSupportedException;
 import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
 import javax.naming.directory.BasicAttribute;
 import javax.naming.directory.BasicAttributes;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.SearchControls;
-import javax.naming.directory.SearchResult;
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
 
@@ -57,8 +58,9 @@
 import org.opends.server.admin.IllegalPropertyValueException;
 import org.opends.server.admin.InheritedDefaultValueProvider;
 import org.opends.server.admin.InstantiableRelationDefinition;
-import org.opends.server.admin.LDAPProfile;
+import org.opends.server.admin.ManagedObjectAlreadyExistsException;
 import org.opends.server.admin.ManagedObjectDefinition;
+import org.opends.server.admin.ManagedObjectNotFoundException;
 import org.opends.server.admin.ManagedObjectPath;
 import org.opends.server.admin.OperationsException;
 import org.opends.server.admin.OptionalRelationDefinition;
@@ -73,8 +75,12 @@
 import org.opends.server.admin.SingletonRelationDefinition;
 import org.opends.server.admin.StringPropertyProvider;
 import org.opends.server.admin.DefinitionDecodingException.Reason;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ConcurrentModificationException;
 import org.opends.server.admin.client.ManagedObject;
 import org.opends.server.admin.client.ManagedObjectDecodingException;
+import org.opends.server.admin.client.OperationRejectedException;
 import org.opends.server.admin.client.Property;
 import org.opends.server.admin.client.PropertySet;
 import org.opends.server.admin.std.client.RootCfgClient;
@@ -89,8 +95,8 @@
  *          The type of client configuration represented by the client
  *          managed object.
  */
-final class LDAPManagedObject<C extends ConfigurationClient>
-    implements ManagedObject<C> {
+final class LDAPManagedObject<C extends ConfigurationClient> implements
+    ManagedObject<C> {
 
   /**
    * Internal inherited default value provider implementation.
@@ -98,25 +104,25 @@
   private static class MyInheritedDefaultValueProvider implements
       InheritedDefaultValueProvider {
 
+    // The LDAP management context.
+    private final LDAPManagementContext context;
+
     // The base path.
     private final ManagedObjectPath path;
 
-    // The LDAP connection context.
-    private final DirContext dirContext;
-
 
 
     /**
      * Create a new inherited default value provider.
      *
-     * @param dirContext
-     *          The LDAP connection context.
+     * @param context
+     *          The LDAP management context.
      * @param path
      *          The base path.
      */
-    public MyInheritedDefaultValueProvider(DirContext dirContext,
+    public MyInheritedDefaultValueProvider(LDAPManagementContext context,
         ManagedObjectPath path) {
-      this.dirContext = dirContext;
+      this.context = context;
       this.path = path;
     }
 
@@ -125,18 +131,22 @@
     /**
      * {@inheritDoc}
      */
-    public Collection<?> getDefaultPropertyValues(
-        ManagedObjectPath path, String propertyName)
-        throws OperationsException, PropertyNotFoundException {
+    public Collection<?> getDefaultPropertyValues(ManagedObjectPath path,
+        String propertyName) throws OperationsException,
+        PropertyNotFoundException {
       ManagedObjectPath<?, ?> tmp = path;
-      ManagedObject<?> mo = readEntry(dirContext, tmp, tmp
-          .getManagedObjectDefinition());
-      ManagedObjectDefinition<?, ?> mod = mo
-          .getManagedObjectDefinition();
+      ManagedObject<?> mo;
+      try {
+        mo = readEntry(context, tmp, tmp.getManagedObjectDefinition());
+      } catch (AuthorizationException e) {
+        throw new OperationsException(e);
+      } catch (CommunicationException e) {
+        throw new OperationsException(e);
+      }
+      ManagedObjectDefinition<?, ?> mod = mo.getManagedObjectDefinition();
 
       try {
-        PropertyDefinition<?> dpd = mod
-            .getPropertyDefinition(propertyName);
+        PropertyDefinition<?> dpd = mod.getPropertyDefinition(propertyName);
         return mo.getPropertyValues(dpd);
       } catch (IllegalArgumentException e) {
         throw new PropertyNotFoundException(propertyName);
@@ -159,19 +169,18 @@
    * Construct a root LDAP managed object associated with the provided
    * LDAP context.
    *
-   * @param dirContext
-   *          The LDAP directory context.
+   * @param context
+   *          The LDAP management context.
    * @return Returns a root LDAP managed object associated with the
    *         provided LDAP context.
    */
   static ManagedObject<RootCfgClient> getRootManagedObject(
-      DirContext dirContext) {
+      LDAPManagementContext context) {
     List<PropertyException> exceptions = new LinkedList<PropertyException>();
     InheritedDefaultValueProvider i = new MyInheritedDefaultValueProvider(
-        dirContext, ManagedObjectPath.emptyPath());
-    PropertySet properties = PropertySet.create(RootCfgDefn
-        .getInstance(), PropertyProvider.DEFAULT_PROVIDER, i,
-        exceptions);
+        context, ManagedObjectPath.emptyPath());
+    PropertySet properties = PropertySet.create(RootCfgDefn.getInstance(),
+        PropertyProvider.DEFAULT_PROVIDER, i, exceptions);
 
     // Should never get any exceptions.
     if (!exceptions.isEmpty()) {
@@ -179,37 +188,18 @@
           "Got exceptions when creating root managed object");
     }
 
-    return new LDAPManagedObject<RootCfgClient>(dirContext,
-        RootCfgDefn.getInstance(), ManagedObjectPath.emptyPath(),
-        properties);
+    return new LDAPManagedObject<RootCfgClient>(context, RootCfgDefn
+        .getInstance(), ManagedObjectPath.emptyPath(), properties);
   }
 
 
 
   // Create a new child LDAP managed object.
   private static <M extends ConfigurationClient>
-    ManagedObject<M> createLDAPManagedObject(
-      DirContext dirContext, ManagedObjectDefinition<M, ?> d,
+      ManagedObject<M> createLDAPManagedObject(
+      LDAPManagementContext context, ManagedObjectDefinition<M, ?> d,
       ManagedObjectPath p, PropertySet properties) {
-    return new LDAPManagedObject<M>(dirContext, d, p, properties);
-  }
-
-
-
-  // Get an array containing the list of LDAP attributes names
-  // associated with a
-  // managed object definition.
-  private static String[] getAttributeNames(
-      ManagedObjectDefinition<?, ?> d) {
-    ArrayList<String> attrIds = new ArrayList<String>();
-
-    for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
-      String attrId = LDAPProfile.getInstance().getAttributeName(d,
-          pd);
-      attrIds.add(attrId);
-    }
-
-    return attrIds.toArray(new String[attrIds.size()]);
+    return new LDAPManagedObject<M>(context, d, p, properties);
   }
 
 
@@ -218,86 +208,85 @@
   // entry.
   private static <M extends ConfigurationClient>
       ManagedObjectDefinition<? extends M, ?> getEntryDefinition(
-      DirContext dirContext, AbstractManagedObjectDefinition<M, ?> d,
-      LdapName dn) throws OperationsException {
-    try {
-      String[] attrIds = new String[] { "objectclass" };
-      Attributes attributes = dirContext.getAttributes(dn, attrIds);
-      Attribute oc = attributes.get("objectclass");
+      final LDAPManagementContext context,
+      AbstractManagedObjectDefinition<M, ?> d, LdapName dn)
+      throws NamingException, DefinitionDecodingException {
+    Attributes attributes = context.getLDAPConnection().readEntry(dn,
+        Collections.singleton("objectclass"));
+    Attribute oc = attributes.get("objectclass");
 
-      if (oc == null) {
-        // No object classes.
-        throw new DefinitionDecodingException(
-            Reason.NO_TYPE_INFORMATION);
-      }
-
-      final Set<String> objectClasses = new HashSet<String>();
-      NamingEnumeration<?> values = oc.getAll();
-      while (values.hasMore()) {
-        Object value = values.next();
-        if (value != null) {
-          objectClasses.add(value.toString().toLowerCase().trim());
-        }
-      }
-
-      if (objectClasses.isEmpty()) {
-        // No object classes.
-        throw new DefinitionDecodingException(
-            Reason.NO_TYPE_INFORMATION);
-      }
-
-      // Resolve the appropriate sub-type based on the object classes.
-      DefinitionResolver resolver = new DefinitionResolver() {
-
-        public boolean matches(AbstractManagedObjectDefinition<?, ?> d) {
-          String objectClass = LDAPProfile.getInstance()
-              .getObjectClass(d);
-          return objectClasses.contains(objectClass);
-        }
-
-      };
-
-      return d.resolveManagedObjectDefinition(resolver);
-    } catch (NamingException e) {
-      OperationsExceptionFactory oef = new OperationsExceptionFactory();
-      throw oef.createException(e);
+    if (oc == null) {
+      // No object classes.
+      throw new DefinitionDecodingException(Reason.NO_TYPE_INFORMATION);
     }
+
+    final Set<String> objectClasses = new HashSet<String>();
+    NamingEnumeration<?> values = oc.getAll();
+    while (values.hasMore()) {
+      Object value = values.next();
+      if (value != null) {
+        objectClasses.add(value.toString().toLowerCase().trim());
+      }
+    }
+
+    if (objectClasses.isEmpty()) {
+      // No object classes.
+      throw new DefinitionDecodingException(Reason.NO_TYPE_INFORMATION);
+    }
+
+    // Resolve the appropriate sub-type based on the object classes.
+    DefinitionResolver resolver = new DefinitionResolver() {
+
+      public boolean matches(AbstractManagedObjectDefinition<?, ?> d) {
+        String objectClass = context.getLDAPProfile().getObjectClass(d);
+        return objectClasses.contains(objectClass);
+      }
+
+    };
+
+    return d.resolveManagedObjectDefinition(resolver);
   }
 
 
 
   // Read the entry identified by the path and which is a sub-type of
-  // the
-  // specified definition.
+  // the specified definition.
   private static <M extends ConfigurationClient>
       ManagedObject<? extends M> readEntry(
-      DirContext dirContext, ManagedObjectPath p,
+      final LDAPManagementContext context, ManagedObjectPath p,
       AbstractManagedObjectDefinition<M, ?> d)
-      throws OperationsException {
-    LdapName dn = LDAPNameBuilder.create(p);
-    final ManagedObjectDefinition<? extends M, ?> mod = getEntryDefinition(
-        dirContext, d, dn);
-    String[] attrIds = getAttributeNames(mod);
+      throws DefinitionDecodingException, ManagedObjectDecodingException,
+      ManagedObjectNotFoundException, AuthorizationException,
+      CommunicationException {
+    LdapName dn = LDAPNameBuilder.create(p, context.getLDAPProfile());
 
+    final ManagedObjectDefinition<? extends M, ?> mod;
     final Attributes attributes;
     try {
-      attributes = dirContext.getAttributes(dn, attrIds);
+      mod = getEntryDefinition(context, d, dn);
+      ArrayList<String> attrIds = new ArrayList<String>();
+      for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
+        String attrId = context.getLDAPProfile().getAttributeName(mod, pd);
+        attrIds.add(attrId);
+      }
+      attributes = context.getLDAPConnection().readEntry(dn, attrIds);
+    } catch (NameNotFoundException e) {
+      throw new ManagedObjectNotFoundException();
+    } catch (NoPermissionException e) {
+      throw new AuthorizationException(e);
     } catch (NamingException e) {
-      OperationsExceptionFactory factory = new OperationsExceptionFactory();
-      throw factory.createException(e);
+      throw new CommunicationException(e);
     }
 
     // Create a provider which uses LDAP string representations.
 
     // TODO: the exception handling is a bit of a hack here.
-    final List<OperationsException> oelist =
-      new LinkedList<OperationsException>();
+    final List<NamingException> nelist = new LinkedList<NamingException>();
     StringPropertyProvider provider = new StringPropertyProvider() {
 
-      public Collection<String> getPropertyValues(
-          PropertyDefinition<?> d) throws IllegalArgumentException {
-        String attrID = LDAPProfile.getInstance().getAttributeName(
-            mod, d);
+      public Collection<String> getPropertyValues(PropertyDefinition<?> d)
+          throws IllegalArgumentException {
+        String attrID = context.getLDAPProfile().getAttributeName(mod, d);
         Attribute attribute = attributes.get(attrID);
         List<String> values = new LinkedList<String>();
 
@@ -311,8 +300,7 @@
               }
             }
           } catch (NamingException e) {
-            OperationsExceptionFactory oef = new OperationsExceptionFactory();
-            oelist.add(oef.createException(e));
+            nelist.add(e);
           }
         }
 
@@ -321,23 +309,29 @@
 
     };
 
-    // There can only be at most one operations exception.
-    if (!oelist.isEmpty()) {
-      throw oelist.get(0);
+    // There can only be at most one exception.
+    if (!nelist.isEmpty()) {
+      try {
+        throw nelist.get(0);
+      } catch (NameNotFoundException e) {
+        throw new ManagedObjectNotFoundException();
+      } catch (NoPermissionException e) {
+        throw new AuthorizationException(e);
+      } catch (NamingException e) {
+        throw new CommunicationException(e);
+      }
     }
 
     // Now decode the properties using the provider.
     List<PropertyException> exceptions = new LinkedList<PropertyException>();
     InheritedDefaultValueProvider i = new MyInheritedDefaultValueProvider(
-        dirContext, p);
-    PropertySet properties = PropertySet.create(mod, provider, i,
-        exceptions);
-    ManagedObject<? extends M> mo = createLDAPManagedObject(
-        dirContext, mod, p, properties);
+        context, p);
+    PropertySet properties = PropertySet.create(mod, provider, i, exceptions);
+    ManagedObject<? extends M> mo = createLDAPManagedObject(context, mod, p,
+        properties);
 
     // If there were no decoding problems then return the object,
-    // otherwise
-    // throw an operations exception.
+    // otherwise throw an operations exception.
     if (exceptions.isEmpty()) {
       return mo;
     } else {
@@ -345,32 +339,28 @@
     }
   }
 
-  // The JNDI context used for the ldap connection.
-  private final DirContext dirContext;
-
-  // The path associated with this managed object.
-  private final ManagedObjectPath<?, ?> path;
-
-  // LDAP profile associated with this connection.
-  private final LDAPProfile profile;
-
   // The managed object definition associated with this managed
   // object.
   private final ManagedObjectDefinition<C, ?> definition;
 
+  // The LDAP management context used for the ldap connection.
+  private final LDAPManagementContext context;
+
+  // The path associated with this managed object.
+  private final ManagedObjectPath<?, ?> path;
+
   // The managed object's properties.
   private final PropertySet properties;
 
 
 
   // Create an new LDAP managed object with the provided JNDI context.
-  private LDAPManagedObject(DirContext dirContext,
+  private LDAPManagedObject(LDAPManagementContext context,
       ManagedObjectDefinition<C, ?> d, ManagedObjectPath path,
       PropertySet properties) {
     this.definition = d;
-    this.dirContext = dirContext;
+    this.context = context;
     this.path = path;
-    this.profile = LDAPProfile.getInstance();
     this.properties = properties;
   }
 
@@ -379,19 +369,37 @@
   /**
    * {@inheritDoc}
    */
-  public void commit() throws OperationsException {
+  public void commit() throws ConcurrentModificationException,
+      OperationRejectedException, AuthorizationException,
+      CommunicationException {
+    // Build the list of modified attributes.
     ManagedObjectDefinition<C, ?> d = getManagedObjectDefinition();
-    LDAPChangeBuilder builder = new LDAPChangeBuilder(dirContext,
-        path, d);
+    Attributes mods = new BasicAttributes();
     for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
-      // FIXME: should throw an error when there are missing mandatory
-      // properties.
       Property<?> p = properties.getProperty(pd);
       if (p.isModified()) {
-        builder.addChange(p);
+        String attrID = context.getLDAPProfile().getAttributeName(d, pd);
+        Attribute attribute = new BasicAttribute(attrID);
+        encodeProperty(attribute, pd, properties);
+        mods.put(attribute);
       }
     }
-    builder.commit();
+
+    // Perform the LDAP modification if something has changed.
+    if (mods.size() > 0) {
+      try {
+        LdapName dn = LDAPNameBuilder.create(path, context.getLDAPProfile());
+        context.getLDAPConnection().modifyEntry(dn, mods);
+      } catch (NoPermissionException e) {
+        throw new AuthorizationException(e);
+      } catch (OperationNotSupportedException e) {
+        // Unwilling to perform.
+        throw new OperationRejectedException(e);
+      } catch (NamingException e) {
+        // Just treat it as a communication problem.
+        throw new CommunicationException(e);
+      }
+    }
   }
 
 
@@ -401,9 +409,11 @@
    */
   public <M extends ConfigurationClient, N extends M>
       ManagedObject<N> createChild(
-      InstantiableRelationDefinition<M, ?> r,
-      ManagedObjectDefinition<N, ?> d, String name, PropertyProvider p)
-      throws IllegalArgumentException, OperationsException {
+      InstantiableRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
+      String name, PropertyProvider p) throws IllegalArgumentException,
+      ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,
+      ConcurrentModificationException, OperationRejectedException,
+      AuthorizationException, CommunicationException {
     validateRelationDefinition(r);
 
     ManagedObjectPath childPath = path.child(r, name);
@@ -411,43 +421,46 @@
     // First make sure all the properties are valid.
     List<PropertyException> exceptions = new LinkedList<PropertyException>();
     InheritedDefaultValueProvider i = new MyInheritedDefaultValueProvider(
-        dirContext, childPath);
+        context, childPath);
     PropertySet properties = PropertySet.create(d, p, i, exceptions);
     if (!exceptions.isEmpty()) {
-      ManagedObject<N> mo = new LDAPManagedObject<N>(dirContext, d,
-          childPath, properties);
+      ManagedObject<N> mo = new LDAPManagedObject<N>(context, d, childPath,
+          properties);
       throw new ManagedObjectDecodingException(mo, exceptions);
     }
 
-    try {
-      // TODO: this implementation does not handle relations which
-      // comprise of more than one RDN arc (this will probably never
-      // be required anyway).
-      LdapName dn = LDAPNameBuilder.create(path, r);
+    ensureThisManagedObjectExists();
 
-      if (!entryExists(dn)) {
-        // Need to create the child managed object's parent entry i.e.
-        // the entry representing the relation itself.
-        Attributes attributes = new BasicAttributes();
+    // TODO: this implementation does not handle relations which
+    // comprise of more than one RDN arc (this will probably never
+    // be required anyway).
+    LdapName dn = LDAPNameBuilder.create(path, r, context.getLDAPProfile());
+    if (!entryExists(dn)) {
+      // Need to create the child managed object's parent entry i.e.
+      // the entry representing the relation itself.
+      Attributes attributes = new BasicAttributes();
 
-        // Create the branch's object class attribute.
-        Attribute oc = new BasicAttribute("objectClass");
-        for (String objectClass : profile
-            .getInstantiableRelationObjectClasses(r)) {
-          oc.add(objectClass);
-        }
-        attributes.put(oc);
-
-        // Create the branch's naming attribute.
-        Rdn rdn = dn.getRdn(dn.size() - 1);
-        attributes.put(rdn.getType(), rdn.getValue().toString());
-
-        // Create the entry.
-        dirContext.createSubcontext(dn, attributes);
+      // Create the branch's object class attribute.
+      Attribute oc = new BasicAttribute("objectClass");
+      for (String objectClass : context.getLDAPProfile()
+          .getInstantiableRelationObjectClasses(r)) {
+        oc.add(objectClass);
       }
-    } catch (NamingException e) {
-      OperationsExceptionFactory oef = new OperationsExceptionFactory();
-      throw oef.createException(e);
+      attributes.put(oc);
+
+      // Create the branch's naming attribute.
+      Rdn rdn = dn.getRdn(dn.size() - 1);
+      attributes.put(rdn.getType(), rdn.getValue().toString());
+
+      // Create the entry.
+      try {
+        context.getLDAPConnection().createEntry(dn, attributes);
+      } catch (OperationNotSupportedException e) {
+        // Unwilling to perform.
+        throw new OperationRejectedException(e);
+      } catch (NamingException e) {
+        adaptNamingException(e);
+      }
     }
 
     return createManagedObject(childPath, d, properties);
@@ -460,9 +473,11 @@
    */
   public <M extends ConfigurationClient, N extends M>
       ManagedObject<N> createChild(
-      OptionalRelationDefinition<M, ?> r,
-      ManagedObjectDefinition<N, ?> d, PropertyProvider p)
-      throws IllegalArgumentException, OperationsException {
+      OptionalRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
+      PropertyProvider p) throws IllegalArgumentException,
+      ManagedObjectDecodingException, ManagedObjectAlreadyExistsException,
+      ConcurrentModificationException, OperationRejectedException,
+      AuthorizationException, CommunicationException {
     validateRelationDefinition(r);
 
     ManagedObjectPath childPath = path.child(r);
@@ -470,14 +485,16 @@
     // First make sure all the properties are valid.
     List<PropertyException> exceptions = new LinkedList<PropertyException>();
     InheritedDefaultValueProvider i = new MyInheritedDefaultValueProvider(
-        dirContext, childPath);
+        context, childPath);
     PropertySet properties = PropertySet.create(d, p, i, exceptions);
     if (!exceptions.isEmpty()) {
-      ManagedObject<N> mo = new LDAPManagedObject<N>(dirContext, d,
-          childPath, properties);
+      ManagedObject<N> mo = new LDAPManagedObject<N>(context, d, childPath,
+          properties);
       throw new ManagedObjectDecodingException(mo, exceptions);
     }
 
+    ensureThisManagedObjectExists();
+
     return createManagedObject(childPath, d, properties);
   }
 
@@ -488,10 +505,13 @@
    */
   public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
       InstantiableRelationDefinition<M, ?> d, String name)
-      throws IllegalArgumentException, OperationsException {
+      throws IllegalArgumentException, DefinitionDecodingException,
+      ManagedObjectDecodingException, ManagedObjectNotFoundException,
+      ConcurrentModificationException, AuthorizationException,
+      CommunicationException {
     validateRelationDefinition(d);
-    return readEntry(dirContext, path.child(d, name), d
-        .getChildDefinition());
+    ensureThisManagedObjectExists();
+    return readEntry(context, path.child(d, name), d.getChildDefinition());
   }
 
 
@@ -500,11 +520,13 @@
    * {@inheritDoc}
    */
   public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
-      OptionalRelationDefinition<M, ?> d)
-      throws IllegalArgumentException, OperationsException {
+      OptionalRelationDefinition<M, ?> d) throws IllegalArgumentException,
+      DefinitionDecodingException, ManagedObjectDecodingException,
+      ManagedObjectNotFoundException, ConcurrentModificationException,
+      AuthorizationException, CommunicationException {
     validateRelationDefinition(d);
-    return readEntry(dirContext, path.child(d), d
-        .getChildDefinition());
+    ensureThisManagedObjectExists();
+    return readEntry(context, path.child(d), d.getChildDefinition());
   }
 
 
@@ -513,11 +535,13 @@
    * {@inheritDoc}
    */
   public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
-      SingletonRelationDefinition<M, ?> d)
-      throws IllegalArgumentException, OperationsException {
+      SingletonRelationDefinition<M, ?> d) throws IllegalArgumentException,
+      DefinitionDecodingException, ManagedObjectDecodingException,
+      ManagedObjectNotFoundException, ConcurrentModificationException,
+      AuthorizationException, CommunicationException {
     validateRelationDefinition(d);
-    return readEntry(dirContext, path.child(d), d
-        .getChildDefinition());
+    ensureThisManagedObjectExists();
+    return readEntry(context, path.child(d), d.getChildDefinition());
   }
 
 
@@ -573,17 +597,14 @@
    * {@inheritDoc}
    */
   public boolean hasChild(OptionalRelationDefinition<?, ?> d)
-      throws IllegalArgumentException, OperationsException {
+      throws IllegalArgumentException, ConcurrentModificationException,
+      AuthorizationException, CommunicationException {
     validateRelationDefinition(d);
+    ensureThisManagedObjectExists();
 
     ManagedObjectPath p = path.child(d);
-    LdapName dn = LDAPNameBuilder.create(p);
-    try {
-      return entryExists(dn);
-    } catch (NamingException e) {
-      OperationsExceptionFactory oef = new OperationsExceptionFactory();
-      throw oef.createException(e);
-    }
+    LdapName dn = LDAPNameBuilder.create(p, context.getLDAPProfile());
+    return entryExists(dn);
   }
 
 
@@ -592,35 +613,25 @@
    * {@inheritDoc}
    */
   public String[] listChildren(InstantiableRelationDefinition<?, ?> d)
-      throws IllegalArgumentException, OperationsException {
+      throws IllegalArgumentException, ConcurrentModificationException,
+      AuthorizationException, CommunicationException {
     validateRelationDefinition(d);
+    ensureThisManagedObjectExists();
 
-    LdapName dn = LDAPNameBuilder.create(path, d);
-
-    String filter = profile.getFilter(d.getChildDefinition());
-    SearchControls controls = new SearchControls();
-    controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
-
+    List<String> children = new ArrayList<String>();
+    LdapName dn = LDAPNameBuilder.create(path, d, context.getLDAPProfile());
     try {
-      NamingEnumeration<SearchResult> results;
-      results = dirContext.search(dn, filter, controls);
-
-      String rtype = profile.getInstantiableRelationChildRDNType(d);
-      List<String> names = new ArrayList<String>();
-      while (results.hasMore()) {
-        SearchResult sr = results.next();
-        Attributes attributes = sr.getAttributes();
-        Attribute cn = attributes.get(rtype);
-        if (cn != null && cn.get() != null) {
-          names.add(cn.get().toString());
-        }
+      for (LdapName child : context.getLDAPConnection().listEntries(dn)) {
+        children.add(child.getRdn(child.size() - 1).getValue().toString());
       }
-
-      return names.toArray(new String[names.size()]);
+    } catch (NameNotFoundException e) {
+      // Ignore this - it means that the base entry does not exist
+      // (which it might not if this managed object has just been
+      // created.
     } catch (NamingException e) {
-      OperationsExceptionFactory oef = new OperationsExceptionFactory();
-      throw oef.createException(e);
+      adaptNamingException(e);
     }
+    return children.toArray(new String[children.size()]);
   }
 
 
@@ -630,9 +641,11 @@
    */
   public <M extends ConfigurationClient> void removeChild(
       InstantiableRelationDefinition<M, ?> d, String name)
-      throws IllegalArgumentException, OperationsException {
+      throws IllegalArgumentException, ManagedObjectNotFoundException,
+      OperationRejectedException, ConcurrentModificationException,
+      AuthorizationException, CommunicationException {
     validateRelationDefinition(d);
-
+    ensureThisManagedObjectExists();
     ManagedObjectPath p = path.child(d, name);
     removeManagedObject(p);
   }
@@ -643,10 +656,12 @@
    * {@inheritDoc}
    */
   public <M extends ConfigurationClient> void removeChild(
-      OptionalRelationDefinition<M, ?> d)
-      throws IllegalArgumentException, OperationsException {
+      OptionalRelationDefinition<M, ?> d) throws IllegalArgumentException,
+      ManagedObjectNotFoundException, OperationRejectedException,
+      ConcurrentModificationException, AuthorizationException,
+      CommunicationException {
     validateRelationDefinition(d);
-
+    ensureThisManagedObjectExists();
     ManagedObjectPath p = path.child(d);
     removeManagedObject(p);
   }
@@ -657,9 +672,8 @@
    * {@inheritDoc}
    */
   public <T> void setPropertyValue(PropertyDefinition<T> d, T value)
-      throws IllegalPropertyValueException,
-      PropertyIsReadOnlyException, PropertyIsMandatoryException,
-      IllegalArgumentException {
+      throws IllegalPropertyValueException, PropertyIsReadOnlyException,
+      PropertyIsMandatoryException, IllegalArgumentException {
     properties.setPropertyValue(d, value);
   }
 
@@ -677,17 +691,39 @@
 
 
 
+  // Adapts a naming exception to an appropriate admin client
+  // exception.
+  private void adaptNamingException(NamingException ne)
+      throws CommunicationException, AuthorizationException {
+    try {
+      throw ne;
+    } catch (javax.naming.CommunicationException e) {
+      throw new CommunicationException(e);
+    } catch (javax.naming.ServiceUnavailableException e) {
+      throw new CommunicationException(e);
+    } catch (javax.naming.NoPermissionException e) {
+      throw new AuthorizationException(e);
+    } catch (NamingException e) {
+      // Just treat it as a communication problem.
+      throw new CommunicationException(e);
+    }
+  }
+
+
+
   // Creates a new managed object. The parent LDAP entry is assumed to
   // already exist.
   private <N extends ConfigurationClient> ManagedObject<N> createManagedObject(
       ManagedObjectPath path, ManagedObjectDefinition<N, ?> d,
-      PropertySet properties) throws OperationsException {
-    LdapName dn = LDAPNameBuilder.create(path);
-    Attributes attributes = new BasicAttributes();
+      PropertySet properties) throws ManagedObjectAlreadyExistsException,
+      OperationRejectedException, AuthorizationException,
+      CommunicationException {
+    LdapName dn = LDAPNameBuilder.create(path, context.getLDAPProfile());
+    Attributes attributes = new BasicAttributes(true);
 
     // Create the child's object class attribute.
-    Attribute oc = new BasicAttribute("objectClass");
-    for (String objectClass : profile.getObjectClasses(d)) {
+    Attribute oc = new BasicAttribute("objectclass");
+    for (String objectClass : context.getLDAPProfile().getObjectClasses(d)) {
       oc.add(objectClass);
     }
     attributes.put(oc);
@@ -698,7 +734,7 @@
 
     // Create the remaining attributes.
     for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
-      String attrID = profile.getAttributeName(d, pd);
+      String attrID = context.getLDAPProfile().getAttributeName(d, pd);
       Attribute attribute = new BasicAttribute(attrID);
       encodeProperty(attribute, pd, properties);
       if (attribute.size() != 0) {
@@ -708,37 +744,17 @@
 
     try {
       // Create the entry.
-      dirContext.createSubcontext(dn, attributes);
+      context.getLDAPConnection().createEntry(dn, attributes);
+    } catch (NameAlreadyBoundException e) {
+      throw new ManagedObjectAlreadyExistsException();
+    } catch (OperationNotSupportedException e) {
+      // Unwilling to perform.
+      throw new OperationRejectedException(e);
     } catch (NamingException e) {
-      OperationsExceptionFactory oef = new OperationsExceptionFactory();
-      throw oef.createException(e);
+      adaptNamingException(e);
     }
 
-    return new LDAPManagedObject<N>(dirContext, d, path, properties);
-  }
-
-
-
-  // Recursively delete a subtree of entries.
-  private void destroySubtree(LdapName dn) throws NamingException {
-    // List the child entries.
-    String filter = "(objectClass=*)";
-    SearchControls controls = new SearchControls();
-    controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
-
-    NamingEnumeration<SearchResult> results;
-    results = dirContext.search(dn, filter, controls);
-
-    // Recursively delete child entries.
-    while (results.hasMore()) {
-      SearchResult sr = results.next();
-      LdapName child = new LdapName(dn.getRdns());
-      child.add(new Rdn(sr.getName()));
-      destroySubtree(child);
-    }
-
-    // Delete the specified entry.
-    dirContext.destroySubcontext(dn);
+    return new LDAPManagedObject<N>(context, d, path, properties);
   }
 
 
@@ -746,32 +762,35 @@
   // Encode a property into LDAP string values.
   private <T> void encodeProperty(Attribute attribute,
       PropertyDefinition<T> pd, PropertySet properties) {
-    for (T value : properties.getPropertyValues(pd)) {
+    Property<T> p = properties.getProperty(pd);
+    for (T value : p.getPendingValues()) {
       attribute.add(pd.encodeValue(value));
     }
   }
 
 
 
-  // Determine whether the named entry exists or not.
-  private boolean entryExists(LdapName dn) throws NamingException {
-    String filter = "(objectClass=*)";
-    SearchControls controls = new SearchControls();
-    controls.setSearchScope(SearchControls.OBJECT_SCOPE);
-
-    try {
-      NamingEnumeration<SearchResult> results = dirContext.search(dn,
-          filter, controls);
-      if (results.hasMore()) {
-        // TODO: should really verify that the relation entry has
-        // the correct object classes, etc. It definitely has the
-        // correct name, which is ok.
-        return true;
-      }
-    } catch (NameNotFoundException e) {
-      // Fall through - parent not found.
+  // Makes sure that the entry corresponding to this managed object
+  // exists.
+  private void ensureThisManagedObjectExists()
+      throws ConcurrentModificationException, CommunicationException,
+      AuthorizationException {
+    LdapName dn = LDAPNameBuilder.create(path, context.getLDAPProfile());
+    if (!entryExists(dn)) {
+      throw new ConcurrentModificationException();
     }
+  }
 
+
+
+  // Determine whether the named entry exists or not.
+  private boolean entryExists(LdapName dn) throws CommunicationException,
+      AuthorizationException {
+    try {
+      return context.getLDAPConnection().entryExists(dn);
+    } catch (NamingException e) {
+      adaptNamingException(e);
+    }
     return false;
   }
 
@@ -779,16 +798,19 @@
 
   // Remove the named managed object.
   private void removeManagedObject(ManagedObjectPath p)
-      throws OperationsException {
-    try {
-      LdapName dn = LDAPNameBuilder.create(p);
-      if (entryExists(dn)) {
-        // Delete the entry and any subordinate entries.
-        destroySubtree(dn);
+      throws CommunicationException, AuthorizationException,
+      OperationRejectedException {
+    LdapName dn = LDAPNameBuilder.create(p, context.getLDAPProfile());
+    if (entryExists(dn)) {
+      // Delete the entry and any subordinate entries.
+      try {
+        context.getLDAPConnection().deleteSubtree(dn);
+      } catch (OperationNotSupportedException e) {
+        // Unwilling to perform.
+        throw new OperationRejectedException(e);
+      } catch (NamingException e) {
+        adaptNamingException(e);
       }
-    } catch (NamingException e) {
-      OperationsExceptionFactory oef = new OperationsExceptionFactory();
-      throw oef.createException(e);
     }
   }
 
@@ -801,8 +823,8 @@
     ManagedObjectDefinition d = getManagedObjectDefinition();
     RelationDefinition tmp = d.getRelationDefinition(rd.getName());
     if (tmp != rd) {
-      throw new IllegalArgumentException("The relation "
-          + rd.getName() + " is not associated with a " + d.getName());
+      throw new IllegalArgumentException("The relation " + rd.getName()
+          + " is not associated with a " + d.getName());
     }
   }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java
index 37bc258..6b191f0 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java
@@ -29,16 +29,11 @@
 
 
 
-import java.util.Hashtable;
-
-import javax.naming.Context;
-import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
-import javax.naming.ldap.InitialLdapContext;
-
+import org.opends.server.admin.LDAPProfile;
 import org.opends.server.admin.client.ManagedObject;
 import org.opends.server.admin.client.ManagementContext;
 import org.opends.server.admin.std.client.RootCfgClient;
+import org.opends.server.util.Validator;
 
 
 
@@ -47,47 +42,56 @@
  */
 public final class LDAPManagementContext extends ManagementContext {
 
-  // The JNDI context used for the ldap connection.
-  private final DirContext dirContext;
-
-
-
   /**
-   * Create a new LDAP management context using simple authentication.
-   * <p>
-   * TODO: we will want to support more secure forms of
-   * authentication.
+   * Create a new LDAP management context using the provided LDAP
+   * connection.
    *
-   * @param host
-   *          The host.
-   * @param port
-   *          The port.
-   * @param name
-   *          The LDAP bind DN.
-   * @param password
-   *          The LDAP bind password.
+   * @param connection
+   *          The LDAP connectin.
    * @return Returns the new management context.
-   * @throws NamingException
-   *           If the LDAP connection could not be established.
    */
-  public static ManagementContext createLDAPContext(String host,
-      int port, String name, String password) throws NamingException {
-    Hashtable<String, Object> env = new Hashtable<String, Object>();
-    env.put(Context.INITIAL_CONTEXT_FACTORY,
-        "com.sun.jndi.ldap.LdapCtxFactory");
-    env.put(Context.PROVIDER_URL, "ldap://" + host + ":" + port);
-    env.put(Context.SECURITY_PRINCIPAL, name);
-    env.put(Context.SECURITY_CREDENTIALS, password);
-
-    DirContext ctx = new InitialLdapContext(env, null);
-    return new LDAPManagementContext(ctx);
+  public static ManagementContext createFromContext(LDAPConnection connection) {
+    Validator.ensureNotNull(connection);
+    return new LDAPManagementContext(connection, LDAPProfile.getInstance());
   }
 
 
 
+  /**
+   * Create a new LDAP management context using the provided LDAP
+   * connection and LDAP profile.
+   * <p>
+   * This constructor is primarily intended for testing purposes so
+   * that unit tests can provide mock LDAP connections and LDAP
+   * profiles.
+   *
+   * @param connection
+   *          The LDAP connection.
+   * @param profile
+   *          The LDAP profile which should be used to construct LDAP
+   *          requests and decode LDAP responses.
+   * @return Returns the new management context.
+   */
+  public static ManagementContext createFromContext(LDAPConnection connection,
+      LDAPProfile profile) {
+    Validator.ensureNotNull(connection, profile);
+    return new LDAPManagementContext(connection, profile);
+  }
+
+  // The LDAP connection.
+  private final LDAPConnection connection;
+
+  // The LDAP profile which should be used to construct LDAP requests
+  // and decode LDAP responses.
+  private final LDAPProfile profile;
+
+
+
   // Private constructor.
-  private LDAPManagementContext(DirContext dirContext) {
-    this.dirContext = dirContext;
+  private LDAPManagementContext(LDAPConnection connection,
+      LDAPProfile profile) {
+    this.connection = connection;
+    this.profile = profile;
   }
 
 
@@ -96,6 +100,31 @@
    * {@inheritDoc}
    */
   public ManagedObject<RootCfgClient> getRootConfigurationManagedObject() {
-    return LDAPManagedObject.getRootManagedObject(dirContext);
+    return LDAPManagedObject.getRootManagedObject(this);
+  }
+
+
+
+  /**
+   * Gets the LDAP connection used for interacting with the server.
+   *
+   * @return Returns the LDAP connection used for interacting with the
+   *         server.
+   */
+  LDAPConnection getLDAPConnection() {
+    return connection;
+  }
+
+
+
+  /**
+   * Gets the LDAP profile which should be used to construct LDAP
+   * requests and decode LDAP responses.
+   *
+   * @return Returns the LDAP profile which should be used to
+   *         construct LDAP requests and decode LDAP responses.
+   */
+  LDAPProfile getLDAPProfile() {
+    return profile;
   }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java
index 021b1ce..167b988 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java
@@ -54,15 +54,19 @@
 final class LDAPNameBuilder implements ManagedObjectPathSerializer {
 
   /**
-   * Creates a new LDAP name representing the specified managed object path.
+   * Creates a new LDAP name representing the specified managed object
+   * path.
    *
    * @param path
    *          The managed object path.
-   * @return Returns a new LDAP name representing the specified managed object
-   *         path.
+   * @param profile
+   *          The LDAP profile which should be used to construct LDAP
+   *          names.
+   * @return Returns a new LDAP name representing the specified
+   *         managed object path.
    */
-  public static LdapName create(ManagedObjectPath path) {
-    LDAPNameBuilder builder = new LDAPNameBuilder();
+  public static LdapName create(ManagedObjectPath path, LDAPProfile profile) {
+    LDAPNameBuilder builder = new LDAPNameBuilder(profile);
     path.serialize(builder);
     return builder.getInstance();
   }
@@ -70,19 +74,22 @@
 
 
   /**
-   * Creates a new LDAP name representing the specified managed object path and
-   * instantiable relation.
+   * Creates a new LDAP name representing the specified managed object
+   * path and instantiable relation.
    *
    * @param path
    *          The managed object path.
    * @param relation
    *          The child instantiable relation.
-   * @return Returns a new LDAP name representing the specified managed object
-   *         path and instantiable relation.
+   * @param profile
+   *          The LDAP profile which should be used to construct LDAP
+   *          names.
+   * @return Returns a new LDAP name representing the specified
+   *         managed object path and instantiable relation.
    */
   public static LdapName create(ManagedObjectPath path,
-      InstantiableRelationDefinition<?, ?> relation) {
-    LDAPNameBuilder builder = new LDAPNameBuilder();
+      InstantiableRelationDefinition<?, ?> relation, LDAPProfile profile) {
+    LDAPNameBuilder builder = new LDAPNameBuilder(profile);
     path.serialize(builder);
     builder.appendManagedObjectPathElement(relation);
     return builder.getInstance();
@@ -98,10 +105,14 @@
 
   /**
    * Create a new JNDI LDAP name builder.
+   *
+   * @param profile
+   *          The LDAP profile which should be used to construct LDAP
+   *          names.
    */
-  public LDAPNameBuilder() {
+  public LDAPNameBuilder(LDAPProfile profile) {
     this.rdns = new LinkedList<Rdn>();
-    this.profile = LDAPProfile.getInstance();
+    this.profile = profile;
   }
 
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/OperationsExceptionFactory.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/OperationsExceptionFactory.java
deleted file mode 100644
index f0c74f1..0000000
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/OperationsExceptionFactory.java
+++ /dev/null
@@ -1,72 +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/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
- *
- *
- *      Portions Copyright 2007 Sun Microsystems, Inc.
- */
-
-package org.opends.server.admin.client.ldap;
-
-
-
-import javax.naming.NameNotFoundException;
-import javax.naming.NamingException;
-
-import org.opends.server.admin.ManagedObjectNotFoundException;
-import org.opends.server.admin.OperationsException;
-
-
-
-/**
- * A factory for creating <code>OperationsExceptions</code> from
- * <code>NamingExceptions</code>.
- */
-final class OperationsExceptionFactory {
-
-  /**
-   * Creates a new operations exception factory.
-   */
-  public OperationsExceptionFactory() {
-    // No implementation required.
-  }
-
-
-
-  /**
-   * Creates a new operations exception whose exact type depends upon the
-   * provided naming exception.
-   *
-   * @param e
-   *          The naming exception.
-   * @return Returns a new operations exception whose exact type depends upon
-   *         the provided naming exception.
-   */
-  public OperationsException createException(NamingException e) {
-    if (e instanceof NameNotFoundException) {
-      return new ManagedObjectNotFoundException(e);
-    } else {
-      // FIXME: resolve other naming exceptions.
-      return new OperationsException(e);
-    }
-  }
-}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationPropertyDefinitionTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationPropertyDefinitionTest.java
index ba8b869..a21b419 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationPropertyDefinitionTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationPropertyDefinitionTest.java
@@ -317,7 +317,7 @@
     builder.setAllowUnlimited(true);
     DurationPropertyDefinition spd = buildTestDefinition(builder);
 
-    PropertyDefinitionVisitor<Boolean, Void> v = new AbstractPropertyDefinitionVisitor<Boolean, Void>() {
+    PropertyDefinitionVisitor<Boolean, Void> v = new PropertyDefinitionVisitor<Boolean, Void>() {
 
       public Boolean visitDuration(DurationPropertyDefinition d,
           Void o) {
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/IntegerPropertyDefinitionTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/IntegerPropertyDefinitionTest.java
index cbfdc46..16ad9ec 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/IntegerPropertyDefinitionTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/IntegerPropertyDefinitionTest.java
@@ -271,7 +271,7 @@
     IntegerPropertyDefinition.Builder builder = createTestBuilder();
     builder.setAllowUnlimited(true);
     IntegerPropertyDefinition spd = buildTestDefinition(builder);
-    PropertyDefinitionVisitor<Boolean, Void> v = new AbstractPropertyDefinitionVisitor<Boolean, Void>() {
+    PropertyDefinitionVisitor<Boolean, Void> v = new PropertyDefinitionVisitor<Boolean, Void>() {
 
       public Boolean visitInteger(IntegerPropertyDefinition d,
           Void o) {
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/MockLDAPProfile.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java
similarity index 81%
rename from opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/MockLDAPProfile.java
rename to opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java
index f2ec23b..cbc3d33 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/MockLDAPProfile.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/MockLDAPProfile.java
@@ -24,10 +24,12 @@
  *
  *      Portions Copyright 2007 Sun Microsystems, Inc.
  */
-package org.opends.server.admin.server;
+package org.opends.server.admin;
 
 
 
+import java.util.Arrays;
+import java.util.LinkedList;
 import java.util.List;
 
 import org.opends.server.admin.AbstractManagedObjectDefinition;
@@ -68,17 +70,6 @@
    * {@inheritDoc}
    */
   @Override
-  public String getFilter(AbstractManagedObjectDefinition<?, ?> d) {
-    // Not implemented yet.
-    throw new UnsupportedOperationException();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
   public String getInstantiableRelationChildRDNType(
       InstantiableRelationDefinition<?, ?> r) {
     return "cn";
@@ -92,8 +83,7 @@
   @Override
   public List<String> getInstantiableRelationObjectClasses(
       InstantiableRelationDefinition<?, ?> r) {
-    // Not implemented yet.
-    throw new UnsupportedOperationException();
+    return Arrays.asList(new String[] { "top", "ds-cfg-branch" });
   }
 
 
@@ -103,8 +93,7 @@
    */
   @Override
   public String getObjectClass(AbstractManagedObjectDefinition<?, ?> d) {
-    // Not implemented yet.
-    throw new UnsupportedOperationException();
+    return "ds-cfg-" + d.getName();
   }
 
 
@@ -113,10 +102,16 @@
    * {@inheritDoc}
    */
   @Override
-  public List<String> getObjectClasses(
-      AbstractManagedObjectDefinition<?, ?> d) {
-    // Not implemented yet.
-    throw new UnsupportedOperationException();
+  public List<String> getObjectClasses(AbstractManagedObjectDefinition<?, ?> d) {
+    LinkedList<String> objectClasses = new LinkedList<String>();
+    for (AbstractManagedObjectDefinition<?, ?> i = d; i != null; i = i
+        .getParent()) {
+      objectClasses.addFirst(getObjectClass(i));
+    }
+
+    // Make sure that we have top.
+    objectClasses.addFirst("top");
+    return objectClasses;
   }
 
 
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/SizePropertyDefinitionTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/SizePropertyDefinitionTest.java
index a23bf28..c8cffa1 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/SizePropertyDefinitionTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/SizePropertyDefinitionTest.java
@@ -285,7 +285,7 @@
     SizePropertyDefinition.Builder builder = createTestBuilder();
     builder.setAllowUnlimited(true);
     SizePropertyDefinition spd = buildTestDefinition(builder);
-    PropertyDefinitionVisitor<Boolean, Void> v = new AbstractPropertyDefinitionVisitor<Boolean, Void>() {
+    PropertyDefinitionVisitor<Boolean, Void> v = new PropertyDefinitionVisitor<Boolean, Void>() {
 
       public Boolean visitSize(SizePropertyDefinition d,
           Void o) {
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfg.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfg.java
similarity index 86%
rename from opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfg.java
rename to opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfg.java
index a2f318f..9272699 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfg.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfg.java
@@ -24,7 +24,7 @@
  *
  *      Portions Copyright 2007 Sun Microsystems, Inc.
  */
-package org.opends.server.admin.server;
+package org.opends.server.admin;
 
 
 
@@ -43,4 +43,12 @@
    */
   ManagedObjectDefinition<? extends TestChildCfgClient, ? extends TestChildCfg> definition();
 
+
+
+  /**
+   * Get the "heartbeat-interval" property.
+   *
+   * @return Returns the value of the "heartbeat-interval" property.
+   */
+  long getHeartbeatInterval();
 }
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfgClient.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgClient.java
similarity index 72%
rename from opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfgClient.java
rename to opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgClient.java
index bcc0607..ea53db8 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfgClient.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgClient.java
@@ -24,7 +24,7 @@
  *
  *      Portions Copyright 2007 Sun Microsystems, Inc.
  */
-package org.opends.server.admin.server;
+package org.opends.server.admin;
 
 
 
@@ -43,4 +43,24 @@
    */
   ManagedObjectDefinition<? extends TestChildCfgClient, ? extends TestChildCfg> definition();
 
+
+
+  /**
+   * Get the "heartbeat-interval" property.
+   *
+   * @return Returns the value of the "heartbeat-interval" property.
+   */
+  long getHeartbeatInterval();
+
+
+
+  /**
+   * Set the "heartbeat-interval" property.
+   *
+   * @param value
+   *          The value of the "heartbeat-interval" property.
+   * @throws IllegalPropertyValueException
+   *           If the new value is invalid.
+   */
+  void setHeartbeatInterval(Long value) throws IllegalPropertyValueException;
 }
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java
new file mode 100644
index 0000000..46ee42f
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestChildCfgDefn.java
@@ -0,0 +1,251 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin;
+
+
+
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ConcurrentModificationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.OperationRejectedException;
+import org.opends.server.admin.server.ServerManagedObject;
+import org.opends.server.types.DN;
+
+
+
+/**
+ * A sample configuration definition class for testing.
+ */
+public final class TestChildCfgDefn extends
+    ManagedObjectDefinition<TestChildCfgClient, TestChildCfg> {
+
+  // The singleton configuration definition instance.
+  private static final TestChildCfgDefn INSTANCE = new TestChildCfgDefn();
+
+  // The "heartbeat-interval" property definition.
+  private static final DurationPropertyDefinition PD_HEARTBEAT_INTERVAL;
+
+  // Build the "heartbeat-interval" property definition.
+  static {
+    DurationPropertyDefinition.Builder builder = DurationPropertyDefinition
+        .createBuilder(INSTANCE, "heartbeat-interval");
+    DefaultBehaviorProvider<Long> provider = new DefinedDefaultBehaviorProvider<Long>(
+        "1000ms");
+    builder.setDefaultBehaviorProvider(provider);
+    builder.setAllowUnlimited(false);
+    builder.setBaseUnit("ms");
+    builder.setLowerLimit("100");
+    PD_HEARTBEAT_INTERVAL = builder.getInstance();
+    INSTANCE.registerPropertyDefinition(PD_HEARTBEAT_INTERVAL);
+  }
+
+
+
+  /**
+   * Get the definition singleton.
+   *
+   * @return Returns the definition singleton.
+   */
+  public static TestChildCfgDefn getInstance() {
+    return INSTANCE;
+  }
+
+
+
+  /**
+   * Private constructor.
+   */
+  private TestChildCfgDefn() {
+    super("test-child", null);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public TestChildCfgClient createClientConfiguration(
+      ManagedObject<? extends TestChildCfgClient> impl) {
+    return new TestChildCfgClientImpl(impl);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public TestChildCfg createServerConfiguration(
+      ServerManagedObject<? extends TestChildCfg> impl) {
+    return new TestChildCfgServerImpl(impl);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public Class<TestChildCfg> getServerConfigurationClass() {
+    return TestChildCfg.class;
+  }
+
+
+
+  /**
+   * Get the "heartbeat-interval" property definition.
+   *
+   * @return Returns the "heartbeat-interval" property definition.
+   */
+  public DurationPropertyDefinition getHeartbeatIntervalPropertyDefinition() {
+    return PD_HEARTBEAT_INTERVAL;
+  }
+
+
+
+  /**
+   * Managed object client implementation.
+   */
+  private static class TestChildCfgClientImpl implements TestChildCfgClient {
+
+    // Private implementation.
+    private ManagedObject<? extends TestChildCfgClient> impl;
+
+
+
+    // Private constructor.
+    private TestChildCfgClientImpl(
+        ManagedObject<? extends TestChildCfgClient> impl) {
+      this.impl = impl;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getHeartbeatInterval() {
+      return impl.getPropertyValue(INSTANCE
+          .getHeartbeatIntervalPropertyDefinition());
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setHeartbeatInterval(Long value) {
+      impl.setPropertyValue(INSTANCE.getHeartbeatIntervalPropertyDefinition(),
+          value);
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public ManagedObjectDefinition<? extends TestChildCfgClient, ? extends TestChildCfg> definition() {
+      return INSTANCE;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public PropertyProvider properties() {
+      return impl;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void commit() throws ConcurrentModificationException,
+        OperationRejectedException, AuthorizationException,
+        CommunicationException {
+      impl.commit();
+    }
+  }
+
+
+
+  /**
+   * Managed object server implementation.
+   */
+  private static class TestChildCfgServerImpl implements TestChildCfg {
+
+    // Private implementation.
+    private ServerManagedObject<? extends TestChildCfg> impl;
+
+
+
+    // Private constructor.
+    private TestChildCfgServerImpl(
+        ServerManagedObject<? extends TestChildCfg> impl) {
+      this.impl = impl;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getHeartbeatInterval() {
+      return impl.getPropertyValue(INSTANCE
+          .getHeartbeatIntervalPropertyDefinition());
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public ManagedObjectDefinition<? extends TestChildCfgClient, ? extends TestChildCfg> definition() {
+      return INSTANCE;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public PropertyProvider properties() {
+      return impl;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public DN dn() {
+      return impl.getDN();
+    }
+  }
+
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfg.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfg.java
similarity index 78%
rename from opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfg.java
rename to opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfg.java
index c553ffc..e45c0e5 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfg.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfg.java
@@ -24,12 +24,10 @@
  *
  *      Portions Copyright 2007 Sun Microsystems, Inc.
  */
-package org.opends.server.admin.server;
+package org.opends.server.admin;
 
 
 
-import org.opends.server.admin.Configuration;
-import org.opends.server.admin.ManagedObjectDefinition;
 
 
 
@@ -43,4 +41,21 @@
    */
   ManagedObjectDefinition<? extends TestParentCfgClient, ? extends TestParentCfg> definition();
 
+
+
+  /**
+   * Get the "maximum-length" property.
+   *
+   * @return Returns the value of the "maximum-length" property.
+   */
+  int getMaximumLength();
+
+
+
+  /**
+   * Get the "minimum-length" property.
+   *
+   * @return Returns the value of the "minimum-length" property.
+   */
+  int getMinimumLength();
 }
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgClient.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgClient.java
new file mode 100644
index 0000000..5a27cdc
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgClient.java
@@ -0,0 +1,214 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin;
+
+
+
+import org.opends.server.admin.ConfigurationClient;
+import org.opends.server.admin.ManagedObjectDefinition;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ConcurrentModificationException;
+import org.opends.server.admin.client.ManagedObjectDecodingException;
+import org.opends.server.admin.client.OperationRejectedException;
+
+
+
+/**
+ * A sample client-side configuration interface for testing.
+ */
+public interface TestParentCfgClient extends ConfigurationClient {
+
+  /**
+   * {@inheritDoc}
+   */
+  ManagedObjectDefinition<? extends TestParentCfgClient, ? extends TestParentCfg> definition();
+
+
+
+  /**
+   * Lists the test children.
+   *
+   * @return Returns an array containing the names of the test
+   *         children.
+   * @throws ConcurrentModificationException
+   *           If this test parent has been removed from the server by
+   *           another client.
+   * @throws AuthorizationException
+   *           If the server refuses to list the test children because
+   *           the client does not have the correct privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
+   *           underlying communication problem.
+   */
+  String[] listTestChildren() throws ConcurrentModificationException,
+      AuthorizationException, CommunicationException;
+
+
+
+  /**
+   * Gets the named test child.
+   *
+   * @param name
+   *          The name of the test child to retrieve.
+   * @return Returns the named test child.
+   * @throws DefinitionDecodingException
+   *           If the named test child was found but its type could
+   *           not be determined.
+   * @throws ManagedObjectDecodingException
+   *           If the named test child was found but one or more of
+   *           its properties could not be decoded.
+   * @throws ManagedObjectNotFoundException
+   *           If the named test child was not found on the server.
+   * @throws ConcurrentModificationException
+   *           If this test parent has been removed from the server by
+   *           another client.
+   * @throws AuthorizationException
+   *           If the server refuses to retrieve the named test child
+   *           because the client does not have the correct
+   *           privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
+   *           underlying communication problem.
+   */
+  TestChildCfgClient getTestChild(String name)
+      throws DefinitionDecodingException, ManagedObjectDecodingException,
+      ManagedObjectNotFoundException, ConcurrentModificationException,
+      AuthorizationException, CommunicationException;
+
+
+
+  /**
+   * Creates a new test child.
+   *
+   * @param <C>
+   *          The type of the test child being added.
+   * @param d
+   *          The definition of the test child to be created.
+   * @param name
+   *          The name of the new test child.
+   * @param p
+   *          A property provider which can be used to initialize the
+   *          property values of the new test child.
+   * @return Returns a new test child instance representing the test
+   *         child that was created.
+   * @throws ManagedObjectDecodingException
+   *           If the test child could not be created because one or
+   *           more of its properties are invalid.
+   * @throws ManagedObjectAlreadyExistsException
+   *           If the test child cannot be created because it already
+   *           exists on the server.
+   * @throws ConcurrentModificationException
+   *           If this test parent has been removed from the server by
+   *           another client.
+   * @throws OperationRejectedException
+   *           If the server refuses to create the test child due to
+   *           some server-side constraint which cannot be satisfied.
+   * @throws AuthorizationException
+   *           If the server refuses to create the test child because
+   *           the client does not have the correct privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
+   *           underlying communication problem.
+   */
+  <C extends TestChildCfgClient> C createTestChild(
+      ManagedObjectDefinition<C, ?> d, String name, PropertyProvider p)
+      throws ManagedObjectDecodingException,
+      ManagedObjectAlreadyExistsException, ConcurrentModificationException,
+      OperationRejectedException, AuthorizationException,
+      CommunicationException;
+
+
+
+  /**
+   * Removes the named test child.
+   *
+   * @param name
+   *          The name of the test child to remove.
+   * @throws ManagedObjectNotFoundException
+   *           If the test child does not exist.
+   * @throws OperationRejectedException
+   *           If the server refuses to remove the test child due to
+   *           some server-side constraint which cannot be satisfied
+   *           (for example, if it is referenced by another managed
+   *           object).
+   * @throws ConcurrentModificationException
+   *           If this test parent has been removed from the server by
+   *           another client.
+   * @throws AuthorizationException
+   *           If the server refuses to remove the test child because
+   *           the client does not have the correct privileges.
+   * @throws CommunicationException
+   *           If the client cannot contact the server due to an
+   *           underlying communication problem.
+   */
+  void removeTestChild(String name) throws ManagedObjectNotFoundException,
+      OperationRejectedException, ConcurrentModificationException,
+      AuthorizationException, CommunicationException;
+
+
+
+  /**
+   * Get the "maximum-length" property.
+   *
+   * @return Returns the value of the "maximum-length" property.
+   */
+  int getMaximumLength();
+
+
+
+  /**
+   * Set the "maximum-length" property.
+   *
+   * @param value
+   *          The value of the "maximum-length" property.
+   * @throws IllegalPropertyValueException
+   *           If the new value is invalid.
+   */
+  void setMaximumLength(Integer value) throws IllegalPropertyValueException;
+
+
+
+  /**
+   * Get the "minimum-length" property.
+   *
+   * @return Returns the value of the "minimum-length" property.
+   */
+  int getMinimumLength();
+
+
+
+  /**
+   * Set the "minimum-length" property.
+   *
+   * @param value
+   *          The value of the "minimum-length" property.
+   * @throws IllegalPropertyValueException
+   *           If the new value is invalid.
+   */
+  void setMinimumLength(Integer value) throws IllegalPropertyValueException;
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java
new file mode 100644
index 0000000..8fdd739
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java
@@ -0,0 +1,391 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin;
+
+
+
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ConcurrentModificationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagedObjectDecodingException;
+import org.opends.server.admin.client.OperationRejectedException;
+import org.opends.server.admin.server.ServerManagedObject;
+import org.opends.server.admin.std.meta.RootCfgDefn;
+import org.opends.server.types.DN;
+
+
+
+/**
+ * A sample configuration definition class for testing.
+ */
+public final class TestParentCfgDefn extends
+    ManagedObjectDefinition<TestParentCfgClient, TestParentCfg> {
+
+  // The singleton configuration definition instance.
+  private static final TestParentCfgDefn INSTANCE = new TestParentCfgDefn();
+
+  /**
+   * The relation between this definition and the root.
+   */
+  public static final InstantiableRelationDefinition<TestParentCfgClient, TestParentCfg> RD_TEST_PARENT;
+
+  // The "test-children" relation definition.
+  private static final InstantiableRelationDefinition<TestChildCfgClient, TestChildCfg> RD_TEST_CHILDREN;
+
+  // The "maximum-length" property definition.
+  private static final IntegerPropertyDefinition PD_MAXIMUM_LENGTH;
+
+  // The "minimum-length" property definition.
+  private static final IntegerPropertyDefinition PD_MINIMUM_LENGTH;
+
+  // Build the "maximum-length" property definition.
+  static {
+    IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition
+        .createBuilder(INSTANCE, "maximum-length");
+    DefaultBehaviorProvider<Integer> provider = new DefinedDefaultBehaviorProvider<Integer>(
+        "456");
+    builder.setDefaultBehaviorProvider(provider);
+    builder.setLowerLimit(0);
+    PD_MAXIMUM_LENGTH = builder.getInstance();
+    INSTANCE.registerPropertyDefinition(PD_MAXIMUM_LENGTH);
+  }
+
+  // Build the "minimum-length" property definition.
+  static {
+    IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition
+        .createBuilder(INSTANCE, "minimum-length");
+    DefaultBehaviorProvider<Integer> provider = new DefinedDefaultBehaviorProvider<Integer>(
+        "123");
+    builder.setDefaultBehaviorProvider(provider);
+    builder.setLowerLimit(0);
+    PD_MINIMUM_LENGTH = builder.getInstance();
+    INSTANCE.registerPropertyDefinition(PD_MINIMUM_LENGTH);
+  }
+
+  // Register this as a relation against the root configuration.
+  static {
+    RD_TEST_PARENT = new InstantiableRelationDefinition<TestParentCfgClient, TestParentCfg>(
+        INSTANCE, "test-parent", "test-parents", INSTANCE);
+    RootCfgDefn.getInstance().registerRelationDefinition(RD_TEST_PARENT);
+  }
+
+  // Build the "test-children" relation definition.
+  static {
+    RD_TEST_CHILDREN = new InstantiableRelationDefinition<TestChildCfgClient, TestChildCfg>(
+        INSTANCE, "test-child", "test-children", TestChildCfgDefn.getInstance());
+    INSTANCE.registerRelationDefinition(RD_TEST_CHILDREN);
+  }
+
+
+
+  /**
+   * Get the definition singleton.
+   *
+   * @return Returns the definition singleton.
+   */
+  public static TestParentCfgDefn getInstance() {
+    return INSTANCE;
+  }
+
+
+
+  /**
+   * Private constructor.
+   */
+  private TestParentCfgDefn() {
+    super("test-parent", null);
+  }
+
+
+
+  /**
+   * Get the "maximum-length" property definition.
+   *
+   * @return Returns the "maximum-length" property definition.
+   */
+  public IntegerPropertyDefinition getMaximumLengthPropertyDefinition() {
+    return PD_MAXIMUM_LENGTH;
+  }
+
+
+
+  /**
+   * Get the "minimum-length" property definition.
+   *
+   * @return Returns the "minimum-length" property definition.
+   */
+  public IntegerPropertyDefinition getMinimumLengthPropertyDefinition() {
+    return PD_MINIMUM_LENGTH;
+  }
+
+
+
+  /**
+   * Get the "test-children" relation definition.
+   *
+   * @return Returns the "test-children" relation definition.
+   */
+  public InstantiableRelationDefinition<TestChildCfgClient, TestChildCfg> getTestChildrenRelationDefinition() {
+    return RD_TEST_CHILDREN;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public TestParentCfgClient createClientConfiguration(
+      ManagedObject<? extends TestParentCfgClient> impl) {
+    return new TestParentCfgClientImpl(impl);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public TestParentCfg createServerConfiguration(
+      ServerManagedObject<? extends TestParentCfg> impl) {
+    return new TestParentCfgServerImpl(impl);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public Class<TestParentCfg> getServerConfigurationClass() {
+    return TestParentCfg.class;
+  }
+
+
+
+  /**
+   * Managed object client implementation.
+   */
+  private static class TestParentCfgClientImpl implements TestParentCfgClient {
+
+    // Private implementation.
+    private ManagedObject<? extends TestParentCfgClient> impl;
+
+
+
+    // Private constructor.
+    private TestParentCfgClientImpl(
+        ManagedObject<? extends TestParentCfgClient> impl) {
+      this.impl = impl;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getMaximumLength() {
+      return impl.getPropertyValue(INSTANCE
+          .getMaximumLengthPropertyDefinition());
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setMaximumLength(Integer value) {
+      impl.setPropertyValue(INSTANCE.getMaximumLengthPropertyDefinition(),
+          value);
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getMinimumLength() {
+      return impl.getPropertyValue(INSTANCE
+          .getMinimumLengthPropertyDefinition());
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setMinimumLength(Integer value) {
+      impl.setPropertyValue(INSTANCE.getMinimumLengthPropertyDefinition(),
+          value);
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public ManagedObjectDefinition<? extends TestParentCfgClient, ? extends TestParentCfg> definition() {
+      return INSTANCE;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public PropertyProvider properties() {
+      return impl;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void commit() throws ConcurrentModificationException,
+        OperationRejectedException, AuthorizationException,
+        CommunicationException {
+      impl.commit();
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public <C extends TestChildCfgClient> C createTestChild(
+        ManagedObjectDefinition<C, ?> d, String name, PropertyProvider p)
+        throws ManagedObjectDecodingException,
+        ManagedObjectAlreadyExistsException, ConcurrentModificationException,
+        OperationRejectedException, AuthorizationException,
+        CommunicationException {
+      return impl.createChild(INSTANCE.getTestChildrenRelationDefinition(), d,
+          name, p).getConfiguration();
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public TestChildCfgClient getTestChild(String name)
+        throws DefinitionDecodingException, ManagedObjectDecodingException,
+        ManagedObjectNotFoundException, ConcurrentModificationException,
+        AuthorizationException, CommunicationException {
+      return impl.getChild(INSTANCE.getTestChildrenRelationDefinition(), name)
+          .getConfiguration();
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String[] listTestChildren() throws ConcurrentModificationException,
+        AuthorizationException, CommunicationException {
+      return impl.listChildren(INSTANCE.getTestChildrenRelationDefinition());
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void removeTestChild(String name)
+        throws ManagedObjectNotFoundException, OperationRejectedException,
+        ConcurrentModificationException, AuthorizationException,
+        CommunicationException {
+      impl.removeChild(INSTANCE.getTestChildrenRelationDefinition(), name);
+    }
+
+  }
+
+
+
+  /**
+   * Managed object server implementation.
+   */
+  private static class TestParentCfgServerImpl implements TestParentCfg {
+
+    // Private implementation.
+    private ServerManagedObject<? extends TestParentCfg> impl;
+
+
+
+    // Private constructor.
+    private TestParentCfgServerImpl(
+        ServerManagedObject<? extends TestParentCfg> impl) {
+      this.impl = impl;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getMaximumLength() {
+      return impl.getPropertyValue(INSTANCE
+          .getMaximumLengthPropertyDefinition());
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getMinimumLength() {
+      return impl.getPropertyValue(INSTANCE
+          .getMinimumLengthPropertyDefinition());
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public ManagedObjectDefinition<? extends TestParentCfgClient, ? extends TestParentCfg> definition() {
+      return INSTANCE;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public PropertyProvider properties() {
+      return impl;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public DN dn() {
+      return impl.getDN();
+    }
+
+  }
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/CreateEntryMockLDAPConnection.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/CreateEntryMockLDAPConnection.java
new file mode 100644
index 0000000..d197f9e
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/CreateEntryMockLDAPConnection.java
@@ -0,0 +1,137 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.client.ldap;
+
+
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.InvalidNameException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.ldap.LdapName;
+
+import org.opends.server.util.Validator;
+import org.testng.Assert;
+
+
+
+/**
+ * A mock LDAP connection which is used to verify that an add
+ * operation was requested and that it has the correct parameters.
+ */
+public final class CreateEntryMockLDAPConnection extends MockLDAPConnection {
+
+  // Detect multiple calls.
+  private boolean alreadyAdded = false;
+
+  // The expected set of attributes (attribute name -> list of
+  // values).
+  private final Map<String, List<String>> attributes = new HashMap<String, List<String>>();
+
+  // The expected DN.
+  private final LdapName expectedDN;
+
+
+
+  /**
+   * Create a new mock ldap connection for detecting add operations.
+   *
+   * @param dn
+   *          The expected DN of the entry to be added.
+   */
+  public CreateEntryMockLDAPConnection(String dn) {
+    try {
+      this.expectedDN = new LdapName(dn);
+    } catch (InvalidNameException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+
+
+  /**
+   * Add an attribute which should be part of the add operation.
+   *
+   * @param expectedName
+   *          The name of the expected attribute.
+   * @param expectedValues
+   *          The attribute's expected values (never empty).
+   */
+  public void addExpectedAttribute(String expectedName,
+      String... expectedValues) {
+    Validator.ensureNotNull(expectedName);
+    Validator.ensureNotNull(expectedValues);
+    Validator.ensureTrue(expectedValues.length > 0);
+    attributes.put(expectedName, Arrays.asList(expectedValues));
+  }
+
+
+
+  /**
+   * Asserts that the entry was created.
+   */
+  public void assertEntryIsCreated() {
+    Assert.assertTrue(alreadyAdded);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void createEntry(LdapName dn, Attributes attributes)
+      throws NamingException {
+    Assert.assertFalse(alreadyAdded);
+    Assert.assertEquals(dn, expectedDN);
+
+    Map<String, List<String>> expected = new HashMap<String, List<String>>(
+        this.attributes);
+    NamingEnumeration<? extends Attribute> ne = attributes.getAll();
+    while (ne.hasMore()) {
+      Attribute attribute = ne.next();
+      String attrID = attribute.getID();
+      List<String> values = expected.remove(attrID);
+      if (values == null) {
+        Assert.fail("Unexpected attribute " + attrID);
+      }
+      assertAttributeEquals(attribute, values);
+    }
+
+    if (!expected.isEmpty()) {
+      Assert.fail("Missing expected attributes: " + expected.keySet());
+    }
+
+    alreadyAdded = true;
+  }
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/DeleteSubtreeMockLDAPConnection.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/DeleteSubtreeMockLDAPConnection.java
new file mode 100644
index 0000000..16a51f4
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/DeleteSubtreeMockLDAPConnection.java
@@ -0,0 +1,87 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.client.ldap;
+
+
+
+import javax.naming.InvalidNameException;
+import javax.naming.NamingException;
+import javax.naming.ldap.LdapName;
+
+import org.testng.Assert;
+
+
+
+/**
+ * A mock LDAP connection which is used to verify that a delete
+ * subtree takes place.
+ */
+public final class DeleteSubtreeMockLDAPConnection extends MockLDAPConnection {
+
+  // Detect multiple calls.
+  private boolean alreadyDeleted = false;
+
+  // The expected DN.
+  private final LdapName expectedDN;
+
+
+
+  /**
+   * Create a new mock ldap connection for detecting subtree deletes.
+   *
+   * @param dn
+   *          The expected subtree DN.
+   */
+  public DeleteSubtreeMockLDAPConnection(String dn) {
+    try {
+      this.expectedDN = new LdapName(dn);
+    } catch (InvalidNameException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+
+
+  /**
+   * Asserts that the subtree was deleted.
+   */
+  public void assertSubtreeIsDeleted() {
+    Assert.assertTrue(alreadyDeleted);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void deleteSubtree(LdapName dn) throws NamingException {
+    Assert.assertFalse(alreadyDeleted);
+    Assert.assertEquals(dn, expectedDN);
+    alreadyDeleted = true;
+  }
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/LDAPClientTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/LDAPClientTest.java
new file mode 100644
index 0000000..f31742f
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/LDAPClientTest.java
@@ -0,0 +1,625 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.client.ldap;
+
+
+
+import java.util.Collection;
+
+import javax.naming.NamingException;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.directory.Attributes;
+import javax.naming.ldap.LdapName;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.admin.AdminTestCase;
+import org.opends.server.admin.DefinitionDecodingException;
+import org.opends.server.admin.ManagedObjectAlreadyExistsException;
+import org.opends.server.admin.ManagedObjectNotFoundException;
+import org.opends.server.admin.MockLDAPProfile;
+import org.opends.server.admin.PropertyProvider;
+import org.opends.server.admin.TestChildCfgClient;
+import org.opends.server.admin.TestChildCfgDefn;
+import org.opends.server.admin.TestParentCfgClient;
+import org.opends.server.admin.TestParentCfgDefn;
+import org.opends.server.admin.client.AuthorizationException;
+import org.opends.server.admin.client.CommunicationException;
+import org.opends.server.admin.client.ConcurrentModificationException;
+import org.opends.server.admin.client.ManagedObject;
+import org.opends.server.admin.client.ManagedObjectDecodingException;
+import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.client.OperationRejectedException;
+import org.opends.server.admin.std.client.RootCfgClient;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Administration framework LDAP client unit tests.
+ */
+public final class LDAPClientTest extends AdminTestCase {
+
+  // Test LDIF.
+  private static final String[] TEST_LDIF = new String[] {
+      "dn: cn=test-parents", "objectclass: top", "objectclass: ds-cfg-branch",
+      "cn: test-parents", "", "dn: cn=test parent 1, cn=test-parents",
+      "objectclass: top", "objectclass: ds-cfg-test-parent",
+      "cn: test parent 1", "", "dn: cn=test parent 2,cn=test-parents",
+      "objectclass: top", "objectclass: ds-cfg-test-parent",
+      "cn: test parent 2", "ds-cfg-minimum-length: 10000",
+      "ds-cfg-maximum-length: 20000", "",
+      "dn:cn=test-children,cn=test parent 1,cn=test-parents",
+      "objectclass: top", "objectclass: ds-cfg-branch", "cn: test-children",
+      "",
+      "dn: cn=test child 1,cn=test-children,cn=test parent 1,cn=test-parents",
+      "objectclass: top", "objectclass: ds-cfg-test-child", "cn: test child 1",
+      "",
+      "dn: cn=test child 2,cn=test-children,cn=test parent 1,cn=test-parents",
+      "objectclass: top", "objectclass: ds-cfg-test-child", "cn: test child 2",
+      "ds-cfg-heartbeat-interval: 12345s", "" };
+
+
+
+  /**
+   * Provide valid naming exception to client API exception mappings.
+   *
+   * @return Returns valid naming exception to client API exception
+   *         mappings.
+   */
+  @DataProvider(name = "createManagedObjectExceptions")
+  public Object[][] createManagedObjectExceptions() {
+    return new Object[][] {
+        { new javax.naming.CommunicationException(),
+            CommunicationException.class },
+        { new javax.naming.ServiceUnavailableException(),
+            CommunicationException.class },
+        { new javax.naming.CannotProceedException(),
+            CommunicationException.class },
+        { new javax.naming.NameAlreadyBoundException(),
+            ManagedObjectAlreadyExistsException.class },
+        { new javax.naming.NoPermissionException(),
+            AuthorizationException.class },
+        { new OperationNotSupportedException(),
+            OperationRejectedException.class } };
+  }
+
+
+
+  /**
+   * Provide valid naming exception to client API exception mappings.
+   *
+   * @return Returns valid naming exception to client API exception
+   *         mappings.
+   */
+  @DataProvider(name = "getManagedObjectExceptions")
+  public Object[][] getManagedObjectExceptions() {
+    return new Object[][] {
+        { new javax.naming.CommunicationException(),
+            CommunicationException.class },
+        { new javax.naming.ServiceUnavailableException(),
+            CommunicationException.class },
+        { new javax.naming.CannotProceedException(),
+            CommunicationException.class },
+        { new javax.naming.NameNotFoundException(),
+            ManagedObjectNotFoundException.class },
+        { new javax.naming.NoPermissionException(),
+            AuthorizationException.class },
+        { new OperationNotSupportedException(), CommunicationException.class } };
+  }
+
+
+
+  /**
+   * Sets up tests
+   *
+   * @throws Exception
+   *           If the server could not be initialized.
+   */
+  @BeforeClass
+  public void setUp() throws Exception {
+    // This test suite depends on having the schema available, so
+    // we'll start the server.
+    TestCaseUtils.startServer();
+  }
+
+
+
+  /**
+   * Tests creation of a child managed object.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testCreateChildManagedObject() throws Exception {
+    MockPropertyProvider p = new MockPropertyProvider();
+    CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection(
+        "cn=test child 3,cn=test-children,cn=test parent 1,cn=test-parents");
+    c.importLDIF(TEST_LDIF);
+    c.addExpectedAttribute("cn", "test child 3");
+    c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child");
+
+    // LDAP encoding uses base unit.
+    p.addProperty("heartbeat-interval", "10s");
+    c.addExpectedAttribute("ds-cfg-heartbeat-interval", "10000ms");
+
+    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
+        new MockLDAPProfile());
+    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+    parent.createTestChild(TestChildCfgDefn.getInstance(), "test child 3", p);
+    c.assertEntryIsCreated();
+  }
+
+
+
+  /**
+   * Tests creation of a child managed object.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testCreateChildManagedObjectDefault() throws Exception {
+    CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection(
+        "cn=test child 3,cn=test-children,cn=test parent 1,cn=test-parents");
+    c.importLDIF(TEST_LDIF);
+    c.addExpectedAttribute("cn", "test child 3");
+    c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-child");
+
+    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
+        new MockLDAPProfile());
+    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+    parent.createTestChild(TestChildCfgDefn.getInstance(), "test child 3",
+        new MockPropertyProvider());
+    c.assertEntryIsCreated();
+  }
+
+
+
+  /**
+   * Tests creation of a top-level managed object using fails when an
+   * underlying NamingException occurs.
+   *
+   * @param cause
+   *          The NamingException cause of the failure.
+   * @param expected
+   *          The expected client API exception class.
+   */
+  @Test(dataProvider = "createManagedObjectExceptions")
+  public void testCreateManagedObjectException(final NamingException cause,
+      Class<? extends Exception> expected) {
+    MockLDAPConnection c = new MockLDAPConnection() {
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public void createEntry(LdapName dn, Attributes attributes)
+          throws NamingException {
+        throw cause;
+      }
+
+    };
+    c.importLDIF(TEST_LDIF);
+    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
+        new MockLDAPProfile());
+    try {
+      createTestParent(ctx, "test parent 3", new MockPropertyProvider());
+    } catch (Exception e) {
+      Assert.assertEquals(e.getClass(), expected);
+    }
+  }
+
+
+
+  /**
+   * Tests creation of a top-level managed object.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testCreateTopLevelManagedObject() throws Exception {
+    MockPropertyProvider p = new MockPropertyProvider();
+    CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection(
+        "cn=test parent 3,cn=test-parents");
+    c.importLDIF(TEST_LDIF);
+    c.addExpectedAttribute("cn", "test parent 3");
+    c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-parent");
+
+    p.addProperty("maximum-length", "54321");
+    c.addExpectedAttribute("ds-cfg-maximum-length", "54321");
+    p.addProperty("minimum-length", "12345");
+    c.addExpectedAttribute("ds-cfg-minimum-length", "12345");
+
+    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
+        new MockLDAPProfile());
+    createTestParent(ctx, "test parent 3", p);
+    c.assertEntryIsCreated();
+  }
+
+
+
+  /**
+   * Tests creation of a top-level managed object.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testCreateTopLevelManagedObjectDefault() throws Exception {
+    CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection(
+        "cn=test parent 3,cn=test-parents");
+    c.importLDIF(TEST_LDIF);
+    c.addExpectedAttribute("cn", "test parent 3");
+    c.addExpectedAttribute("objectclass", "top", "ds-cfg-test-parent");
+
+    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
+        new MockLDAPProfile());
+    createTestParent(ctx, "test parent 3", new MockPropertyProvider());
+    c.assertEntryIsCreated();
+  }
+
+
+
+  /**
+   * Tests retrieval of a child managed object with non-default
+   * values.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testGetChildManagedObject() throws Exception {
+    ManagementContext ctx = getManagementContext(TEST_LDIF);
+    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+    TestChildCfgClient child = parent.getTestChild("test child 2");
+    Assert.assertEquals(child.getHeartbeatInterval(), 12345000);
+  }
+
+
+
+  /**
+   * Tests retrieval of a child managed object with default values.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testGetChildManagedObjectDefault() throws Exception {
+    ManagementContext ctx = getManagementContext(TEST_LDIF);
+    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+    TestChildCfgClient child = parent.getTestChild("test child 1");
+    Assert.assertEquals(child.getHeartbeatInterval(), 1000);
+  }
+
+
+
+  /**
+   * Tests retrieval of a top-level managed object using fails when an
+   * underlying NamingException occurs.
+   *
+   * @param cause
+   *          The NamingException cause of the failure.
+   * @param expected
+   *          The expected client API exception class.
+   */
+  @Test(dataProvider = "getManagedObjectExceptions")
+  public void testGetManagedObjectException(final NamingException cause,
+      Class<? extends Exception> expected) {
+    MockLDAPConnection c = new MockLDAPConnection() {
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public Attributes readEntry(LdapName dn, Collection<String> attrIds)
+          throws NamingException {
+        throw cause;
+      }
+
+    };
+    c.importLDIF(TEST_LDIF);
+    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
+        new MockLDAPProfile());
+    try {
+      getTestParent(ctx, "test parent 2");
+    } catch (Exception e) {
+      Assert.assertEquals(e.getClass(), expected);
+    }
+  }
+
+
+
+  /**
+   * Tests retrieval of a top-level managed object with non-default
+   * values.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testGetTopLevelManagedObject() throws Exception {
+    ManagementContext ctx = getManagementContext(TEST_LDIF);
+    TestParentCfgClient parent = getTestParent(ctx, "test parent 2");
+    Assert.assertEquals(parent.getMinimumLength(), 10000);
+    Assert.assertEquals(parent.getMaximumLength(), 20000);
+  }
+
+
+
+  /**
+   * Tests retrieval of a top-level managed object with default
+   * values.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testGetTopLevelManagedObjectDefault() throws Exception {
+    ManagementContext ctx = getManagementContext(TEST_LDIF);
+    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+    Assert.assertEquals(parent.getMinimumLength(), 123);
+    Assert.assertEquals(parent.getMaximumLength(), 456);
+  }
+
+
+
+  /**
+   * Tests listing of child managed objects.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testListChildManagedObjects() throws Exception {
+    ManagementContext ctx = getManagementContext(TEST_LDIF);
+    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+    String[] actual = parent.listTestChildren();
+    String[] expected = new String[] { "test child 1", "test child 2" };
+    Assert.assertEqualsNoOrder(actual, expected);
+  }
+
+
+
+  /**
+   * Tests listing of child managed objects when their are not any.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testListChildManagedObjectsEmpty() throws Exception {
+    ManagementContext ctx = getManagementContext(TEST_LDIF);
+    TestParentCfgClient parent = getTestParent(ctx, "test parent 2");
+    String[] actual = parent.listTestChildren();
+    String[] expected = new String[] {};
+    Assert.assertEqualsNoOrder(actual, expected);
+  }
+
+
+
+  /**
+   * Tests listing of top level managed objects.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testListTopLevelManagedObjects() throws Exception {
+    ManagementContext ctx = getManagementContext(TEST_LDIF);
+    String[] actual = listTestParents(ctx);
+    String[] expected = new String[] { "test parent 1", "test parent 2" };
+    Assert.assertEqualsNoOrder(actual, expected);
+  }
+
+
+
+  /**
+   * Tests listing of top level managed objects when their are not
+   * any.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testListTopLevelManagedObjectsEmpty() throws Exception {
+    ManagementContext ctx = getManagementContext();
+    String[] actual = listTestParents(ctx);
+    String[] expected = new String[] {};
+    Assert.assertEqualsNoOrder(actual, expected);
+  }
+
+
+
+  /**
+   * Tests modification of a child managed object.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testModifyChildManagedObjectResetToDefault() throws Exception {
+    ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection(
+        "cn=test child 2,cn=test-children,cn=test parent 1,cn=test-parents");
+    c.importLDIF(TEST_LDIF);
+    c.addExpectedModification("ds-cfg-heartbeat-interval");
+    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
+        new MockLDAPProfile());
+    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+    TestChildCfgClient child = parent.getTestChild("test child 2");
+    child.setHeartbeatInterval(null);
+    child.commit();
+    Assert.assertTrue(c.isEntryModified());
+  }
+
+
+
+  /**
+   * Tests modification of a top-level managed object.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testModifyTopLevelManagedObjectNoChanges() throws Exception {
+    ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection(
+        "cn=test parent 1,cn=test-parents");
+    c.importLDIF(TEST_LDIF);
+    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
+        new MockLDAPProfile());
+    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+    parent.commit();
+    Assert.assertFalse(c.isEntryModified());
+  }
+
+
+
+  /**
+   * Tests modification of a top-level managed object.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testModifyTopLevelManagedObjectWithChanges() throws Exception {
+    ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection(
+        "cn=test parent 1,cn=test-parents");
+    c.importLDIF(TEST_LDIF);
+    c.addExpectedModification("ds-cfg-maximum-length", "54321");
+    c.addExpectedModification("ds-cfg-minimum-length", "12345");
+    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
+        new MockLDAPProfile());
+    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+    parent.setMaximumLength(54321);
+    parent.setMinimumLength(12345);
+    parent.commit();
+    Assert.assertTrue(c.isEntryModified());
+  }
+
+
+
+  /**
+   * Tests removal of a child managed object.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testRemoveChildManagedObject() throws Exception {
+    DeleteSubtreeMockLDAPConnection c = new DeleteSubtreeMockLDAPConnection(
+        "cn=test child 1,cn=test-children,cn=test parent 1,cn=test-parents");
+    c.importLDIF(TEST_LDIF);
+    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
+        new MockLDAPProfile());
+    TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
+    parent.removeTestChild("test child 1");
+    c.assertSubtreeIsDeleted();
+  }
+
+
+
+  /**
+   * Tests removal of a top-level managed object.
+   *
+   * @throws Exception
+   *           If an unexpected error occurred.
+   */
+  @Test
+  public void testRemoveTopLevelManagedObject() throws Exception {
+    DeleteSubtreeMockLDAPConnection c = new DeleteSubtreeMockLDAPConnection(
+        "cn=test parent 1,cn=test-parents");
+    c.importLDIF(TEST_LDIF);
+    ManagementContext ctx = LDAPManagementContext.createFromContext(c,
+        new MockLDAPProfile());
+    removeTestParent(ctx, "test parent 1");
+    c.assertSubtreeIsDeleted();
+  }
+
+
+
+  // Create the named test parent managed object.
+  private void createTestParent(ManagementContext context, String name,
+      PropertyProvider p) throws ManagedObjectDecodingException,
+      AuthorizationException, ManagedObjectAlreadyExistsException,
+      ConcurrentModificationException, OperationRejectedException,
+      CommunicationException {
+    ManagedObject<RootCfgClient> root = context
+        .getRootConfigurationManagedObject();
+    root.createChild(TestParentCfgDefn.RD_TEST_PARENT, TestParentCfgDefn
+        .getInstance(), name, p);
+  }
+
+
+
+  // Creates a management context using the provided LDIF.
+  private ManagementContext getManagementContext(String... ldif) {
+    MockLDAPConnection c = new MockLDAPConnection();
+    c.importLDIF(ldif);
+    return LDAPManagementContext.createFromContext(c, new MockLDAPProfile());
+  }
+
+
+
+  // Retrieve the named test parent managed object.
+  private TestParentCfgClient getTestParent(ManagementContext context,
+      String name) throws DefinitionDecodingException,
+      ManagedObjectDecodingException, AuthorizationException,
+      ManagedObjectNotFoundException, ConcurrentModificationException,
+      CommunicationException {
+    ManagedObject<RootCfgClient> root = context
+        .getRootConfigurationManagedObject();
+    return root.getChild(TestParentCfgDefn.RD_TEST_PARENT, name)
+        .getConfiguration();
+  }
+
+
+
+  // List test parent managed objects.
+  private String[] listTestParents(ManagementContext context)
+      throws AuthorizationException, ConcurrentModificationException,
+      CommunicationException {
+    ManagedObject<RootCfgClient> root = context
+        .getRootConfigurationManagedObject();
+    return root.listChildren(TestParentCfgDefn.RD_TEST_PARENT);
+  }
+
+
+
+  // Remove the named test parent managed object.
+  private void removeTestParent(ManagementContext context, String name)
+      throws AuthorizationException, ManagedObjectNotFoundException,
+      OperationRejectedException, ConcurrentModificationException,
+      CommunicationException {
+    ManagedObject<RootCfgClient> root = context
+        .getRootConfigurationManagedObject();
+    root.removeChild(TestParentCfgDefn.RD_TEST_PARENT, name);
+  }
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockLDAPConnection.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockLDAPConnection.java
new file mode 100644
index 0000000..cda4bc3
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockLDAPConnection.java
@@ -0,0 +1,358 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.client.ldap;
+
+
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.ldap.LdapName;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.types.AttributeValue;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.Entry;
+import org.opends.server.types.RDN;
+import org.testng.Assert;
+
+
+
+/**
+ * A mock LDAP connection which fakes up search results based on some
+ * LDIF content. Implementations should override the modify operations
+ * in order to get provide the correct fake behavior.
+ */
+public class MockLDAPConnection extends LDAPConnection {
+
+  /**
+   * A mock entry.
+   */
+  private static final class MockEntry {
+
+    // The entry's attributes.
+    private final Attributes attributes;
+
+    // The entry's children.
+    private final List<MockEntry> children;
+
+    // The name of this mock entry.
+    private final DN dn;
+
+
+
+    /**
+     * Create a new mock entry with the provided name and attributes.
+     *
+     * @param dn
+     *          The name of the entry.
+     * @param attributes
+     *          The attributes.
+     */
+    public MockEntry(DN dn, Attributes attributes) {
+      this.dn = dn;
+      this.attributes = attributes;
+      this.children = new LinkedList<MockEntry>();
+    }
+
+
+
+    /**
+     * Get the entry's attributes.
+     *
+     * @return Returns the entry's attributes.
+     */
+    public Attributes getAttributes() {
+      return attributes;
+    }
+
+
+
+    /**
+     * Get the entry's children.
+     *
+     * @return Returns the entry's children.
+     */
+    public List<MockEntry> getChildren() {
+      return children;
+    }
+
+
+
+    /**
+     * Get the entry's name.
+     *
+     * @return Returns the entry's name.
+     */
+    public DN getDN() {
+      return dn;
+    }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+      StringBuilder builder = new StringBuilder();
+      builder.append("dn=");
+      builder.append(dn);
+      builder.append(" attributes=");
+      builder.append(attributes);
+      return builder.toString();
+    }
+  }
+
+  // All the entries.
+  private final Map<DN, MockEntry> entries;
+
+  // The single root entry.
+  private final MockEntry rootEntry;
+
+
+
+  /**
+   * Creates a new mock LDAP connection.
+   */
+  public MockLDAPConnection() {
+    this.rootEntry = new MockEntry(DN.nullDN(), new BasicAttributes());
+    this.entries = new HashMap<DN, MockEntry>();
+    this.entries.put(DN.nullDN(), this.rootEntry);
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public void createEntry(LdapName dn, Attributes attributes)
+      throws NamingException {
+    throw new UnsupportedOperationException("createEntry");
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public void deleteSubtree(LdapName dn) throws NamingException {
+    throw new UnsupportedOperationException("deleteSubtree");
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean entryExists(LdapName dn) throws NamingException {
+    return getEntry(dn) != null;
+  }
+
+
+
+  /**
+   * Imports the provided LDIF into this mock connection.
+   *
+   * @param lines
+   *          The LDIF.
+   */
+  public final void importLDIF(String... lines) {
+    try {
+      for (Entry entry : TestCaseUtils.makeEntries(lines)) {
+        addEntry(entry);
+      }
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Collection<LdapName> listEntries(LdapName dn) throws NamingException {
+    MockEntry entry = getEntry(dn);
+
+    if (entry == null) {
+      throw new NameNotFoundException("could not find entry " + dn);
+    } else {
+      LinkedList<LdapName> names = new LinkedList<LdapName>();
+      for (MockEntry child : entry.children) {
+        names.add(new LdapName(child.getDN().toString()));
+      }
+      return names;
+    }
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public void modifyEntry(LdapName dn, Attributes mods) throws NamingException {
+    throw new UnsupportedOperationException("modifyEntry");
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Attributes readEntry(LdapName dn, Collection<String> attrIds)
+      throws NamingException {
+    MockEntry entry = getEntry(dn);
+
+    if (entry == null) {
+      throw new NameNotFoundException("could not find entry " + dn);
+    } else if (attrIds.isEmpty()) {
+      return entry.getAttributes();
+    } else {
+      Attributes attributes = entry.getAttributes();
+      Attributes filteredAttributes = new BasicAttributes();
+      for (String attrId : attrIds) {
+        if (attributes.get(attrId) != null) {
+          filteredAttributes.put(attributes.get(attrId));
+        }
+      }
+      return filteredAttributes;
+    }
+  }
+
+
+
+  /**
+   * Asserts whether the provided attribute contains exactly the set
+   * of values contained in the provided collection.
+   *
+   * @param attr
+   *          The attribute.
+   * @param values
+   *          The expected values.
+   * @throws NamingException
+   *           If an unexpected problem occurred.
+   */
+  protected final void assertAttributeEquals(Attribute attr,
+      Collection<String> values) throws NamingException {
+    LinkedList<String> actualValues = new LinkedList<String>();
+    NamingEnumeration<?> ne = attr.getAll();
+    while (ne.hasMore()) {
+      actualValues.add(ne.next().toString());
+    }
+
+    if (actualValues.size() != values.size()
+        || !actualValues.containsAll(values)) {
+      Assert.fail("Attribute " + attr.getID() + " contains " + actualValues
+          + " but expected " + values);
+    }
+  }
+
+
+
+  /**
+   * Create a new mock entry.
+   *
+   * @param entry
+   *          The entry to be added.
+   */
+  private void addEntry(Entry entry) {
+    MockEntry parent = rootEntry;
+    DN entryDN = entry.getDN();
+
+    // Create required glue entries.
+    for (int i = 0; i < entryDN.getNumComponents() - 1; i++) {
+      RDN rdn = entryDN.getRDN(entryDN.getNumComponents() - i - 1);
+      DN dn = parent.getDN().concat(rdn);
+
+      if (!entries.containsKey(dn)) {
+        MockEntry glue = new MockEntry(dn, new BasicAttributes());
+        parent.getChildren().add(glue);
+        entries.put(dn, glue);
+      }
+
+      parent = entries.get(dn);
+    }
+
+    // We now have the parent entry - so construct the new entry.
+    Attributes attributes = new BasicAttributes();
+    for (org.opends.server.types.Attribute attribute : entry.getAttributes()) {
+      BasicAttribute ba = new BasicAttribute(attribute.getName());
+      for (AttributeValue value : attribute.getValues()) {
+        ba.add(value.getStringValue());
+      }
+      attributes.put(ba);
+    }
+
+    // Add object classes.
+    BasicAttribute oc = new BasicAttribute("objectclass");
+    for (String s : entry.getObjectClasses().values()) {
+      oc.add(s);
+    }
+    attributes.put(oc);
+
+    MockEntry child = new MockEntry(entryDN, attributes);
+    parent.getChildren().add(child);
+    entries.put(entryDN, child);
+  }
+
+
+
+  /**
+   * Gets the named entry.
+   *
+   * @param dn
+   *          The name of the entry.
+   * @return Returns the mock entry or <code>null</code> if it does
+   *         not exist.
+   */
+  private MockEntry getEntry(LdapName dn) {
+    DN name;
+    try {
+      name = DN.decode(dn.toString());
+    } catch (DirectoryException e) {
+      throw new RuntimeException(e);
+    }
+
+    return entries.get(name);
+  }
+
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockPropertyProvider.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockPropertyProvider.java
new file mode 100644
index 0000000..765a2b8
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockPropertyProvider.java
@@ -0,0 +1,111 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.client.ldap;
+
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.opends.server.admin.PropertyDefinition;
+import org.opends.server.admin.PropertyProvider;
+import org.opends.server.util.Validator;
+
+
+
+/**
+ * A mock property provider which simplifies creation of managed
+ * objects and LDAP attribute comparisons.
+ */
+public final class MockPropertyProvider implements PropertyProvider {
+
+  // The properties.
+  private final Map<String, List<String>> properties = new HashMap<String, List<String>>();
+
+
+
+  /**
+   * Default constructor.
+   */
+  public MockPropertyProvider() {
+    // No implementation required.
+  }
+
+
+
+  /**
+   * Add a property.
+   *
+   * @param name
+   *          The name of the property.
+   * @param values
+   *          The property's values.
+   */
+  public void addProperty(String name, String... values) {
+    Validator.ensureNotNull(name);
+    Validator.ensureNotNull(values);
+    Validator.ensureTrue(values.length > 0);
+    properties.put(name, Arrays.asList(values));
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public <T> Collection<T> getPropertyValues(PropertyDefinition<T> d)
+      throws IllegalArgumentException {
+    List<String> values = properties.get(d.getName());
+
+    if (values == null) {
+      return Collections.<T> emptySet();
+    }
+
+    List<T> encodedValues = new ArrayList<T>(values.size());
+    for (String value : values) {
+      encodedValues.add(d.decodeValue(value));
+    }
+
+    return encodedValues;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String toString() {
+    return properties.toString();
+  }
+
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/ModifyEntryMockLDAPConnection.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/ModifyEntryMockLDAPConnection.java
new file mode 100644
index 0000000..6e4034c
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/ModifyEntryMockLDAPConnection.java
@@ -0,0 +1,139 @@
+/*
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.client.ldap;
+
+
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.InvalidNameException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.ldap.LdapName;
+
+import org.opends.server.util.Validator;
+import org.testng.Assert;
+
+
+
+/**
+ * A mock LDAP connection which is used to verify that a modify
+ * operation was requested and that it has the correct parameters.
+ */
+public final class ModifyEntryMockLDAPConnection extends MockLDAPConnection {
+
+  // Detect multiple calls.
+  private boolean alreadyModified = false;
+
+  // The expected DN.
+  private final LdapName expectedDN;
+
+  // The expected set of modifications (attribute name -> list of
+  // values).
+  private final Map<String, List<String>> modifications = new HashMap<String, List<String>>();
+
+
+
+  /**
+   * Create a new mock ldap connection for detecting modify
+   * operations.
+   *
+   * @param dn
+   *          The expected DN of the entry to be added.
+   */
+  public ModifyEntryMockLDAPConnection(String dn) {
+    try {
+      this.expectedDN = new LdapName(dn);
+    } catch (InvalidNameException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+
+
+  /**
+   * Add a modification which should be part of the modify operation.
+   *
+   * @param expectedName
+   *          The name of the expected attribute.
+   * @param expectedValues
+   *          The attribute's expected new values (possibly empty if
+   *          deleted).
+   */
+  public void addExpectedModification(String expectedName,
+      String... expectedValues) {
+    Validator.ensureNotNull(expectedName);
+    Validator.ensureNotNull(expectedValues);
+    modifications.put(expectedName, Arrays.asList(expectedValues));
+  }
+
+
+
+  /**
+   * Determines whether or not the entry was modified.
+   *
+   * @return Returns <code>true</code> if it was modified.
+   */
+  public boolean isEntryModified() {
+    return alreadyModified;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void modifyEntry(LdapName dn, Attributes mods) throws NamingException {
+    Assert.assertFalse(alreadyModified);
+    Assert.assertEquals(dn, expectedDN);
+
+    Map<String, List<String>> expected = new HashMap<String, List<String>>(
+        modifications);
+    NamingEnumeration<? extends Attribute> ne = mods.getAll();
+    while (ne.hasMore()) {
+      Attribute mod = ne.next();
+      String attrID = mod.getID();
+      List<String> values = expected.remove(attrID);
+      if (values == null) {
+        Assert.fail("Unexpected modification to attribute " + attrID);
+      }
+      assertAttributeEquals(mod, values);
+    }
+
+    if (!expected.isEmpty()) {
+      Assert.fail("Missing modifications to: " + expected.keySet());
+    }
+
+    alreadyModified = true;
+  }
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DNBuilderTest.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DNBuilderTest.java
index 61878e8..941217e 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DNBuilderTest.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DNBuilderTest.java
@@ -36,8 +36,15 @@
 import org.opends.server.admin.ConfigurationClient;
 import org.opends.server.admin.InstantiableRelationDefinition;
 import org.opends.server.admin.ManagedObjectPath;
+import org.opends.server.admin.MockLDAPProfile;
 import org.opends.server.admin.OptionalRelationDefinition;
 import org.opends.server.admin.SingletonRelationDefinition;
+import org.opends.server.admin.TestChildCfg;
+import org.opends.server.admin.TestChildCfgClient;
+import org.opends.server.admin.TestChildCfgDefn;
+import org.opends.server.admin.TestParentCfg;
+import org.opends.server.admin.TestParentCfgClient;
+import org.opends.server.admin.TestParentCfgDefn;
 import org.opends.server.admin.std.meta.RootCfgDefn;
 import org.opends.server.types.DN;
 import org.testng.annotations.BeforeClass;
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfgDefn.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfgDefn.java
deleted file mode 100644
index 72fb361..0000000
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestChildCfgDefn.java
+++ /dev/null
@@ -1,64 +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/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
- *
- *
- *      Portions Copyright 2007 Sun Microsystems, Inc.
- */
-package org.opends.server.admin.server;
-
-
-
-import org.opends.server.admin.AbstractManagedObjectDefinition;
-
-
-
-/**
- * A sample configuration definition class for testing.
- */
-public final class TestChildCfgDefn extends
-    AbstractManagedObjectDefinition<TestChildCfgClient, TestChildCfg> {
-
-  // The singleton configuration definition instance.
-  private static final TestChildCfgDefn INSTANCE = new TestChildCfgDefn();
-
-
-
-  /**
-   * Get the definition singleton.
-   *
-   * @return Returns the definition singleton.
-   */
-  public static TestChildCfgDefn getInstance() {
-    return INSTANCE;
-  }
-
-
-
-  /**
-   * Private constructor.
-   */
-  private TestChildCfgDefn() {
-    super("test-child", null);
-  }
-
-}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfgClient.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfgClient.java
deleted file mode 100644
index 98281fb..0000000
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfgClient.java
+++ /dev/null
@@ -1,46 +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/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
- *
- *
- *      Portions Copyright 2007 Sun Microsystems, Inc.
- */
-package org.opends.server.admin.server;
-
-
-
-import org.opends.server.admin.ConfigurationClient;
-import org.opends.server.admin.ManagedObjectDefinition;
-
-
-
-/**
- * A sample client-side configuration interface for testing.
- */
-public interface TestParentCfgClient extends ConfigurationClient {
-
-  /**
-   * {@inheritDoc}
-   */
-  ManagedObjectDefinition<? extends TestParentCfgClient, ? extends TestParentCfg> definition();
-
-}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfgDefn.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfgDefn.java
deleted file mode 100644
index ac8901b..0000000
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/TestParentCfgDefn.java
+++ /dev/null
@@ -1,65 +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/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * 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/opends/resource/legal-notices/OpenDS.LICENSE.  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
- *
- *
- *      Portions Copyright 2007 Sun Microsystems, Inc.
- */
-package org.opends.server.admin.server;
-
-
-
-import org.opends.server.admin.AbstractManagedObjectDefinition;
-
-
-
-/**
- * A sample configuration definition class for testing.
- */
-public final class TestParentCfgDefn
-    extends
-    AbstractManagedObjectDefinition<TestParentCfgClient, TestParentCfg> {
-
-  // The singleton configuration definition instance.
-  private static final TestParentCfgDefn INSTANCE = new TestParentCfgDefn();
-
-
-
-  /**
-   * Get the definition singleton.
-   *
-   * @return Returns the definition singleton.
-   */
-  public static TestParentCfgDefn getInstance() {
-    return INSTANCE;
-  }
-
-
-
-  /**
-   * Private constructor.
-   */
-  private TestParentCfgDefn() {
-    super("test-parent", null);
-  }
-
-}

--
Gitblit v1.10.0