From 19f32e8b95817bcc2ef0a73bbcb4be16e101c989 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Mon, 02 Dec 2013 11:07:17 +0000
Subject: [PATCH] OpenDJ 3 : config framework

---
 opendj-admin/src/main/java/org/opends/server/admin/client/AdminSecurityException.java              |   65 
 opendj-admin/src/main/java/org/opends/server/admin/client/CommunicationException.java              |    8 
 opendj-admin/src/main/java/org/opends/server/admin/client/MissingMandatoryPropertiesException.java |   21 
 opendj-admin/src/main/java/org/opends/server/admin/client/AuthenticationException.java             |  101 -
 opendj-admin/src/main/java/org/opends/server/admin/client/spi/Driver.java                          | 1328 ++++++++++++--------------
 opendj-admin/src/main/java/org/opends/server/admin/client/package-info.java                        |    4 
 opendj-admin/src/main/java/org/opends/server/admin/client/IllegalManagedObjectNameException.java   |    6 
 opendj-admin/src/main/java/org/opends/server/admin/client/AdminClientException.java                |   72 
 opendj-admin/src/main/java/org/opends/server/admin/client/OperationRejectedException.java          |  317 ++---
 opendj-admin/src/main/java/org/opends/server/admin/client/AuthenticationNotSupportedException.java |  106 -
 opendj-admin/src/main/java/org/opends/server/admin/client/ManagedObjectDecodingException.java      |   20 
 opendj-admin/src/main/java/org/opends/server/admin/client/AuthorizationException.java              |  103 -
 opendj-admin/src/main/java/org/opends/server/admin/client/ConcurrentModificationException.java     |    8 
 opendj-admin/src/main/java/org/opends/server/admin/client/ManagementContext.java                   |  846 +++++++---------
 14 files changed, 1,367 insertions(+), 1,638 deletions(-)

diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/AdminClientException.java b/opendj-admin/src/main/java/org/opends/server/admin/client/AdminClientException.java
index b596166..7715a0b 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/AdminClientException.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/AdminClientException.java
@@ -27,54 +27,44 @@
 
 package org.opends.server.admin.client;
 
-
-
-import org.opends.messages.Message;
-
+import org.forgerock.i18n.LocalizableMessage;
 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.
+ * 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.
+ * Client exceptions represent communications problems, security problems, and
+ * service related problems.
  */
 public abstract class AdminClientException extends AdminException {
 
-  /**
-   * Serialization ID.
-   */
-  private static final long serialVersionUID = 4044747533980824456L;
+    /**
+     * Serialization ID.
+     */
+    private static final long serialVersionUID = 4044747533980824456L;
 
+    /**
+     * Create an administration client exception with a message and cause.
+     *
+     * @param message
+     *            The message.
+     * @param cause
+     *            The cause.
+     */
+    protected AdminClientException(LocalizableMessage message, Throwable cause) {
+        super(message, cause);
+    }
 
-
-  /**
-   * Create an administration client exception with a message and
-   * cause.
-   *
-   * @param message
-   *          The message.
-   * @param cause
-   *          The cause.
-   */
-  protected AdminClientException(Message message, Throwable cause) {
-    super(message, cause);
-  }
-
-
-
-  /**
-   * Create an administration client exception with a message.
-   *
-   * @param message
-   *          The message.
-   */
-  protected AdminClientException(Message message) {
-    super(message);
-  }
+    /**
+     * Create an administration client exception with a message.
+     *
+     * @param message
+     *            The message.
+     */
+    protected AdminClientException(LocalizableMessage message) {
+        super(message);
+    }
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/AdminSecurityException.java b/opendj-admin/src/main/java/org/opends/server/admin/client/AdminSecurityException.java
index 2f92e71..fd1b96a 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/AdminSecurityException.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/AdminSecurityException.java
@@ -27,48 +27,39 @@
 
 package org.opends.server.admin.client;
 
-
-
-import org.opends.messages.Message;
-
-
+import org.forgerock.i18n.LocalizableMessage;
 
 /**
- * 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.
+ * 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 {
 
-  /**
-   * Fake serialization ID.
-   */
-  private static final long serialVersionUID = 1L;
+    /**
+     * Fake serialization ID.
+     */
+    private static final long serialVersionUID = 1L;
 
+    /**
+     * Create a security exception with a message and cause.
+     *
+     * @param message
+     *            The message.
+     * @param cause
+     *            The cause.
+     */
+    protected AdminSecurityException(LocalizableMessage message, Throwable cause) {
+        super(message, cause);
+    }
 
-
-  /**
-   * Create a security exception with a message and cause.
-   *
-   * @param message
-   *          The message.
-   * @param cause
-   *          The cause.
-   */
-  protected AdminSecurityException(Message message, Throwable cause) {
-    super(message, cause);
-  }
-
-
-
-  /**
-   * Create a security exception with a message.
-   *
-   * @param message
-   *          The message.
-   */
-  protected AdminSecurityException(Message message) {
-    super(message);
-  }
+    /**
+     * Create a security exception with a message.
+     *
+     * @param message
+     *            The message.
+     */
+    protected AdminSecurityException(LocalizableMessage message) {
+        super(message);
+    }
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/AuthenticationException.java b/opendj-admin/src/main/java/org/opends/server/admin/client/AuthenticationException.java
index c5f6ab7..9777cc8 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/AuthenticationException.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/AuthenticationException.java
@@ -27,71 +27,58 @@
 
 package org.opends.server.admin.client;
 
+import org.forgerock.i18n.LocalizableMessage;
 
-
-import static org.opends.messages.AdminMessages.*;
-
-import org.opends.messages.Message;
-
-
+import static com.forgerock.opendj.ldap.AdminMessages.*;
 
 /**
- * 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.
+ * 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;
+    /**
+     * Serialization ID.
+     */
+    private static final long serialVersionUID = 3544797197747686958L;
 
+    /**
+     * Creates an authentication exception with a default message.
+     */
+    public AuthenticationException() {
+        super(ERR_AUTHENTICATION_EXCEPTION_DEFAULT.get());
+    }
 
+    /**
+     * Create an authentication exception with a cause and a default message.
+     *
+     * @param cause
+     *            The cause.
+     */
+    public AuthenticationException(Throwable cause) {
+        super(ERR_AUTHENTICATION_EXCEPTION_DEFAULT.get(), cause);
+    }
 
-  /**
-   * Creates an authentication exception with a default message.
-   */
-  public AuthenticationException() {
-    super(ERR_AUTHENTICATION_EXCEPTION_DEFAULT.get());
-  }
+    /**
+     * Create an authentication exception with a message and cause.
+     *
+     * @param message
+     *            The message.
+     * @param cause
+     *            The cause.
+     */
+    public AuthenticationException(LocalizableMessage message, Throwable cause) {
+        super(message, cause);
+    }
 
-
-
-  /**
-   * Create an authentication exception with a cause and a default
-   * message.
-   *
-   * @param cause
-   *          The cause.
-   */
-  public AuthenticationException(Throwable cause) {
-    super(ERR_AUTHENTICATION_EXCEPTION_DEFAULT.get(), cause);
-  }
-
-
-
-  /**
-   * Create an authentication exception with a message and cause.
-   *
-   * @param message
-   *          The message.
-   * @param cause
-   *          The cause.
-   */
-  public AuthenticationException(Message message, Throwable cause) {
-    super(message, cause);
-  }
-
-
-
-  /**
-   * Create an authentication exception with a message.
-   *
-   * @param message
-   *          The message.
-   */
-  public AuthenticationException(Message message) {
-    super(message);
-  }
+    /**
+     * Create an authentication exception with a message.
+     *
+     * @param message
+     *            The message.
+     */
+    public AuthenticationException(LocalizableMessage message) {
+        super(message);
+    }
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/AuthenticationNotSupportedException.java b/opendj-admin/src/main/java/org/opends/server/admin/client/AuthenticationNotSupportedException.java
index 7f66a59..c737eb3 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/AuthenticationNotSupportedException.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/AuthenticationNotSupportedException.java
@@ -27,73 +27,59 @@
 
 package org.opends.server.admin.client;
 
+import org.forgerock.i18n.LocalizableMessage;
 
-
-import static org.opends.messages.AdminMessages.*;
-
-import org.opends.messages.Message;
-
-
+import static com.forgerock.opendj.ldap.AdminMessages.*;
 
 /**
- * This exception is thrown when the particular flavor of
- * authentication requested is not supported by the Directory Server.
+ * This exception is thrown when the particular flavor of authentication
+ * requested is not supported by the Directory Server.
  */
-public class AuthenticationNotSupportedException
-    extends AdminSecurityException {
+public class AuthenticationNotSupportedException extends AdminSecurityException {
 
-  /**
-   * Serialization ID.
-   */
-  private static final long serialVersionUID = 7387834052676291793L;
+    /**
+     * Serialization ID.
+     */
+    private static final long serialVersionUID = 7387834052676291793L;
 
+    /**
+     * Creates an authentication not supported exception with a default message.
+     */
+    public AuthenticationNotSupportedException() {
+        super(ERR_AUTHENTICATION_NOT_SUPPORTED_EXCEPTION_DEFAULT.get());
+    }
 
+    /**
+     * Creates an authentication not supported exception with a cause and a
+     * default message.
+     *
+     * @param cause
+     *            The cause.
+     */
+    public AuthenticationNotSupportedException(Throwable cause) {
+        super(ERR_AUTHENTICATION_NOT_SUPPORTED_EXCEPTION_DEFAULT.get(), cause);
+    }
 
-  /**
-   * Creates an authentication not supported exception with a default
-   * message.
-   */
-  public AuthenticationNotSupportedException() {
-    super(ERR_AUTHENTICATION_NOT_SUPPORTED_EXCEPTION_DEFAULT.get());
-  }
+    /**
+     * Create an authentication not supported exception with a message and
+     * cause.
+     *
+     * @param message
+     *            The message.
+     * @param cause
+     *            The cause.
+     */
+    public AuthenticationNotSupportedException(LocalizableMessage message, Throwable cause) {
+        super(message, cause);
+    }
 
-
-
-  /**
-   * Creates an authentication not supported exception with a cause
-   * and a default message.
-   *
-   * @param cause
-   *          The cause.
-   */
-  public AuthenticationNotSupportedException(Throwable cause) {
-    super(ERR_AUTHENTICATION_NOT_SUPPORTED_EXCEPTION_DEFAULT.get(), cause);
-  }
-
-
-
-  /**
-   * Create an authentication not supported exception with a message
-   * and cause.
-   *
-   * @param message
-   *          The message.
-   * @param cause
-   *          The cause.
-   */
-  public AuthenticationNotSupportedException(Message message, Throwable cause) {
-    super(message, cause);
-  }
-
-
-
-  /**
-   * Create an authentication not supported exception with a message.
-   *
-   * @param message
-   *          The message.
-   */
-  public AuthenticationNotSupportedException(Message message) {
-    super(message);
-  }
+    /**
+     * Create an authentication not supported exception with a message.
+     *
+     * @param message
+     *            The message.
+     */
+    public AuthenticationNotSupportedException(LocalizableMessage message) {
+        super(message);
+    }
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/AuthorizationException.java b/opendj-admin/src/main/java/org/opends/server/admin/client/AuthorizationException.java
index 5f8b3ef..7629c03 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/AuthorizationException.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/AuthorizationException.java
@@ -27,72 +27,59 @@
 
 package org.opends.server.admin.client;
 
+import org.forgerock.i18n.LocalizableMessage;
 
-
-import static org.opends.messages.AdminMessages.*;
-
-import org.opends.messages.Message;
-
-
+import static com.forgerock.opendj.ldap.AdminMessages.*;
 
 /**
- * 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.
+ * 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;
+    /**
+     * Serialization ID.
+     */
+    private static final long serialVersionUID = 8414248362572933814L;
 
+    /**
+     * Create an authorization exception with a default message.
+     */
+    public AuthorizationException() {
+        super(ERR_AUTHORIZATION_EXCEPTION_DEFAULT.get());
+    }
 
+    /**
+     * Create an authorization exception with a cause and a default message.
+     *
+     * @param cause
+     *            The cause.
+     */
+    public AuthorizationException(Throwable cause) {
+        super(ERR_AUTHORIZATION_EXCEPTION_DEFAULT.get(), cause);
+    }
 
-  /**
-   * Create an authorization exception with a default message.
-   */
-  public AuthorizationException() {
-    super(ERR_AUTHORIZATION_EXCEPTION_DEFAULT.get());
-  }
+    /**
+     * Create an authorization exception with a message and cause.
+     *
+     * @param message
+     *            The message.
+     * @param cause
+     *            The cause.
+     */
+    public AuthorizationException(LocalizableMessage message, Throwable cause) {
+        super(message, cause);
+    }
 
-
-
-  /**
-   * Create an authorization exception with a cause and a default
-   * message.
-   *
-   * @param cause
-   *          The cause.
-   */
-  public AuthorizationException(Throwable cause) {
-    super(ERR_AUTHORIZATION_EXCEPTION_DEFAULT.get(), cause);
-  }
-
-
-
-  /**
-   * Create an authorization exception with a message and cause.
-   *
-   * @param message
-   *          The message.
-   * @param cause
-   *          The cause.
-   */
-  public AuthorizationException(Message message, Throwable cause) {
-    super(message, cause);
-  }
-
-
-
-  /**
-   * Create an authorization exception with a message.
-   *
-   * @param message
-   *          The message.
-   */
-  public AuthorizationException(Message message) {
-    super(message);
-  }
+    /**
+     * Create an authorization exception with a message.
+     *
+     * @param message
+     *            The message.
+     */
+    public AuthorizationException(LocalizableMessage message) {
+        super(message);
+    }
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/CommunicationException.java b/opendj-admin/src/main/java/org/opends/server/admin/client/CommunicationException.java
index 45815bd..ea18c76 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/CommunicationException.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/CommunicationException.java
@@ -29,9 +29,9 @@
 
 
 
-import static org.opends.messages.AdminMessages.*;
+import org.forgerock.i18n.LocalizableMessage;
 
-import org.opends.messages.Message;
+import static com.forgerock.opendj.ldap.AdminMessages.*;
 
 
 
@@ -82,7 +82,7 @@
    * @param cause
    *          The cause.
    */
-  public CommunicationException(Message message, Throwable cause) {
+  public CommunicationException(LocalizableMessage message, Throwable cause) {
     super(message, cause);
   }
 
@@ -94,7 +94,7 @@
    * @param message
    *          The message.
    */
-  public CommunicationException(Message message) {
+  public CommunicationException(LocalizableMessage message) {
     super(message);
   }
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/ConcurrentModificationException.java b/opendj-admin/src/main/java/org/opends/server/admin/client/ConcurrentModificationException.java
index 3e6c3df..0c0dd03 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/ConcurrentModificationException.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/ConcurrentModificationException.java
@@ -29,9 +29,9 @@
 
 
 
-import static org.opends.messages.AdminMessages.*;
+import static com.forgerock.opendj.ldap.AdminMessages.*;
 
-import org.opends.messages.Message;
+import org.forgerock.i18n.LocalizableMessage;
 import org.opends.server.admin.OperationsException;
 
 
@@ -82,7 +82,7 @@
    * @param cause
    *          The cause.
    */
-  public ConcurrentModificationException(Message message, Throwable cause) {
+  public ConcurrentModificationException(LocalizableMessage message, Throwable cause) {
     super(message, cause);
   }
 
@@ -94,7 +94,7 @@
    * @param message
    *          The message.
    */
-  public ConcurrentModificationException(Message message) {
+  public ConcurrentModificationException(LocalizableMessage message) {
     super(message);
   }
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/IllegalManagedObjectNameException.java b/opendj-admin/src/main/java/org/opends/server/admin/client/IllegalManagedObjectNameException.java
index d8957f1..a40f45f 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/IllegalManagedObjectNameException.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/IllegalManagedObjectNameException.java
@@ -29,9 +29,9 @@
 
 
 
-import static org.opends.messages.AdminMessages.*;
+import static com.forgerock.opendj.ldap.AdminMessages.*;
 
-import org.opends.messages.Message;
+import org.forgerock.i18n.LocalizableMessage;
 import org.opends.server.admin.IllegalPropertyValueStringException;
 import org.opends.server.admin.OperationsException;
 import org.opends.server.admin.PropertyDefinition;
@@ -58,7 +58,7 @@
 
 
   // Create the message
-  private static Message createMessage(String illegalName,
+  private static LocalizableMessage createMessage(String illegalName,
       PropertyDefinition<?> namingPropertyDefinition) {
     if (illegalName.length() == 0) {
       return ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_EMPTY.get();
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/ManagedObjectDecodingException.java b/opendj-admin/src/main/java/org/opends/server/admin/client/ManagedObjectDecodingException.java
index 7e042fe..5d929ea 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/ManagedObjectDecodingException.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/ManagedObjectDecodingException.java
@@ -29,19 +29,19 @@
 
 
 
-import static org.opends.messages.AdminMessages.*;
-
-import org.opends.messages.Message;
-import org.opends.messages.MessageBuilder;
+import static com.forgerock.opendj.ldap.AdminMessages.*;
 
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.LocalizableMessageBuilder;
 import org.opends.server.admin.DecodingException;
 import org.opends.server.admin.ManagedObjectDefinition;
 import org.opends.server.admin.PropertyException;
-import org.opends.server.util.Validator;
+
+import com.forgerock.opendj.util.Validator;
 
 
 
@@ -59,25 +59,25 @@
 
 
   // Create the message.
-  private static Message createMessage(ManagedObject<?> partialManagedObject,
+  private static LocalizableMessage createMessage(ManagedObject<?> partialManagedObject,
       Collection<PropertyException> causes) {
     Validator.ensureNotNull(causes);
-    Validator.ensureTrue(!causes.isEmpty());
+    Validator.ensureTrue(!causes.isEmpty(), "causes should not be empty");
 
     ManagedObjectDefinition<?, ?> d = partialManagedObject
         .getManagedObjectDefinition();
     if (causes.size() == 1) {
       return ERR_MANAGED_OBJECT_DECODING_EXCEPTION_SINGLE.get(d
-          .getUserFriendlyName(), causes.iterator().next().getMessageObject());
+          .getUserFriendlyName(), causes.iterator().next().getLocalizableMessageObject());
     } else {
-      MessageBuilder builder = new MessageBuilder();
+      LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
 
       boolean isFirst = true;
       for (PropertyException cause : causes) {
         if (!isFirst) {
           builder.append("; ");
         }
-        builder.append(cause.getMessageObject());
+        builder.append(cause.getLocalizableMessageObject());
         isFirst = false;
       }
 
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/ManagementContext.java b/opendj-admin/src/main/java/org/opends/server/admin/client/ManagementContext.java
index 0a1d047..b3517d9 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/ManagementContext.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/ManagementContext.java
@@ -27,11 +27,10 @@
 
 package org.opends.server.admin.client;
 
-
-
 import java.util.Set;
 import java.util.SortedSet;
 
+import org.forgerock.opendj.admin.client.RootCfgClient;
 import org.opends.server.admin.AbstractManagedObjectDefinition;
 import org.opends.server.admin.Configuration;
 import org.opends.server.admin.ConfigurationClient;
@@ -44,485 +43,414 @@
 import org.opends.server.admin.PropertyException;
 import org.opends.server.admin.SetRelationDefinition;
 import org.opends.server.admin.client.spi.Driver;
-import org.opends.server.admin.std.client.RootCfgClient;
-
-
 
 /**
  * Client management connection context.
  */
 public abstract class ManagementContext {
 
-  /**
-   * Creates a new management context.
-   */
-  protected ManagementContext() {
-    // No implementation required.
-  }
-
-
-
-  /**
-   * Deletes the named instantiable child managed object from the
-   * named parent managed object.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          relation definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          relation definition refers to.
-   * @param parent
-   *          The path of the parent managed object.
-   * @param rd
-   *          The instantiable relation definition.
-   * @param name
-   *          The name of the child managed object to be removed.
-   * @return Returns <code>true</code> if the named instantiable
-   *         child managed object was found, or <code>false</code>
-   *         if it was not found.
-   * @throws IllegalArgumentException
-   *           If the relation definition is not associated with the
-   *           parent managed object's definition.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @throws OperationRejectedException
-   *           If the managed object cannot be removed due to some
-   *           client-side or server-side constraint which cannot be
-   *           satisfied (for example, if it is referenced by another
-   *           managed object).
-   * @throws AuthorizationException
-   *           If the server refuses to remove 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.
-   */
-  public final <C extends ConfigurationClient, S extends Configuration>
-  boolean deleteManagedObject(
-      ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
-      String name) throws IllegalArgumentException,
-      ManagedObjectNotFoundException, OperationRejectedException,
-      AuthorizationException, CommunicationException {
-    return getDriver().deleteManagedObject(parent, rd, name);
-  }
-
-
-
-  /**
-   * Deletes the optional child managed object from the named parent
-   * managed object.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          relation definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          relation definition refers to.
-   * @param parent
-   *          The path of the parent managed object.
-   * @param rd
-   *          The optional relation definition.
-   * @return Returns <code>true</code> if the optional child managed
-   *         object was found, or <code>false</code> if it was not
-   *         found.
-   * @throws IllegalArgumentException
-   *           If the relation definition is not associated with the
-   *           parent managed object's definition.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @throws OperationRejectedException
-   *           If the managed object cannot be removed due to some
-   *           client-side or server-side constraint which cannot be
-   *           satisfied (for example, if it is referenced by another
-   *           managed object).
-   * @throws AuthorizationException
-   *           If the server refuses to remove 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.
-   */
-  public final <C extends ConfigurationClient, S extends Configuration>
-  boolean deleteManagedObject(
-      ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd)
-      throws IllegalArgumentException, ManagedObjectNotFoundException,
-      OperationRejectedException, AuthorizationException,
-      CommunicationException {
-    return getDriver().deleteManagedObject(parent, rd);
-  }
-
-
-
-  /**
-   * Deletes s set child managed object from the
-   * named parent managed object.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          relation definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          relation definition refers to.
-   * @param parent
-   *          The path of the parent managed object.
-   * @param rd
-   *          The set relation definition.
-   * @param name
-   *          The name of the child managed object to be removed.
-   * @return Returns <code>true</code> if the set
-   *         child managed object was found, or <code>false</code>
-   *         if it was not found.
-   * @throws IllegalArgumentException
-   *           If the relation definition is not associated with the
-   *           parent managed object's definition.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @throws OperationRejectedException
-   *           If the managed object cannot be removed due to some
-   *           client-side or server-side constraint which cannot be
-   *           satisfied (for example, if it is referenced by another
-   *           managed object).
-   * @throws AuthorizationException
-   *           If the server refuses to remove 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.
-   */
-  public final <C extends ConfigurationClient, S extends Configuration>
-  boolean deleteManagedObject(
-      ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd,
-      String name) throws IllegalArgumentException,
-      ManagedObjectNotFoundException, OperationRejectedException,
-      AuthorizationException, CommunicationException {
-    return getDriver().deleteManagedObject(parent, rd, name);
-  }
-
-
-
-  /**
-   * Gets the named managed object.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          path definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          path definition refers to.
-   * @param path
-   *          The path of the managed object.
-   * @return Returns the named managed object.
-   * @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 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.
-   */
-  @SuppressWarnings("unchecked")
-  public final <C extends ConfigurationClient, S extends Configuration>
-  ManagedObject<? extends C> getManagedObject(
-      ManagedObjectPath<C, S> path) throws DefinitionDecodingException,
-      ManagedObjectDecodingException, ManagedObjectNotFoundException,
-      AuthorizationException, CommunicationException {
-    // Be careful to handle the root configuration.
-    if (path.isEmpty()) {
-      return (ManagedObject<C>) getRootConfigurationManagedObject();
+    /**
+     * Creates a new management context.
+     */
+    protected ManagementContext() {
+        // No implementation required.
     }
 
-    return getDriver().getManagedObject(path);
-  }
-
-
-
-  /**
-   * Gets the effective value of a property in the named managed
-   * object.
-   *
-   * @param <PD>
-   *          The type of the property to be retrieved.
-   * @param path
-   *          The path of the managed object containing the property.
-   * @param pd
-   *          The property to be retrieved.
-   * @return Returns the property's effective value, or
-   *         <code>null</code> if there are no values defined.
-   * @throws IllegalArgumentException
-   *           If the property definition is not associated with the
-   *           referenced managed object's definition.
-   * @throws DefinitionDecodingException
-   *           If the managed object was found but its type could not
-   *           be determined.
-   * @throws PropertyException
-   *           If the managed object was found but the requested
-   *           property could not be decoded.
-   * @throws ManagedObjectNotFoundException
-   *           If the requested managed object could not be found on
-   *           the server.
-   * @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.
-   */
-  public final <PD> PD getPropertyValue(ManagedObjectPath<?, ?> path,
-      PropertyDefinition<PD> pd) throws IllegalArgumentException,
-      DefinitionDecodingException, AuthorizationException,
-      ManagedObjectNotFoundException, CommunicationException,
-      PropertyException {
-    Set<PD> values = getPropertyValues(path, pd);
-    if (values.isEmpty()) {
-      return null;
-    } else {
-      return values.iterator().next();
+    /**
+     * Deletes the named instantiable child managed object from the named parent
+     * managed object.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the
+     *            relation definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the
+     *            relation definition refers to.
+     * @param parent
+     *            The path of the parent managed object.
+     * @param rd
+     *            The instantiable relation definition.
+     * @param name
+     *            The name of the child managed object to be removed.
+     * @return Returns <code>true</code> if the named instantiable child managed
+     *         object was found, or <code>false</code> if it was not found.
+     * @throws IllegalArgumentException
+     *             If the relation definition is not associated with the parent
+     *             managed object's definition.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @throws OperationRejectedException
+     *             If the managed object cannot be removed due to some
+     *             client-side or server-side constraint which cannot be
+     *             satisfied (for example, if it is referenced by another
+     *             managed object).
+     * @throws AuthorizationException
+     *             If the server refuses to remove 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.
+     */
+    public final <C extends ConfigurationClient, S extends Configuration> boolean deleteManagedObject(
+            ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd, String name)
+            throws IllegalArgumentException, ManagedObjectNotFoundException, OperationRejectedException,
+            AuthorizationException, CommunicationException {
+        return getDriver().deleteManagedObject(parent, rd, name);
     }
-  }
 
+    /**
+     * Deletes the optional child managed object from the named parent managed
+     * object.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the
+     *            relation definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the
+     *            relation definition refers to.
+     * @param parent
+     *            The path of the parent managed object.
+     * @param rd
+     *            The optional relation definition.
+     * @return Returns <code>true</code> if the optional child managed object
+     *         was found, or <code>false</code> if it was not found.
+     * @throws IllegalArgumentException
+     *             If the relation definition is not associated with the parent
+     *             managed object's definition.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @throws OperationRejectedException
+     *             If the managed object cannot be removed due to some
+     *             client-side or server-side constraint which cannot be
+     *             satisfied (for example, if it is referenced by another
+     *             managed object).
+     * @throws AuthorizationException
+     *             If the server refuses to remove 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.
+     */
+    public final <C extends ConfigurationClient, S extends Configuration> boolean deleteManagedObject(
+            ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd) throws IllegalArgumentException,
+            ManagedObjectNotFoundException, OperationRejectedException, AuthorizationException, CommunicationException {
+        return getDriver().deleteManagedObject(parent, rd);
+    }
 
+    /**
+     * Deletes s set child managed object from the named parent managed object.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the
+     *            relation definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the
+     *            relation definition refers to.
+     * @param parent
+     *            The path of the parent managed object.
+     * @param rd
+     *            The set relation definition.
+     * @param name
+     *            The name of the child managed object to be removed.
+     * @return Returns <code>true</code> if the set child managed object was
+     *         found, or <code>false</code> if it was not found.
+     * @throws IllegalArgumentException
+     *             If the relation definition is not associated with the parent
+     *             managed object's definition.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @throws OperationRejectedException
+     *             If the managed object cannot be removed due to some
+     *             client-side or server-side constraint which cannot be
+     *             satisfied (for example, if it is referenced by another
+     *             managed object).
+     * @throws AuthorizationException
+     *             If the server refuses to remove 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.
+     */
+    public final <C extends ConfigurationClient, S extends Configuration> boolean deleteManagedObject(
+            ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd, String name)
+            throws IllegalArgumentException, ManagedObjectNotFoundException, OperationRejectedException,
+            AuthorizationException, CommunicationException {
+        return getDriver().deleteManagedObject(parent, rd, name);
+    }
 
-  /**
-   * Gets the effective values of a property in the named managed
-   * object.
-   *
-   * @param <PD>
-   *          The type of the property to be retrieved.
-   * @param path
-   *          The path of the managed object containing the property.
-   * @param pd
-   *          The property to be retrieved.
-   * @return Returns the property's effective values, or an empty set
-   *         if there are no values defined.
-   * @throws IllegalArgumentException
-   *           If the property definition is not associated with the
-   *           referenced managed object's definition.
-   * @throws DefinitionDecodingException
-   *           If the managed object was found but its type could not
-   *           be determined.
-   * @throws PropertyException
-   *           If the managed object was found but the requested
-   *           property could not be decoded.
-   * @throws ManagedObjectNotFoundException
-   *           If the requested managed object could not be found on
-   *           the server.
-   * @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.
-   */
-  public final <PD> SortedSet<PD> getPropertyValues(
-      ManagedObjectPath<?, ?> path, PropertyDefinition<PD> pd)
-      throws IllegalArgumentException, DefinitionDecodingException,
-      AuthorizationException, ManagedObjectNotFoundException,
-      CommunicationException, PropertyException {
-    return getDriver().getPropertyValues(path, pd);
-  }
+    /**
+     * Gets the named managed object.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the path
+     *            definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the path
+     *            definition refers to.
+     * @param path
+     *            The path of the managed object.
+     * @return Returns the named managed object.
+     * @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 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.
+     */
+    @SuppressWarnings("unchecked")
+    public final <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getManagedObject(
+            ManagedObjectPath<C, S> path) throws DefinitionDecodingException, ManagedObjectDecodingException,
+            ManagedObjectNotFoundException, AuthorizationException, CommunicationException {
+        // Be careful to handle the root configuration.
+        if (path.isEmpty()) {
+            return (ManagedObject<C>) getRootConfigurationManagedObject();
+        }
 
+        return getDriver().getManagedObject(path);
+    }
 
+    /**
+     * Gets the effective value of a property in the named managed object.
+     *
+     * @param <PD>
+     *            The type of the property to be retrieved.
+     * @param path
+     *            The path of the managed object containing the property.
+     * @param pd
+     *            The property to be retrieved.
+     * @return Returns the property's effective value, or <code>null</code> if
+     *         there are no values defined.
+     * @throws IllegalArgumentException
+     *             If the property definition is not associated with the
+     *             referenced managed object's definition.
+     * @throws DefinitionDecodingException
+     *             If the managed object was found but its type could not be
+     *             determined.
+     * @throws PropertyException
+     *             If the managed object was found but the requested property
+     *             could not be decoded.
+     * @throws ManagedObjectNotFoundException
+     *             If the requested managed object could not be found on the
+     *             server.
+     * @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.
+     */
+    public final <PD> PD getPropertyValue(ManagedObjectPath<?, ?> path, PropertyDefinition<PD> pd)
+            throws IllegalArgumentException, DefinitionDecodingException, AuthorizationException,
+            ManagedObjectNotFoundException, CommunicationException, PropertyException {
+        Set<PD> values = getPropertyValues(path, pd);
+        if (values.isEmpty()) {
+            return null;
+        } else {
+            return values.iterator().next();
+        }
+    }
 
-  /**
-   * Gets the root configuration client associated with this
-   * management context.
-   *
-   * @return Returns the root configuration client associated with
-   *         this management context.
-   */
-  public final RootCfgClient getRootConfiguration() {
-    return getRootConfigurationManagedObject().getConfiguration();
-  }
+    /**
+     * Gets the effective values of a property in the named managed object.
+     *
+     * @param <PD>
+     *            The type of the property to be retrieved.
+     * @param path
+     *            The path of the managed object containing the property.
+     * @param pd
+     *            The property to be retrieved.
+     * @return Returns the property's effective values, or an empty set if there
+     *         are no values defined.
+     * @throws IllegalArgumentException
+     *             If the property definition is not associated with the
+     *             referenced managed object's definition.
+     * @throws DefinitionDecodingException
+     *             If the managed object was found but its type could not be
+     *             determined.
+     * @throws PropertyException
+     *             If the managed object was found but the requested property
+     *             could not be decoded.
+     * @throws ManagedObjectNotFoundException
+     *             If the requested managed object could not be found on the
+     *             server.
+     * @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.
+     */
+    public final <PD> SortedSet<PD> getPropertyValues(ManagedObjectPath<?, ?> path, PropertyDefinition<PD> pd)
+            throws IllegalArgumentException, DefinitionDecodingException, AuthorizationException,
+            ManagedObjectNotFoundException, CommunicationException, PropertyException {
+        return getDriver().getPropertyValues(path, pd);
+    }
 
+    /**
+     * Gets the root configuration client associated with this management
+     * context.
+     *
+     * @return Returns the root configuration client associated with this
+     *         management context.
+     */
+    public final RootCfgClient getRootConfiguration() {
+        return getRootConfigurationManagedObject().getConfiguration();
+    }
 
+    /**
+     * Gets the root configuration managed object associated with this
+     * management context.
+     *
+     * @return Returns the root configuration managed object associated with
+     *         this management context.
+     */
+    public final ManagedObject<RootCfgClient> getRootConfigurationManagedObject() {
+        return getDriver().getRootConfigurationManagedObject();
+    }
 
-  /**
-   * Gets the root configuration managed object associated with this
-   * management context.
-   *
-   * @return Returns the root configuration managed object associated
-   *         with this management context.
-   */
-  public final
-  ManagedObject<RootCfgClient> getRootConfigurationManagedObject() {
-    return getDriver().getRootConfigurationManagedObject();
-  }
+    /**
+     * Lists the child managed objects of the named parent managed object.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the
+     *            relation definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the
+     *            relation definition refers to.
+     * @param parent
+     *            The path of the parent managed object.
+     * @param rd
+     *            The instantiable relation definition.
+     * @return Returns the names of the child managed objects.
+     * @throws IllegalArgumentException
+     *             If the relation definition is not associated with the parent
+     *             managed object's definition.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @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.
+     */
+    public final <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects(
+            ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd) throws IllegalArgumentException,
+            ManagedObjectNotFoundException, AuthorizationException, CommunicationException {
+        return listManagedObjects(parent, rd, rd.getChildDefinition());
+    }
 
+    /**
+     * Lists the child managed objects of the named parent managed object which
+     * are a sub-type of the specified managed object definition.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the
+     *            relation definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the
+     *            relation definition refers to.
+     * @param parent
+     *            The path of the parent managed object.
+     * @param rd
+     *            The instantiable relation definition.
+     * @param d
+     *            The managed object definition.
+     * @return Returns the names of the child managed objects which are a
+     *         sub-type of the specified managed object definition.
+     * @throws IllegalArgumentException
+     *             If the relation definition is not associated with the parent
+     *             managed object's definition.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @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.
+     */
+    public final <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects(
+            ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
+            AbstractManagedObjectDefinition<? extends C, ? extends S> d) throws IllegalArgumentException,
+            ManagedObjectNotFoundException, AuthorizationException, CommunicationException {
+        return getDriver().listManagedObjects(parent, rd, d);
+    }
 
+    /**
+     * Lists the child managed objects of the named parent managed object.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the
+     *            relation definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the
+     *            relation definition refers to.
+     * @param parent
+     *            The path of the parent managed object.
+     * @param rd
+     *            The set relation definition.
+     * @return Returns the names of the child managed objects.
+     * @throws IllegalArgumentException
+     *             If the relation definition is not associated with the parent
+     *             managed object's definition.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @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.
+     */
+    public final <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects(
+            ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd) throws IllegalArgumentException,
+            ManagedObjectNotFoundException, AuthorizationException, CommunicationException {
+        return getDriver().listManagedObjects(parent, rd, rd.getChildDefinition());
+    }
 
-  /**
-   * Lists the child managed objects of the named parent managed
-   * object.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          relation definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          relation definition refers to.
-   * @param parent
-   *          The path of the parent managed object.
-   * @param rd
-   *          The instantiable relation definition.
-   * @return Returns the names of the child managed objects.
-   * @throws IllegalArgumentException
-   *           If the relation definition is not associated with the
-   *           parent managed object's definition.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @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.
-   */
-  public final <C extends ConfigurationClient, S extends Configuration>
-  String[] listManagedObjects(
-      ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd)
-      throws IllegalArgumentException, ManagedObjectNotFoundException,
-      AuthorizationException, CommunicationException {
-    return listManagedObjects(parent, rd, rd.getChildDefinition());
-  }
+    /**
+     * Determines whether or not the named managed object exists.
+     *
+     * @param path
+     *            The path of the named managed object.
+     * @return Returns <code>true</code> if the named managed object exists,
+     *         <code>false</code> otherwise.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @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.
+     */
+    public final boolean managedObjectExists(ManagedObjectPath<?, ?> path) throws ManagedObjectNotFoundException,
+            AuthorizationException, CommunicationException {
+        return getDriver().managedObjectExists(path);
+    }
 
+    /**
+     * Gets the driver associated with this management context.
+     *
+     * @return Returns the driver associated with this management context.
+     */
+    protected abstract Driver getDriver();
 
-
-  /**
-   * Lists the child managed objects of the named parent managed
-   * object which are a sub-type of the specified managed object
-   * definition.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          relation definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          relation definition refers to.
-   * @param parent
-   *          The path of the parent managed object.
-   * @param rd
-   *          The instantiable relation definition.
-   * @param d
-   *          The managed object definition.
-   * @return Returns the names of the child managed objects which are
-   *         a sub-type of the specified managed object definition.
-   * @throws IllegalArgumentException
-   *           If the relation definition is not associated with the
-   *           parent managed object's definition.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @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.
-   */
-  public final <C extends ConfigurationClient, S extends Configuration>
-  String[] listManagedObjects(
-      ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
-      AbstractManagedObjectDefinition<? extends C, ? extends S> d)
-      throws IllegalArgumentException, ManagedObjectNotFoundException,
-      AuthorizationException, CommunicationException {
-    return getDriver().listManagedObjects(parent, rd, d);
-  }
-
-
-
-  /**
-   * Lists the child managed objects of the named parent managed
-   * object.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          relation definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          relation definition refers to.
-   * @param parent
-   *          The path of the parent managed object.
-   * @param rd
-   *          The set relation definition.
-   * @return Returns the names of the child managed objects.
-   * @throws IllegalArgumentException
-   *           If the relation definition is not associated with the
-   *           parent managed object's definition.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @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.
-   */
-  public final <C extends ConfigurationClient, S extends Configuration>
-  String[] listManagedObjects(
-      ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd)
-      throws IllegalArgumentException, ManagedObjectNotFoundException,
-      AuthorizationException, CommunicationException {
-    return getDriver().listManagedObjects(parent, rd, rd.getChildDefinition());
-  }
-
-
-
-  /**
-   * Determines whether or not the named managed object exists.
-   *
-   * @param path
-   *          The path of the named managed object.
-   * @return Returns <code>true</code> if the named managed object
-   *         exists, <code>false</code> otherwise.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @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.
-   */
-  public final boolean managedObjectExists(ManagedObjectPath<?, ?> path)
-      throws ManagedObjectNotFoundException, AuthorizationException,
-      CommunicationException {
-    return getDriver().managedObjectExists(path);
-  }
-
-
-
-  /**
-   * Gets the driver associated with this management context.
-   *
-   * @return Returns the driver associated with this management
-   *         context.
-   */
-  protected abstract Driver getDriver();
-
-
-
-  /**
-   * Closes this management context.
-   */
-  public final void close() {
-    this.getDriver().close();
-  }
+    /**
+     * Closes this management context.
+     */
+    public final void close() {
+        this.getDriver().close();
+    }
 
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/MissingMandatoryPropertiesException.java b/opendj-admin/src/main/java/org/opends/server/admin/client/MissingMandatoryPropertiesException.java
index 4d9b598..3183ece 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/MissingMandatoryPropertiesException.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/MissingMandatoryPropertiesException.java
@@ -29,17 +29,18 @@
 
 
 
-import static org.opends.messages.AdminMessages.*;
+import static com.forgerock.opendj.ldap.AdminMessages.*;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 
-import org.opends.messages.Message;
-import org.opends.messages.MessageBuilder;
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.LocalizableMessageBuilder;
 import org.opends.server.admin.OperationsException;
 import org.opends.server.admin.PropertyIsMandatoryException;
-import org.opends.server.util.Validator;
+
+import com.forgerock.opendj.util.Validator;
 
 
 
@@ -58,16 +59,16 @@
 
 
   // Create the message.
-  private static Message createMessage(
+  private static LocalizableMessage createMessage(
       Collection<PropertyIsMandatoryException> causes) {
     Validator.ensureNotNull(causes);
-    Validator.ensureTrue(!causes.isEmpty());
+    Validator.ensureTrue(!causes.isEmpty(), "causes should not be empty");
 
     if (causes.size() == 1) {
       return ERR_MISSING_MANDATORY_PROPERTIES_EXCEPTION_SINGLE.get(causes
           .iterator().next().getPropertyDefinition().getName());
     } else {
-      MessageBuilder builder = new MessageBuilder();
+      LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
 
       boolean isFirst = true;
       for (PropertyIsMandatoryException cause : causes) {
@@ -92,7 +93,7 @@
 
   // The user friendly name of the component that caused this
   // exception.
-  private final Message ufn;
+  private final LocalizableMessage ufn;
 
 
 
@@ -110,7 +111,7 @@
    *          Indicates whether the exception occurred during managed
    *          object creation.
    */
-  public MissingMandatoryPropertiesException(Message ufn,
+  public MissingMandatoryPropertiesException(LocalizableMessage ufn,
       Collection<PropertyIsMandatoryException> causes, boolean isCreate) {
     super(createMessage(causes));
 
@@ -153,7 +154,7 @@
    * @return Returns the user friendly name of the component that
    *         caused this exception.
    */
-  public Message getUserFriendlyName() {
+  public LocalizableMessage getUserFriendlyName() {
     return ufn;
   }
 
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/OperationRejectedException.java b/opendj-admin/src/main/java/org/opends/server/admin/client/OperationRejectedException.java
index 73030e0..658f986 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/OperationRejectedException.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/OperationRejectedException.java
@@ -27,217 +27,184 @@
 
 package org.opends.server.admin.client;
 
-
-
-import static org.opends.messages.AdminMessages.*;
+import static com.forgerock.opendj.ldap.AdminMessages.*;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 
-import org.opends.messages.Message;
-import org.opends.messages.MessageBuilder;
-import org.opends.server.util.Validator;
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.LocalizableMessageBuilder;
 
-
+import com.forgerock.opendj.util.Validator;
 
 /**
- * This exception is thrown when the client or server refuses to
- * create, delete, or modify a managed object due to one or more
- * constraints that cannot be satisfied.
+ * This exception is thrown when the client or server refuses to create, delete,
+ * or modify a managed object due to one or more constraints that cannot be
+ * satisfied.
  * <p>
- * Operations can be rejected either by a client-side constraint
- * violation triggered by {@link ClientConstraintHandler}, or by a
- * server-side error.
+ * Operations can be rejected either by a client-side constraint violation
+ * triggered by {@link ClientConstraintHandler}, or by a server-side error.
  * <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.
+ * 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 {
 
-  /**
-   * The type of operation that caused this exception.
-   */
-  public enum OperationType {
     /**
-     * A managed object could not be created.
+     * The type of operation that caused this exception.
      */
-    CREATE,
+    public enum OperationType {
+        /**
+         * A managed object could not be created.
+         */
+        CREATE,
 
-    /**
-     * A managed object could not be deleted.
-     */
-    DELETE,
+        /**
+         * A managed object could not be deleted.
+         */
+        DELETE,
 
-    /**
-     * A managed object could not be modified.
-     */
-    MODIFY;
-  }
-
-  /**
-   * Serialization ID.
-   */
-  private static final long serialVersionUID = 8547688890613079044L;
-
-
-
-  // Gets the default message.
-  private static Message getDefaultMessage(Collection<Message> messages) {
-    Validator.ensureNotNull(messages);
-    Validator.ensureTrue(!messages.isEmpty());
-
-    if (messages.size() == 1) {
-      return ERR_OPERATION_REJECTED_EXCEPTION_SINGLE.get(messages.iterator()
-          .next());
-    } else {
-      return ERR_OPERATION_REJECTED_EXCEPTION_PLURAL
-          .get(getSingleMessage(messages));
+        /**
+         * A managed object could not be modified.
+         */
+        MODIFY;
     }
-  }
 
+    /**
+     * Serialization ID.
+     */
+    private static final long serialVersionUID = 8547688890613079044L;
 
+    // Gets the default message.
+    private static LocalizableMessage getDefaultMessage(Collection<LocalizableMessage> messages) {
+        Validator.ensureNotNull(messages);
+        Validator.ensureTrue(!messages.isEmpty(), "Messages should not be empty");
 
-  // Merge the messages into a single message.
-  private static Message getSingleMessage(Collection<Message> messages) {
-    if (messages.size() == 1) {
-      return messages.iterator().next();
-    } else {
-      MessageBuilder builder = new MessageBuilder();
-
-      boolean isFirst = true;
-      for (Message m : messages) {
-        if (!isFirst) {
-          builder.append(";  ");
+        if (messages.size() == 1) {
+            return ERR_OPERATION_REJECTED_EXCEPTION_SINGLE.get(messages.iterator().next());
+        } else {
+            return ERR_OPERATION_REJECTED_EXCEPTION_PLURAL.get(getSingleMessage(messages));
         }
-        builder.append(m);
-        isFirst = false;
-      }
-
-      return builder.toMessage();
     }
-  }
 
-  // The messages describing the constraint violations that occurred.
-  private final Collection<Message> messages;
+    // Merge the messages into a single message.
+    private static LocalizableMessage getSingleMessage(Collection<LocalizableMessage> messages) {
+        if (messages.size() == 1) {
+            return messages.iterator().next();
+        } else {
+            LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
 
-  // The type of operation that caused this exception.
-  private final OperationType type;
+            boolean isFirst = true;
+            for (LocalizableMessage m : messages) {
+                if (!isFirst) {
+                    builder.append(";  ");
+                }
+                builder.append(m);
+                isFirst = false;
+            }
 
-  // The user friendly name of the component that caused this
-  // exception.
-  private final Message ufn;
+            return builder.toMessage();
+        }
+    }
 
+    // The messages describing the constraint violations that occurred.
+    private final Collection<LocalizableMessage> messages;
 
+    // The type of operation that caused this exception.
+    private final OperationType type;
 
-  /**
-   * Creates a new operation rejected exception with a default
-   * message.
-   *
-   * @param type
-   *          The type of operation that caused this exception.
-   * @param ufn
-   *          The user friendly name of the component that caused this
-   *          exception.
-   */
-  public OperationRejectedException(OperationType type, Message ufn) {
-    this(type, ufn, ERR_OPERATION_REJECTED_DEFAULT.get());
-  }
+    // The user friendly name of the component that caused this
+    // exception.
+    private final LocalizableMessage ufn;
 
+    /**
+     * Creates a new operation rejected exception with a default message.
+     *
+     * @param type
+     *            The type of operation that caused this exception.
+     * @param ufn
+     *            The user friendly name of the component that caused this
+     *            exception.
+     */
+    public OperationRejectedException(OperationType type, LocalizableMessage ufn) {
+        this(type, ufn, ERR_OPERATION_REJECTED_DEFAULT.get());
+    }
 
+    /**
+     * Creates a new operation rejected exception with the provided messages.
+     *
+     * @param type
+     *            The type of operation that caused this exception.
+     * @param ufn
+     *            The user friendly name of the component that caused this
+     *            exception.
+     * @param messages
+     *            The messages describing the constraint violations that
+     *            occurred (must be non-<code>null</code> and non-empty).
+     */
+    public OperationRejectedException(OperationType type, LocalizableMessage ufn, Collection<LocalizableMessage> messages) {
+        super(getDefaultMessage(messages));
 
-  /**
-   * Creates a new operation rejected exception with the provided
-   * messages.
-   *
-   * @param type
-   *          The type of operation that caused this exception.
-   * @param ufn
-   *          The user friendly name of the component that caused this
-   *          exception.
-   * @param messages
-   *          The messages describing the constraint violations that
-   *          occurred (must be non-<code>null</code> and
-   *          non-empty).
-   */
-  public OperationRejectedException(OperationType type, Message ufn,
-      Collection<Message> messages) {
-    super(getDefaultMessage(messages));
+        this.messages = new ArrayList<LocalizableMessage>(messages);
+        this.type = type;
+        this.ufn = ufn;
+    }
 
-    this.messages = new ArrayList<Message>(messages);
-    this.type = type;
-    this.ufn = ufn;
-  }
+    /**
+     * Creates a new operation rejected exception with the provided message.
+     *
+     * @param type
+     *            The type of operation that caused this exception.
+     * @param ufn
+     *            The user friendly name of the component that caused this
+     *            exception.
+     * @param message
+     *            The message describing the constraint violation that occurred.
+     */
+    public OperationRejectedException(OperationType type, LocalizableMessage ufn, LocalizableMessage message) {
+        this(type, ufn, Collections.singleton(message));
+    }
 
+    /**
+     * Gets an unmodifiable collection view of the messages describing the
+     * constraint violations that occurred.
+     *
+     * @return Returns an unmodifiable collection view of the messages
+     *         describing the constraint violations that occurred.
+     */
+    public Collection<LocalizableMessage> getMessages() {
+        return Collections.unmodifiableCollection(messages);
+    }
 
+    /**
+     * Creates a single message listing all the messages combined into a single
+     * list separated by semi-colons.
+     *
+     * @return Returns a single message listing all the messages combined into a
+     *         single list separated by semi-colons.
+     */
+    public LocalizableMessage getMessagesAsSingleMessage() {
+        return getSingleMessage(messages);
+    }
 
-  /**
-   * Creates a new operation rejected exception with the provided
-   * message.
-   *
-   * @param type
-   *          The type of operation that caused this exception.
-   * @param ufn
-   *          The user friendly name of the component that caused this
-   *          exception.
-   * @param message
-   *          The message describing the constraint violation that
-   *          occurred.
-   */
-  public OperationRejectedException(OperationType type, Message ufn,
-      Message message) {
-    this(type, ufn, Collections.singleton(message));
-  }
+    /**
+     * Gets the type of operation that caused this exception.
+     *
+     * @return Returns the type of operation that caused this exception.
+     */
+    public OperationType getOperationType() {
+        return type;
+    }
 
-
-
-  /**
-   * Gets an unmodifiable collection view of the messages describing
-   * the constraint violations that occurred.
-   *
-   * @return Returns an unmodifiable collection view of the messages
-   *         describing the constraint violations that occurred.
-   */
-  public Collection<Message> getMessages() {
-    return Collections.unmodifiableCollection(messages);
-  }
-
-
-
-  /**
-   * Creates a single message listing all the messages combined into a
-   * single list separated by semi-colons.
-   *
-   * @return Returns a single message listing all the messages
-   *         combined into a single list separated by semi-colons.
-   */
-  public Message getMessagesAsSingleMessage() {
-    return getSingleMessage(messages);
-  }
-
-
-
-  /**
-   * Gets the type of operation that caused this exception.
-   *
-   * @return Returns the type of operation that caused this exception.
-   */
-  public OperationType getOperationType() {
-    return type;
-  }
-
-
-
-  /**
-   * Gets the user friendly name of the component that caused this
-   * exception.
-   *
-   * @return Returns the user friendly name of the component that
-   *         caused this exception.
-   */
-  public Message getUserFriendlyName() {
-    return ufn;
-  }
+    /**
+     * Gets the user friendly name of the component that caused this exception.
+     *
+     * @return Returns the user friendly name of the component that caused this
+     *         exception.
+     */
+    public LocalizableMessage getUserFriendlyName() {
+        return ufn;
+    }
 
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/package-info.java b/opendj-admin/src/main/java/org/opends/server/admin/client/package-info.java
index 6bfb68b..470ae16 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/package-info.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/package-info.java
@@ -25,15 +25,11 @@
  *      Copyright 2008 Sun Microsystems, Inc.
  */
 
-
-
 /**
  * Common client-side administration classes.
  * <p>
  * This package contains classes which client applications are
  * expected to use.
  */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.PRIVATE)
 package org.opends.server.admin.client;
 
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/spi/Driver.java b/opendj-admin/src/main/java/org/opends/server/admin/client/spi/Driver.java
index 99621ec..f88c255 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/spi/Driver.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/spi/Driver.java
@@ -27,8 +27,6 @@
 
 package org.opends.server.admin.client.spi;
 
-
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -36,7 +34,8 @@
 import java.util.List;
 import java.util.SortedSet;
 
-import org.opends.messages.Message;
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.opendj.admin.client.RootCfgClient;
 import org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider;
 import org.opends.server.admin.AbstractManagedObjectDefinition;
 import org.opends.server.admin.AliasDefaultBehaviorProvider;
@@ -70,740 +69,637 @@
 import org.opends.server.admin.client.ManagementContext;
 import org.opends.server.admin.client.OperationRejectedException;
 import org.opends.server.admin.client.OperationRejectedException.OperationType;
-import org.opends.server.admin.std.client.RootCfgClient;
-
-
 
 /**
- * An abstract management connection context driver which should form
- * the basis of driver implementations.
+ * An abstract management connection context driver which should form the basis
+ * of driver implementations.
  */
 public abstract class Driver {
 
-  /**
-   * A default behavior visitor used for retrieving the default values
-   * of a property.
-   *
-   * @param <T>
-   *          The type of the property.
-   */
-  private class DefaultValueFinder<T> implements
-      DefaultBehaviorProviderVisitor<T, Collection<T>, Void> {
-
-    // Any exception that occurred whilst retrieving inherited default
-    // values.
-    private DefaultBehaviorException exception = null;
-
-    // The path of the managed object containing the first property.
-    private final ManagedObjectPath<?, ?> firstPath;
-
-    // Indicates whether the managed object has been created yet.
-    private final boolean isCreate;
-
-    // The path of the managed object containing the next property.
-    private ManagedObjectPath<?, ?> nextPath = null;
-
-    // The next property whose default values were required.
-    private PropertyDefinition<T> nextProperty = null;
-
-
-
-    // Private constructor.
-    private DefaultValueFinder(ManagedObjectPath<?, ?> p, boolean isCreate) {
-      this.firstPath = p;
-      this.isCreate = isCreate;
-    }
-
-
-
     /**
-     * {@inheritDoc}
+     * A default behavior visitor used for retrieving the default values of a
+     * property.
+     *
+     * @param <T>
+     *            The type of the property.
      */
-    public Collection<T> visitAbsoluteInherited(
-        AbsoluteInheritedDefaultBehaviorProvider<T> d, Void p) {
-      try {
-        return getInheritedProperty(d.getManagedObjectPath(), d
-            .getManagedObjectDefinition(), d.getPropertyName());
-      } catch (DefaultBehaviorException e) {
-        exception = e;
-        return Collections.emptySet();
-      }
-    }
+    private class DefaultValueFinder<T> implements DefaultBehaviorProviderVisitor<T, Collection<T>, Void> {
 
+        // Any exception that occurred whilst retrieving inherited default
+        // values.
+        private DefaultBehaviorException exception = null;
 
+        // The path of the managed object containing the first property.
+        private final ManagedObjectPath<?, ?> firstPath;
 
-    /**
-     * {@inheritDoc}
-     */
-    public Collection<T> visitAlias(AliasDefaultBehaviorProvider<T> d, Void p) {
-      return Collections.emptySet();
-    }
+        // Indicates whether the managed object has been created yet.
+        private final boolean isCreate;
 
+        // The path of the managed object containing the next property.
+        private ManagedObjectPath<?, ?> nextPath = null;
 
+        // The next property whose default values were required.
+        private PropertyDefinition<T> nextProperty = null;
 
-    /**
-     * {@inheritDoc}
-     */
-    public Collection<T> visitDefined(DefinedDefaultBehaviorProvider<T> d,
-        Void p) {
-      Collection<String> stringValues = d.getDefaultValues();
-      List<T> values = new ArrayList<T>(stringValues.size());
-
-      for (String stringValue : stringValues) {
-        try {
-          values.add(nextProperty.decodeValue(stringValue));
-        } catch (IllegalPropertyValueStringException e) {
-          exception = new DefaultBehaviorException(nextProperty, e);
-          break;
-        }
-      }
-
-      return values;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public Collection<T> visitRelativeInherited(
-        RelativeInheritedDefaultBehaviorProvider<T> d, Void p) {
-      try {
-        return getInheritedProperty(d.getManagedObjectPath(nextPath), d
-            .getManagedObjectDefinition(), d.getPropertyName());
-      } catch (DefaultBehaviorException e) {
-        exception = e;
-        return Collections.emptySet();
-      }
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public Collection<T> visitUndefined(UndefinedDefaultBehaviorProvider<T> d,
-        Void p) {
-      return Collections.emptySet();
-    }
-
-
-
-    // Find the default values for the next path/property.
-    private Collection<T> find(ManagedObjectPath<?, ?> p,
-        PropertyDefinition<T> pd) throws DefaultBehaviorException {
-      this.nextPath = p;
-      this.nextProperty = pd;
-
-      Collection<T> values = nextProperty.getDefaultBehaviorProvider().accept(
-          this, null);
-
-      if (exception != null) {
-        throw exception;
-      }
-
-      if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
-        throw new DefaultBehaviorException(pd,
-            new PropertyIsSingleValuedException(pd));
-      }
-
-      return values;
-    }
-
-
-
-    // Get an inherited property value.
-    @SuppressWarnings("unchecked")
-    private Collection<T> getInheritedProperty(ManagedObjectPath target,
-        AbstractManagedObjectDefinition<?, ?> d, String propertyName)
-        throws DefaultBehaviorException {
-      // First check that the requested type of managed object
-      // corresponds to the path.
-      AbstractManagedObjectDefinition<?, ?> supr = target
-          .getManagedObjectDefinition();
-      if (!supr.isParentOf(d)) {
-        throw new DefaultBehaviorException(
-            nextProperty, new DefinitionDecodingException(supr,
-                Reason.WRONG_TYPE_INFORMATION));
-      }
-
-      // Save the current property in case of recursion.
-      PropertyDefinition<T> pd1 = nextProperty;
-
-      try {
-        // Determine the requested property definition.
-        PropertyDefinition<T> pd2;
-        try {
-          // FIXME: we use the definition taken from the default
-          // behavior here when we should really use the exact
-          // definition of the component being created.
-          PropertyDefinition<?> pdTmp = d.getPropertyDefinition(propertyName);
-          pd2 = pd1.getClass().cast(pdTmp);
-        } catch (IllegalArgumentException e) {
-          throw new PropertyNotFoundException(propertyName);
-        } catch (ClassCastException e) {
-          // FIXME: would be nice to throw a better exception here.
-          throw new PropertyNotFoundException(propertyName);
+        // Private constructor.
+        private DefaultValueFinder(ManagedObjectPath<?, ?> p, boolean isCreate) {
+            this.firstPath = p;
+            this.isCreate = isCreate;
         }
 
-        // If the path relates to the current managed object and the
-        // managed object is in the process of being created it won't
-        // exist, so we should just use the default values of the
-        // referenced property.
-        if (isCreate && firstPath.equals(target)) {
-          // Recursively retrieve this property's default values.
-          Collection<T> tmp = find(target, pd2);
-          Collection<T> values = new ArrayList<T>(tmp.size());
-          for (T value : tmp) {
-            pd1.validateValue(value);
-            values.add(value);
-          }
-          return values;
-        } else {
-          // FIXME: issue 2481 - this is broken if the referenced property
-          // inherits its defaults from the newly created managed object.
-          return getPropertyValues(target, pd2);
+        /**
+         * {@inheritDoc}
+         */
+        public Collection<T> visitAbsoluteInherited(AbsoluteInheritedDefaultBehaviorProvider<T> d, Void p) {
+            try {
+                return getInheritedProperty(d.getManagedObjectPath(), d.getManagedObjectDefinition(),
+                        d.getPropertyName());
+            } catch (DefaultBehaviorException e) {
+                exception = e;
+                return Collections.emptySet();
+            }
         }
-      } catch (DefaultBehaviorException e) {
-        // Wrap any errors due to recursion.
-        throw new DefaultBehaviorException(pd1, e);
-      } catch (DefinitionDecodingException e) {
-        throw new DefaultBehaviorException(pd1, e);
-      } catch (PropertyNotFoundException e) {
-        throw new DefaultBehaviorException(pd1, e);
-      } catch (AuthorizationException e) {
-        throw new DefaultBehaviorException(pd1, e);
-      } catch (ManagedObjectNotFoundException e) {
-        throw new DefaultBehaviorException(pd1, e);
-      } catch (CommunicationException e) {
-        throw new DefaultBehaviorException(pd1, e);
-      } catch (PropertyException e) {
-        throw new DefaultBehaviorException(pd1, e);
-      }
-    }
-  };
 
-
-
-  /**
-   * Creates a new abstract management context.
-   */
-  protected Driver() {
-    // No implementation required.
-  }
-
-
-
-  /**
-   * Closes any context associated with this management context
-   * driver.
-   */
-  public void close() {
-    // do nothing by default
-  }
-
-
-
-  /**
-   * Deletes the named instantiable child managed object from the
-   * named parent managed object.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          relation definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          relation definition refers to.
-   * @param parent
-   *          The path of the parent managed object.
-   * @param rd
-   *          The instantiable relation definition.
-   * @param name
-   *          The name of the child managed object to be removed.
-   * @return Returns <code>true</code> if the named instantiable
-   *         child managed object was found, or <code>false</code>
-   *         if it was not found.
-   * @throws IllegalArgumentException
-   *           If the relation definition is not associated with the
-   *           parent managed object's definition.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @throws OperationRejectedException
-   *           If the managed object cannot be removed due to some
-   *           client-side or server-side constraint which cannot be
-   *           satisfied (for example, if it is referenced by another
-   *           managed object).
-   * @throws AuthorizationException
-   *           If the server refuses to remove 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.
-   */
-  public final <C extends ConfigurationClient, S extends Configuration>
-  boolean deleteManagedObject(
-      ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
-      String name) throws IllegalArgumentException,
-      ManagedObjectNotFoundException, OperationRejectedException,
-      AuthorizationException, CommunicationException {
-    validateRelationDefinition(parent, rd);
-    ManagedObjectPath<?, ?> child = parent.child(rd, name);
-    return doDeleteManagedObject(child);
-  }
-
-
-
-  /**
-   * Deletes the optional child managed object from the named parent
-   * managed object.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          relation definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          relation definition refers to.
-   * @param parent
-   *          The path of the parent managed object.
-   * @param rd
-   *          The optional relation definition.
-   * @return Returns <code>true</code> if the optional child managed
-   *         object was found, or <code>false</code> if it was not
-   *         found.
-   * @throws IllegalArgumentException
-   *           If the relation definition is not associated with the
-   *           parent managed object's definition.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @throws OperationRejectedException
-   *           If the managed object cannot be removed due to some
-   *           client-side or server-side constraint which cannot be
-   *           satisfied (for example, if it is referenced by another
-   *           managed object).
-   * @throws AuthorizationException
-   *           If the server refuses to remove 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.
-   */
-  public final <C extends ConfigurationClient, S extends Configuration>
-  boolean deleteManagedObject(
-      ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd)
-      throws IllegalArgumentException, ManagedObjectNotFoundException,
-      OperationRejectedException, AuthorizationException,
-      CommunicationException {
-    validateRelationDefinition(parent, rd);
-    ManagedObjectPath<?, ?> child = parent.child(rd);
-    return doDeleteManagedObject(child);
-  }
-
-
-
-  /**
-   * Deletes the named instantiable child managed object from the
-   * named parent managed object.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          relation definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          relation definition refers to.
-   * @param parent
-   *          The path of the parent managed object.
-   * @param rd
-   *          The instantiable relation definition.
-   * @param name
-   *          The name of the child managed object to be removed.
-   * @return Returns <code>true</code> if the named instantiable
-   *         child managed object was found, or <code>false</code>
-   *         if it was not found.
-   * @throws IllegalArgumentException
-   *           If the relation definition is not associated with the
-   *           parent managed object's definition.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @throws OperationRejectedException
-   *           If the managed object cannot be removed due to some
-   *           client-side or server-side constraint which cannot be
-   *           satisfied (for example, if it is referenced by another
-   *           managed object).
-   * @throws AuthorizationException
-   *           If the server refuses to remove 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.
-   */
-  public final <C extends ConfigurationClient, S extends Configuration>
-  boolean deleteManagedObject(
-      ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd,
-      String name) throws IllegalArgumentException,
-      ManagedObjectNotFoundException, OperationRejectedException,
-      AuthorizationException, CommunicationException {
-    validateRelationDefinition(parent, rd);
-    ManagedObjectPath<?, ?> child = parent.child(rd, name);
-    return doDeleteManagedObject(child);
-  }
-
-
-
-  /**
-   * Gets the named managed object. The path is guaranteed to be
-   * non-empty, so implementations do not need to worry about handling
-   * this special case.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          path definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          path definition refers to.
-   * @param path
-   *          The non-empty path of the managed object.
-   * @return Returns the named managed object.
-   * @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 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.
-   */
-  public abstract <C extends ConfigurationClient, S extends Configuration>
-  ManagedObject<? extends C> getManagedObject(
-      ManagedObjectPath<C, S> path) throws DefinitionDecodingException,
-      ManagedObjectDecodingException, ManagedObjectNotFoundException,
-      AuthorizationException, CommunicationException;
-
-
-
-  /**
-   * Gets the effective values of a property in the named managed
-   * object.
-   * <p>
-   * Implementations MUST NOT not use
-   * {@link #getManagedObject(ManagedObjectPath)} to read the
-   * referenced managed object in its entirety. Specifically,
-   * implementations MUST only attempt to resolve the default values
-   * for the requested property and its dependencies (if it uses
-   * inherited defaults). This is to avoid infinite recursion where a
-   * managed object contains a property which inherits default values
-   * from another property in the same managed object.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          path definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          path definition refers to.
-   * @param <PD>
-   *          The type of the property to be retrieved.
-   * @param path
-   *          The path of the managed object containing the property.
-   * @param pd
-   *          The property to be retrieved.
-   * @return Returns the property's effective values, or an empty set
-   *         if there are no values defined.
-   * @throws IllegalArgumentException
-   *           If the property definition is not associated with the
-   *           referenced managed object's definition.
-   * @throws DefinitionDecodingException
-   *           If the managed object was found but its type could not
-   *           be determined.
-   * @throws PropertyException
-   *           If the managed object was found but the requested
-   *           property could not be decoded.
-   * @throws ManagedObjectNotFoundException
-   *           If the requested managed object could not be found on
-   *           the server.
-   * @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.
-   */
-  public abstract <C extends ConfigurationClient, S extends Configuration, PD>
-  SortedSet<PD> getPropertyValues(
-      ManagedObjectPath<C, S> path, PropertyDefinition<PD> pd)
-      throws IllegalArgumentException, DefinitionDecodingException,
-      AuthorizationException, ManagedObjectNotFoundException,
-      CommunicationException, PropertyException;
-
-
-
-  /**
-   * Gets the root configuration managed object associated with this
-   * management context driver.
-   *
-   * @return Returns the root configuration managed object associated
-   *         with this management context driver.
-   */
-  public abstract
-  ManagedObject<RootCfgClient> getRootConfigurationManagedObject();
-
-
-
-  /**
-   * Lists the child managed objects of the named parent managed
-   * object which are a sub-type of the specified managed object
-   * definition.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          relation definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          relation definition refers to.
-   * @param parent
-   *          The path of the parent managed object.
-   * @param rd
-   *          The instantiable relation definition.
-   * @param d
-   *          The managed object definition.
-   * @return Returns the names of the child managed objects which are
-   *         a sub-type of the specified managed object definition.
-   * @throws IllegalArgumentException
-   *           If the relation definition is not associated with the
-   *           parent managed object's definition.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @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.
-   */
-  public abstract <C extends ConfigurationClient, S extends Configuration>
-  String[] listManagedObjects(
-      ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
-      AbstractManagedObjectDefinition<? extends C, ? extends S> d)
-      throws IllegalArgumentException, ManagedObjectNotFoundException,
-      AuthorizationException, CommunicationException;
-
-
-
-  /**
-   * Lists the child managed objects of the named parent managed
-   * object which are a sub-type of the specified managed object
-   * definition.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          relation definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          relation definition refers to.
-   * @param parent
-   *          The path of the parent managed object.
-   * @param rd
-   *          The set relation definition.
-   * @param d
-   *          The managed object definition.
-   * @return Returns the names of the child managed objects which are
-   *         a sub-type of the specified managed object definition.
-   * @throws IllegalArgumentException
-   *           If the relation definition is not associated with the
-   *           parent managed object's definition.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @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.
-   */
-  public abstract <C extends ConfigurationClient, S extends Configuration>
-  String[] listManagedObjects(
-      ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd,
-      AbstractManagedObjectDefinition<? extends C, ? extends S> d)
-      throws IllegalArgumentException, ManagedObjectNotFoundException,
-      AuthorizationException, CommunicationException;
-
-
-
-  /**
-   * Determines whether or not the named managed object exists.
-   * <p>
-   * Implementations should always return <code>true</code> when the
-   * provided path is empty.
-   *
-   * @param path
-   *          The path of the named managed object.
-   * @return Returns <code>true</code> if the named managed object
-   *         exists, <code>false</code> otherwise.
-   * @throws ManagedObjectNotFoundException
-   *           If the parent managed object could not be found.
-   * @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.
-   */
-  public abstract boolean managedObjectExists(ManagedObjectPath<?, ?> path)
-      throws ManagedObjectNotFoundException, AuthorizationException,
-      CommunicationException;
-
-
-
-  /**
-   * Deletes the named managed object.
-   * <p>
-   * Implementations do not need check whether the named managed
-   * object exists, nor do they need to enforce client constraints.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that the
-   *          relation definition refers to.
-   * @param <S>
-   *          The type of server managed object configuration that the
-   *          relation definition refers to.
-   * @param path
-   *          The path of the managed object to be deleted.
-   * @throws OperationRejectedException
-   *           If the managed object cannot be removed due to some
-   *           server-side constraint which cannot be satisfied (for
-   *           example, if it is referenced by another managed
-   *           object).
-   * @throws AuthorizationException
-   *           If the server refuses to remove 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.
-   */
-  protected abstract <C extends ConfigurationClient, S extends Configuration>
-  void deleteManagedObject(
-      ManagedObjectPath<C, S> path) throws OperationRejectedException,
-      AuthorizationException, CommunicationException;
-
-
-
-  /**
-   * Gets the default values for the specified property.
-   *
-   * @param <PD>
-   *          The type of the property.
-   * @param p
-   *          The managed object path of the current managed object.
-   * @param pd
-   *          The property definition.
-   * @param isCreate
-   *          Indicates whether the managed object has been created
-   *          yet.
-   * @return Returns the default values for the specified property.
-   * @throws DefaultBehaviorException
-   *           If the default values could not be retrieved or decoded
-   *           properly.
-   */
-  protected final <PD> Collection<PD> findDefaultValues(
-      ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd, boolean isCreate)
-      throws DefaultBehaviorException {
-    DefaultValueFinder<PD> v = new DefaultValueFinder<PD>(p, isCreate);
-    return v.find(p, pd);
-  }
-
-
-
-  /**
-   * Gets the management context associated with this driver.
-   *
-   * @return Returns the management context associated with this
-   *         driver.
-   */
-  protected abstract ManagementContext getManagementContext();
-
-
-
-  /**
-   * Validate that a relation definition belongs to the managed object
-   * referenced by the provided path.
-   *
-   * @param path
-   *          The parent managed object path.
-   * @param rd
-   *          The relation definition.
-   * @throws IllegalArgumentException
-   *           If the relation definition does not belong to the
-   *           managed object definition.
-   */
-  protected final void validateRelationDefinition(ManagedObjectPath<?, ?> path,
-      RelationDefinition<?, ?> rd) throws IllegalArgumentException {
-    AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition();
-    RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName());
-    if (tmp != rd) {
-      throw new IllegalArgumentException("The relation " + rd.getName()
-          + " is not associated with a " + d.getName());
-    }
-  }
-
-
-
-  // Remove a managed object, first ensuring that the parent exists,
-  // then ensuring that the child exists, before ensuring that any
-  // constraints are satisfied.
-  private <C extends ConfigurationClient, S extends Configuration>
-  boolean doDeleteManagedObject(
-      ManagedObjectPath<C, S> path) throws ManagedObjectNotFoundException,
-      OperationRejectedException, AuthorizationException,
-      CommunicationException {
-    // First make sure that the parent exists.
-    if (!managedObjectExists(path.parent())) {
-      throw new ManagedObjectNotFoundException();
-    }
-
-    // Make sure that the targeted managed object exists.
-    if (!managedObjectExists(path)) {
-      return false;
-    }
-
-    // The targeted managed object is guaranteed to exist, so enforce
-    // any constraints.
-    AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition();
-    List<Message> messages = new LinkedList<Message>();
-    boolean isAcceptable = true;
-
-    for (Constraint constraint : d.getAllConstraints()) {
-      for (ClientConstraintHandler handler : constraint
-          .getClientConstraintHandlers()) {
-        ManagementContext context = getManagementContext();
-        if (!handler.isDeleteAcceptable(context, path, messages)) {
-          isAcceptable = false;
+        /**
+         * {@inheritDoc}
+         */
+        public Collection<T> visitAlias(AliasDefaultBehaviorProvider<T> d, Void p) {
+            return Collections.emptySet();
         }
-      }
-      if (!isAcceptable) {
-        break;
-      }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Collection<T> visitDefined(DefinedDefaultBehaviorProvider<T> d, Void p) {
+            Collection<String> stringValues = d.getDefaultValues();
+            List<T> values = new ArrayList<T>(stringValues.size());
+
+            for (String stringValue : stringValues) {
+                try {
+                    values.add(nextProperty.decodeValue(stringValue));
+                } catch (IllegalPropertyValueStringException e) {
+                    exception = new DefaultBehaviorException(nextProperty, e);
+                    break;
+                }
+            }
+
+            return values;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Collection<T> visitRelativeInherited(RelativeInheritedDefaultBehaviorProvider<T> d, Void p) {
+            try {
+                return getInheritedProperty(d.getManagedObjectPath(nextPath), d.getManagedObjectDefinition(),
+                        d.getPropertyName());
+            } catch (DefaultBehaviorException e) {
+                exception = e;
+                return Collections.emptySet();
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Collection<T> visitUndefined(UndefinedDefaultBehaviorProvider<T> d, Void p) {
+            return Collections.emptySet();
+        }
+
+        // Find the default values for the next path/property.
+        private Collection<T> find(ManagedObjectPath<?, ?> p, PropertyDefinition<T> pd) throws DefaultBehaviorException {
+            this.nextPath = p;
+            this.nextProperty = pd;
+
+            Collection<T> values = nextProperty.getDefaultBehaviorProvider().accept(this, null);
+
+            if (exception != null) {
+                throw exception;
+            }
+
+            if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
+                throw new DefaultBehaviorException(pd, new PropertyIsSingleValuedException(pd));
+            }
+
+            return values;
+        }
+
+        // Get an inherited property value.
+        @SuppressWarnings("unchecked")
+        private Collection<T> getInheritedProperty(ManagedObjectPath target, AbstractManagedObjectDefinition<?, ?> d,
+                String propertyName) throws DefaultBehaviorException {
+            // First check that the requested type of managed object
+            // corresponds to the path.
+            AbstractManagedObjectDefinition<?, ?> supr = target.getManagedObjectDefinition();
+            if (!supr.isParentOf(d)) {
+                throw new DefaultBehaviorException(nextProperty, new DefinitionDecodingException(supr,
+                        Reason.WRONG_TYPE_INFORMATION));
+            }
+
+            // Save the current property in case of recursion.
+            PropertyDefinition<T> pd1 = nextProperty;
+
+            try {
+                // Determine the requested property definition.
+                PropertyDefinition<T> pd2;
+                try {
+                    // FIXME: we use the definition taken from the default
+                    // behavior here when we should really use the exact
+                    // definition of the component being created.
+                    PropertyDefinition<?> pdTmp = d.getPropertyDefinition(propertyName);
+                    pd2 = pd1.getClass().cast(pdTmp);
+                } catch (IllegalArgumentException e) {
+                    throw new PropertyNotFoundException(propertyName);
+                } catch (ClassCastException e) {
+                    // FIXME: would be nice to throw a better exception here.
+                    throw new PropertyNotFoundException(propertyName);
+                }
+
+                // If the path relates to the current managed object and the
+                // managed object is in the process of being created it won't
+                // exist, so we should just use the default values of the
+                // referenced property.
+                if (isCreate && firstPath.equals(target)) {
+                    // Recursively retrieve this property's default values.
+                    Collection<T> tmp = find(target, pd2);
+                    Collection<T> values = new ArrayList<T>(tmp.size());
+                    for (T value : tmp) {
+                        pd1.validateValue(value);
+                        values.add(value);
+                    }
+                    return values;
+                } else {
+                    // FIXME: issue 2481 - this is broken if the referenced
+                    // property
+                    // inherits its defaults from the newly created managed
+                    // object.
+                    return getPropertyValues(target, pd2);
+                }
+            } catch (DefaultBehaviorException e) {
+                // Wrap any errors due to recursion.
+                throw new DefaultBehaviorException(pd1, e);
+            } catch (DefinitionDecodingException e) {
+                throw new DefaultBehaviorException(pd1, e);
+            } catch (PropertyNotFoundException e) {
+                throw new DefaultBehaviorException(pd1, e);
+            } catch (AuthorizationException e) {
+                throw new DefaultBehaviorException(pd1, e);
+            } catch (ManagedObjectNotFoundException e) {
+                throw new DefaultBehaviorException(pd1, e);
+            } catch (CommunicationException e) {
+                throw new DefaultBehaviorException(pd1, e);
+            } catch (PropertyException e) {
+                throw new DefaultBehaviorException(pd1, e);
+            }
+        }
+    };
+
+    /**
+     * Creates a new abstract management context.
+     */
+    protected Driver() {
+        // No implementation required.
     }
 
-    if (!isAcceptable) {
-      throw new OperationRejectedException(OperationType.DELETE, d
-          .getUserFriendlyName(), messages);
+    /**
+     * Closes any context associated with this management context driver.
+     */
+    public void close() {
+        // do nothing by default
     }
 
-    deleteManagedObject(path);
-    return true;
-  }
+    /**
+     * Deletes the named instantiable child managed object from the named parent
+     * managed object.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the
+     *            relation definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the
+     *            relation definition refers to.
+     * @param parent
+     *            The path of the parent managed object.
+     * @param rd
+     *            The instantiable relation definition.
+     * @param name
+     *            The name of the child managed object to be removed.
+     * @return Returns <code>true</code> if the named instantiable child managed
+     *         object was found, or <code>false</code> if it was not found.
+     * @throws IllegalArgumentException
+     *             If the relation definition is not associated with the parent
+     *             managed object's definition.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @throws OperationRejectedException
+     *             If the managed object cannot be removed due to some
+     *             client-side or server-side constraint which cannot be
+     *             satisfied (for example, if it is referenced by another
+     *             managed object).
+     * @throws AuthorizationException
+     *             If the server refuses to remove 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.
+     */
+    public final <C extends ConfigurationClient, S extends Configuration> boolean deleteManagedObject(
+            ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd, String name)
+            throws IllegalArgumentException, ManagedObjectNotFoundException, OperationRejectedException,
+            AuthorizationException, CommunicationException {
+        validateRelationDefinition(parent, rd);
+        ManagedObjectPath<?, ?> child = parent.child(rd, name);
+        return doDeleteManagedObject(child);
+    }
+
+    /**
+     * Deletes the optional child managed object from the named parent managed
+     * object.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the
+     *            relation definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the
+     *            relation definition refers to.
+     * @param parent
+     *            The path of the parent managed object.
+     * @param rd
+     *            The optional relation definition.
+     * @return Returns <code>true</code> if the optional child managed object
+     *         was found, or <code>false</code> if it was not found.
+     * @throws IllegalArgumentException
+     *             If the relation definition is not associated with the parent
+     *             managed object's definition.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @throws OperationRejectedException
+     *             If the managed object cannot be removed due to some
+     *             client-side or server-side constraint which cannot be
+     *             satisfied (for example, if it is referenced by another
+     *             managed object).
+     * @throws AuthorizationException
+     *             If the server refuses to remove 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.
+     */
+    public final <C extends ConfigurationClient, S extends Configuration> boolean deleteManagedObject(
+            ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd) throws IllegalArgumentException,
+            ManagedObjectNotFoundException, OperationRejectedException, AuthorizationException, CommunicationException {
+        validateRelationDefinition(parent, rd);
+        ManagedObjectPath<?, ?> child = parent.child(rd);
+        return doDeleteManagedObject(child);
+    }
+
+    /**
+     * Deletes the named instantiable child managed object from the named parent
+     * managed object.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the
+     *            relation definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the
+     *            relation definition refers to.
+     * @param parent
+     *            The path of the parent managed object.
+     * @param rd
+     *            The instantiable relation definition.
+     * @param name
+     *            The name of the child managed object to be removed.
+     * @return Returns <code>true</code> if the named instantiable child managed
+     *         object was found, or <code>false</code> if it was not found.
+     * @throws IllegalArgumentException
+     *             If the relation definition is not associated with the parent
+     *             managed object's definition.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @throws OperationRejectedException
+     *             If the managed object cannot be removed due to some
+     *             client-side or server-side constraint which cannot be
+     *             satisfied (for example, if it is referenced by another
+     *             managed object).
+     * @throws AuthorizationException
+     *             If the server refuses to remove 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.
+     */
+    public final <C extends ConfigurationClient, S extends Configuration> boolean deleteManagedObject(
+            ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd, String name)
+            throws IllegalArgumentException, ManagedObjectNotFoundException, OperationRejectedException,
+            AuthorizationException, CommunicationException {
+        validateRelationDefinition(parent, rd);
+        ManagedObjectPath<?, ?> child = parent.child(rd, name);
+        return doDeleteManagedObject(child);
+    }
+
+    /**
+     * Gets the named managed object. The path is guaranteed to be non-empty, so
+     * implementations do not need to worry about handling this special case.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the path
+     *            definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the path
+     *            definition refers to.
+     * @param path
+     *            The non-empty path of the managed object.
+     * @return Returns the named managed object.
+     * @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 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.
+     */
+    public abstract <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getManagedObject(
+            ManagedObjectPath<C, S> path) throws DefinitionDecodingException, ManagedObjectDecodingException,
+            ManagedObjectNotFoundException, AuthorizationException, CommunicationException;
+
+    /**
+     * Gets the effective values of a property in the named managed object.
+     * <p>
+     * Implementations MUST NOT not use
+     * {@link #getManagedObject(ManagedObjectPath)} to read the referenced
+     * managed object in its entirety. Specifically, implementations MUST only
+     * attempt to resolve the default values for the requested property and its
+     * dependencies (if it uses inherited defaults). This is to avoid infinite
+     * recursion where a managed object contains a property which inherits
+     * default values from another property in the same managed object.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the path
+     *            definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the path
+     *            definition refers to.
+     * @param <PD>
+     *            The type of the property to be retrieved.
+     * @param path
+     *            The path of the managed object containing the property.
+     * @param pd
+     *            The property to be retrieved.
+     * @return Returns the property's effective values, or an empty set if there
+     *         are no values defined.
+     * @throws IllegalArgumentException
+     *             If the property definition is not associated with the
+     *             referenced managed object's definition.
+     * @throws DefinitionDecodingException
+     *             If the managed object was found but its type could not be
+     *             determined.
+     * @throws PropertyException
+     *             If the managed object was found but the requested property
+     *             could not be decoded.
+     * @throws ManagedObjectNotFoundException
+     *             If the requested managed object could not be found on the
+     *             server.
+     * @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.
+     */
+    public abstract <C extends ConfigurationClient, S extends Configuration, PD> SortedSet<PD> getPropertyValues(
+            ManagedObjectPath<C, S> path, PropertyDefinition<PD> pd) throws IllegalArgumentException,
+            DefinitionDecodingException, AuthorizationException, ManagedObjectNotFoundException,
+            CommunicationException, PropertyException;
+
+    /**
+     * Gets the root configuration managed object associated with this
+     * management context driver.
+     *
+     * @return Returns the root configuration managed object associated with
+     *         this management context driver.
+     */
+    public abstract ManagedObject<RootCfgClient> getRootConfigurationManagedObject();
+
+    /**
+     * Lists the child managed objects of the named parent managed object which
+     * are a sub-type of the specified managed object definition.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the
+     *            relation definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the
+     *            relation definition refers to.
+     * @param parent
+     *            The path of the parent managed object.
+     * @param rd
+     *            The instantiable relation definition.
+     * @param d
+     *            The managed object definition.
+     * @return Returns the names of the child managed objects which are a
+     *         sub-type of the specified managed object definition.
+     * @throws IllegalArgumentException
+     *             If the relation definition is not associated with the parent
+     *             managed object's definition.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @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.
+     */
+    public abstract <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects(
+            ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
+            AbstractManagedObjectDefinition<? extends C, ? extends S> d) throws IllegalArgumentException,
+            ManagedObjectNotFoundException, AuthorizationException, CommunicationException;
+
+    /**
+     * Lists the child managed objects of the named parent managed object which
+     * are a sub-type of the specified managed object definition.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the
+     *            relation definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the
+     *            relation definition refers to.
+     * @param parent
+     *            The path of the parent managed object.
+     * @param rd
+     *            The set relation definition.
+     * @param d
+     *            The managed object definition.
+     * @return Returns the names of the child managed objects which are a
+     *         sub-type of the specified managed object definition.
+     * @throws IllegalArgumentException
+     *             If the relation definition is not associated with the parent
+     *             managed object's definition.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @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.
+     */
+    public abstract <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects(
+            ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd,
+            AbstractManagedObjectDefinition<? extends C, ? extends S> d) throws IllegalArgumentException,
+            ManagedObjectNotFoundException, AuthorizationException, CommunicationException;
+
+    /**
+     * Determines whether or not the named managed object exists.
+     * <p>
+     * Implementations should always return <code>true</code> when the provided
+     * path is empty.
+     *
+     * @param path
+     *            The path of the named managed object.
+     * @return Returns <code>true</code> if the named managed object exists,
+     *         <code>false</code> otherwise.
+     * @throws ManagedObjectNotFoundException
+     *             If the parent managed object could not be found.
+     * @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.
+     */
+    public abstract boolean managedObjectExists(ManagedObjectPath<?, ?> path) throws ManagedObjectNotFoundException,
+            AuthorizationException, CommunicationException;
+
+    /**
+     * Deletes the named managed object.
+     * <p>
+     * Implementations do not need check whether the named managed object
+     * exists, nor do they need to enforce client constraints.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that the
+     *            relation definition refers to.
+     * @param <S>
+     *            The type of server managed object configuration that the
+     *            relation definition refers to.
+     * @param path
+     *            The path of the managed object to be deleted.
+     * @throws OperationRejectedException
+     *             If the managed object cannot be removed due to some
+     *             server-side constraint which cannot be satisfied (for
+     *             example, if it is referenced by another managed object).
+     * @throws AuthorizationException
+     *             If the server refuses to remove 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.
+     */
+    protected abstract <C extends ConfigurationClient, S extends Configuration> void deleteManagedObject(
+            ManagedObjectPath<C, S> path) throws OperationRejectedException, AuthorizationException,
+            CommunicationException;
+
+    /**
+     * Gets the default values for the specified property.
+     *
+     * @param <PD>
+     *            The type of the property.
+     * @param p
+     *            The managed object path of the current managed object.
+     * @param pd
+     *            The property definition.
+     * @param isCreate
+     *            Indicates whether the managed object has been created yet.
+     * @return Returns the default values for the specified property.
+     * @throws DefaultBehaviorException
+     *             If the default values could not be retrieved or decoded
+     *             properly.
+     */
+    protected final <PD> Collection<PD> findDefaultValues(ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd,
+            boolean isCreate) throws DefaultBehaviorException {
+        DefaultValueFinder<PD> v = new DefaultValueFinder<PD>(p, isCreate);
+        return v.find(p, pd);
+    }
+
+    /**
+     * Gets the management context associated with this driver.
+     *
+     * @return Returns the management context associated with this driver.
+     */
+    protected abstract ManagementContext getManagementContext();
+
+    /**
+     * Validate that a relation definition belongs to the managed object
+     * referenced by the provided path.
+     *
+     * @param path
+     *            The parent managed object path.
+     * @param rd
+     *            The relation definition.
+     * @throws IllegalArgumentException
+     *             If the relation definition does not belong to the managed
+     *             object definition.
+     */
+    protected final void validateRelationDefinition(ManagedObjectPath<?, ?> path, RelationDefinition<?, ?> rd)
+            throws IllegalArgumentException {
+        AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition();
+        RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName());
+        if (tmp != rd) {
+            throw new IllegalArgumentException("The relation " + rd.getName() + " is not associated with a "
+                    + d.getName());
+        }
+    }
+
+    // Remove a managed object, first ensuring that the parent exists,
+    // then ensuring that the child exists, before ensuring that any
+    // constraints are satisfied.
+    private <C extends ConfigurationClient, S extends Configuration> boolean doDeleteManagedObject(
+            ManagedObjectPath<C, S> path) throws ManagedObjectNotFoundException, OperationRejectedException,
+            AuthorizationException, CommunicationException {
+        // First make sure that the parent exists.
+        if (!managedObjectExists(path.parent())) {
+            throw new ManagedObjectNotFoundException();
+        }
+
+        // Make sure that the targeted managed object exists.
+        if (!managedObjectExists(path)) {
+            return false;
+        }
+
+        // The targeted managed object is guaranteed to exist, so enforce
+        // any constraints.
+        AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition();
+        List<LocalizableMessage> messages = new LinkedList<LocalizableMessage>();
+        boolean isAcceptable = true;
+
+        for (Constraint constraint : d.getAllConstraints()) {
+            for (ClientConstraintHandler handler : constraint.getClientConstraintHandlers()) {
+                ManagementContext context = getManagementContext();
+                if (!handler.isDeleteAcceptable(context, path, messages)) {
+                    isAcceptable = false;
+                }
+            }
+            if (!isAcceptable) {
+                break;
+            }
+        }
+
+        if (!isAcceptable) {
+            throw new OperationRejectedException(OperationType.DELETE, d.getUserFriendlyName(), messages);
+        }
+
+        deleteManagedObject(path);
+        return true;
+    }
 
 }

--
Gitblit v1.10.0