From c2d0d212b510d8e82b9b123b4d06a80b835c8cd4 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Fri, 06 Dec 2013 16:52:01 +0000
Subject: [PATCH] OpenDJ 3 : config framework

---
 opendj-admin/src/main/resources/com/forgerock/opendj/ldap/extension.properties             | 1016 ++++++++++
 opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectPath.java                  | 2375 ++++++++++-------------
 opendj-admin/src/main/java/org/opends/server/admin/ACIPropertyDefinition.java              |    1 
 opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/AciException.java    |   78 
 opendj-admin/src/main/resources/stylesheets/catalog.xml                                    |    5 
 opendj-admin/src/main/java/org/opends/server/admin/server/ConfigAddListenerAdaptor.java    |    3 
 opendj-admin/pom.xml                                                                       |   29 
 opendj-admin/src/main/java/org/opends/server/admin/AggregationPropertyDefinition.java      |   37 
 opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/Aci.java             |   12 
 opendj-admin/src/main/java/org/opends/server/admin/Reference.java                          |  342 +-
 opendj-admin/src/main/java/org/opends/server/config/ConfigurationRepository.java           |   47 
 opendj-admin/src/main/java/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java |    4 
 opendj-admin/src/main/java/org/opends/server/config/ConfigEntry.java                       |   15 
 opendj-admin/src/main/java/org/opends/server/admin/DefaultBehaviorException.java           |    2 
 opendj-admin/src/main/resources/com/forgerock/opendj/ldap/admin.properties                 |    7 
 opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagedObject.java         |   29 
 opendj-admin/src/main/java/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java  |  485 ++--
 opendj-admin/src/main/java/org/opends/server/admin/ClassLoaderProvider.java                | 1336 ++++++-------
 opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagementContext.java     |  229 -
 opendj-admin/src/main/resources/stylesheets/admin.xsd                                      |    2 
 20 files changed, 3,369 insertions(+), 2,685 deletions(-)

diff --git a/opendj-admin/pom.xml b/opendj-admin/pom.xml
index 7ac4e87..af9dd40 100644
--- a/opendj-admin/pom.xml
+++ b/opendj-admin/pom.xml
@@ -56,12 +56,12 @@
       com.sun.security.auth*;resolution:=optional,
       *
     </opendj.osgi.import>
-    <xmlDefinitionsBaseDir>src/main/resources/definitions</xmlDefinitionsBaseDir>
+    <xmlDefinitionsBaseDir>${basedir}/src/main/resources/definitions</xmlDefinitionsBaseDir>
     <xmlDefinitionsDir>${xmlDefinitionsBaseDir}/org/forgerock/opendj/admin</xmlDefinitionsDir>
     <adminPackage>org/forgerock/opendj/admin</adminPackage>
     <generatedSourcesDir>${project.build.directory}/generated-sources/admin/${adminPackage}</generatedSourcesDir>
-    <xslDir>src/main/resources/stylesheets</xslDir>
-    
+    <xslDir>${basedir}/src/main/resources/stylesheets</xslDir>
+
     <!-- properties used to generate DynamicConstant class -->
     <serverProductName>OpenDJ</serverProductName>
     <serverShortProductName>OpenDJ</serverShortProductName>
@@ -87,6 +87,7 @@
               <messageFiles>
                 <messageFile>com/forgerock/opendj/ldap/admin.properties</messageFile>
                 <messageFile>com/forgerock/opendj/ldap/config.properties</messageFile>
+                <messageFile>com/forgerock/opendj/ldap/extension.properties</messageFile>
                 <messageFile>com/forgerock/opendj/ldap/protocol.properties</messageFile>
               </messageFiles>
             </configuration>
@@ -99,8 +100,28 @@
         <artifactId>xml-maven-plugin</artifactId>
         <version>1.0</version>
         <executions>
+          <!-- Validate core components XML definition files -->
+          <execution>
+            <id>validate-core-components</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>validate</goal>
+            </goals>
+            <configuration>
+              <validationSets>
+                <validationSet>
+                  <dir>${xmlDefinitionsDir}</dir>
+                  <systemId>${xslDir}/admin.xsd</systemId>
+                </validationSet>
+              </validationSets>
+              <catalogs>
+                <catalog>${xslDir}/catalog.xml</catalog>
+              </catalogs>
+            </configuration>
+          </execution>
           <execution>
             <id>generate-core-components</id>
+            <phase>generate-sources</phase>
             <goals>
               <goal>transform</goal>
             </goals>
@@ -427,8 +448,6 @@
         </executions>
       </plugin>
     </plugins>
-    <pluginManagement>
-    </pluginManagement>
   </build>
   <reporting>
     <plugins>
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/ACIPropertyDefinition.java b/opendj-admin/src/main/java/org/opends/server/admin/ACIPropertyDefinition.java
index 75b597c..c9d3d05 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/ACIPropertyDefinition.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/ACIPropertyDefinition.java
@@ -30,6 +30,7 @@
 import static com.forgerock.opendj.util.Validator.*;
 
 import org.opends.server.authorization.dseecompat.Aci;
+import org.opends.server.authorization.dseecompat.AciException;
 import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.DN;
 
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/AggregationPropertyDefinition.java b/opendj-admin/src/main/java/org/opends/server/admin/AggregationPropertyDefinition.java
index 33d3c7b..651b95e 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/AggregationPropertyDefinition.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/AggregationPropertyDefinition.java
@@ -26,6 +26,10 @@
  */
 package org.opends.server.admin;
 
+import static com.forgerock.opendj.ldap.AdminMessages.*;
+import static com.forgerock.opendj.util.StaticUtils.*;
+import static com.forgerock.opendj.util.Validator.*;
+
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
@@ -53,7 +57,11 @@
 import org.opends.server.admin.server.ServerManagementContext;
 import org.opends.server.config.ConfigException;
 import org.opends.server.types.ConfigChangeResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.slf4j.LocalizedLogger;
+import org.forgerock.opendj.admin.meta.RootCfgDefn;
 import org.forgerock.opendj.ldap.DN;
 import org.forgerock.opendj.ldap.ResultCode;
 
@@ -260,13 +268,13 @@
                 }
             } catch (ConfigException e) {
                 // The condition could not be evaluated.
-                if (debugEnabled()) {
-                    TRACER.debugCaught(DebugLogLevel.ERROR, e);
-                }
-
-                LocalizableMessage message = ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION.get(mo.getManagedObjectDefinition()
-                        .getUserFriendlyName(), String.valueOf(mo.getDN()), StaticUtils.getExceptionLocalizableMessage(e));
-                ErrorLogger.logError(message);
+                debugLogger.trace("Unable to perform post add", e);
+                LocalizableMessage message = ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION.get(mo
+                        .getManagedObjectDefinition().getUserFriendlyName(), String.valueOf(mo.getDN()),
+                        getExceptionMessage(e));
+                LocalizedLogger logger = LocalizedLogger
+                        .getLocalizedLogger(ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION.resourceName());
+                logger.error(message);
                 unacceptableReasons.add(message);
                 return false;
             }
@@ -504,12 +512,14 @@
                 try {
                     ref = context.getManagedObject(path);
                 } catch (DefinitionDecodingException e) {
-                    LocalizableMessage msg = ERR_CLIENT_REFINT_TARGET_INVALID.get(ufn, name, getName(), e.getLocalizableMessageObject());
+                    LocalizableMessage msg = ERR_CLIENT_REFINT_TARGET_INVALID.get(ufn, name, getName(),
+                            e.getMessageObject());
                     unacceptableReasons.add(msg);
                     isAcceptable = false;
                     continue;
                 } catch (ManagedObjectDecodingException e) {
-                    LocalizableMessage msg = ERR_CLIENT_REFINT_TARGET_INVALID.get(ufn, name, getName(), e.getLocalizableMessageObject());
+                    LocalizableMessage msg = ERR_CLIENT_REFINT_TARGET_INVALID.get(ufn, name, getName(),
+                            e.getMessageObject());
                     unacceptableReasons.add(msg);
                     isAcceptable = false;
                     continue;
@@ -688,11 +698,6 @@
     }
 
     /**
-     * The tracer object for the debug logger.
-     */
-    private static final DebugTracer TRACER = getTracer();
-
-    /**
      * Creates an aggregation property definition builder.
      *
      * @param <C>
@@ -713,6 +718,8 @@
         return new Builder<C, S>(d, propertyName);
     }
 
+    private static final Logger debugLogger = LoggerFactory.getLogger(AggregationPropertyDefinition.class);
+
     // The active server-side referential integrity change listeners
     // associated with this property.
     private final Map<DN, List<ReferentialIntegrityChangeListener>> changeListeners = new HashMap<DN, List<ReferentialIntegrityChangeListener>>();
@@ -902,7 +909,7 @@
         ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance();
         String property = "property." + getName() + ".syntax.aggregation.constraint-synopsis";
         try {
-            return resource.getLocalizableMessage(getManagedObjectDefinition(), property, locale);
+            return resource.getMessage(getManagedObjectDefinition(), property, locale);
         } catch (MissingResourceException e) {
             return null;
         }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/ClassLoaderProvider.java b/opendj-admin/src/main/java/org/opends/server/admin/ClassLoaderProvider.java
index ca8e856..ec8166e 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/ClassLoaderProvider.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/ClassLoaderProvider.java
@@ -27,8 +27,9 @@
  */
 package org.opends.server.admin;
 
-
-
+import static com.forgerock.opendj.ldap.AdminMessages.*;
+import static com.forgerock.opendj.ldap.ExtensionMessages.*;
+import static com.forgerock.opendj.util.StaticUtils.*;
 import static com.forgerock.opendj.util.Validator.*;
 
 import java.io.ByteArrayOutputStream;
@@ -54,767 +55,664 @@
 import java.util.jar.Manifest;
 
 import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.forgerock.opendj.admin.meta.RootCfgDefn;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.InitializationException;
+import org.opends.server.util.DynamicConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.forgerock.opendj.ldap.AdminMessages;
 
 /**
- * Manages the class loader which should be used for loading
- * configuration definition classes and associated extensions.
+ * Manages the class loader which should be used for loading configuration
+ * definition classes and associated extensions.
  * <p>
- * For extensions which define their own extended configuration
- * definitions, the class loader will make sure that the configuration
- * definition classes are loaded and initialized.
+ * For extensions which define their own extended configuration definitions, the
+ * class loader will make sure that the configuration definition classes are
+ * loaded and initialized.
  * <p>
  * Initially the class loader provider is disabled, and calls to the
- * {@link #getClassLoader()} will return the system default class
- * loader.
+ * {@link #getClassLoader()} will return the system default class loader.
  * <p>
- * Applications <b>MUST NOT</b> maintain persistent references to the
- * class loader as it can change at run-time.
+ * Applications <b>MUST NOT</b> maintain persistent references to the class
+ * loader as it can change at run-time.
  */
 public final class ClassLoaderProvider {
 
-  /**
-   * The tracer object for the debug logger.
-   */
-  private static final DebugTracer TRACER = getTracer();
-
-  /**
-   * Private URLClassLoader implementation. This is only required so
-   * that we can provide access to the addURL method.
-   */
-  private static final class MyURLClassLoader extends URLClassLoader {
+    private static final LocalizedLogger adminLogger = LocalizedLogger.getLocalizedLogger(AdminMessages.resourceName());
+    private static final Logger debugLogger = LoggerFactory.getLogger(ClassLoaderProvider.class);
 
     /**
-     * Create a class loader with the default parent class loader.
+     * Private URLClassLoader implementation. This is only required so that we
+     * can provide access to the addURL method.
      */
-    public MyURLClassLoader() {
-      super(new URL[0]);
-    }
-
-
-
-    /**
-     * Create a class loader with the provided parent class loader.
-     *
-     * @param parent
-     *          The parent class loader.
-     */
-    public MyURLClassLoader(ClassLoader parent) {
-      super(new URL[0], parent);
-    }
-
-
-
-    /**
-     * Add a Jar file to this class loader.
-     *
-     * @param jarFile
-     *          The name of the Jar file.
-     * @throws MalformedURLException
-     *           If a protocol handler for the URL could not be found,
-     *           or if some other error occurred while constructing
-     *           the URL.
-     * @throws SecurityException
-     *           If a required system property value cannot be
-     *           accessed.
-     */
-    public void addJarFile(File jarFile) throws SecurityException,
-        MalformedURLException {
-      addURL(jarFile.toURI().toURL());
-    }
-
-  }
-
-  // The name of the manifest file listing the core configuration
-  // definition classes.
-  private static final String CORE_MANIFEST = "core.manifest";
-
-  // The name of the manifest file listing a extension's configuration
-  // definition classes.
-  private static final String EXTENSION_MANIFEST = "extension.manifest";
-
-  // The name of the lib directory.
-  private static final String LIB_DIR = "lib";
-
-  // The name of the extensions directory.
-  private static final String EXTENSIONS_DIR = "extensions";
-
-  // The singleton instance.
-  private static final ClassLoaderProvider INSTANCE = new ClassLoaderProvider();
-
-  // Attribute name in jar's MANIFEST corresponding to the revision number.
-  private static final String REVISION_NUMBER = "Revision-Number";
-
-  // The attribute names for build information is name, version and revision
-  // number
-  private static final String[] BUILD_INFORMATION_ATTRIBUTE_NAMES =
-                 new String[]{Attributes.Name.EXTENSION_NAME.toString(),
-                              Attributes.Name.IMPLEMENTATION_VERSION.toString(),
-                              REVISION_NUMBER};
-
-
-  /**
-   * Get the single application wide class loader provider instance.
-   *
-   * @return Returns the single application wide class loader provider
-   *         instance.
-   */
-  public static ClassLoaderProvider getInstance() {
-    return INSTANCE;
-  }
-
-  // Set of registered Jar files.
-  private Set<File> jarFiles = new HashSet<File>();
-
-  // Underlying class loader used to load classes and resources (null
-  // if disabled).
-  //
-  // We contain a reference to the URLClassLoader rather than
-  // sub-class it so that it is possible to replace the loader at
-  // run-time. For example, when removing or replacing extension Jar
-  // files (the URLClassLoader only supports adding new
-  // URLs, not removal).
-  private MyURLClassLoader loader = null;
-
-
-
-  // Private constructor.
-  private ClassLoaderProvider() {
-    // No implementation required.
-  }
-
-
-
-  /**
-   * Add the named extensions to this class loader provider.
-   *
-   * @param extensions
-   *          The names of the extensions to be loaded. The names
-   *          should not contain any path elements and must be located
-   *          within the extensions folder.
-   * @throws InitializationException
-   *           If one of the extensions could not be loaded and
-   *           initialized.
-   * @throws IllegalStateException
-   *           If this class loader provider is disabled.
-   * @throws IllegalArgumentException
-   *           If one of the extension names was not a single relative
-   *           path name element or was an absolute path.
-   */
-  public synchronized void addExtension(String... extensions)
-      throws InitializationException, IllegalStateException,
-      IllegalArgumentException {
-    ensureNotNull(extensions);
-
-    if (loader == null) {
-      throw new IllegalStateException(
-          "Class loader provider is disabled.");
-    }
-
-    File libPath = new File(DirectoryServer.getInstanceRoot(), LIB_DIR);
-    File extensionsPath = new File(libPath, EXTENSIONS_DIR);
-
-    ArrayList<File> files = new ArrayList<File>(extensions.length);
-    for (String extension : extensions) {
-      File file = new File(extensionsPath, extension);
-
-      // For security reasons we need to make sure that the file name
-      // passed in did not contain any path elements and names a file
-      // in the extensions folder.
-
-      // Can handle potential null parent.
-      if (!extensionsPath.equals(file.getParentFile())) {
-        throw new IllegalArgumentException("Illegal file name: "
-            + extension);
-      }
-
-      // The file is valid.
-      files.add(file);
-    }
-
-    // Add the extensions.
-    addExtension(files.toArray(new File[files.size()]));
-  }
-
-
-
-  /**
-   * Disable this class loader provider and removed any registered
-   * extensions.
-   *
-   * @throws IllegalStateException
-   *           If this class loader provider is already disabled.
-   */
-  public synchronized void disable() throws IllegalStateException {
-    if (loader == null) {
-      throw new IllegalStateException(
-          "Class loader provider already disabled.");
-    }
-    loader = null;
-    jarFiles = new HashSet<File>();
-  }
-
-
-
-  /**
-   * Enable this class loader provider using the application's
-   * class loader as the parent class loader.
-   *
-   * @throws InitializationException
-   *           If the class loader provider could not initialize
-   *           successfully.
-   * @throws IllegalStateException
-   *           If this class loader provider is already enabled.
-   */
-  public synchronized void enable() throws InitializationException,
-      IllegalStateException {
-    enable(RootCfgDefn.class.getClassLoader());
-  }
-
-
-
-  /**
-   * Enable this class loader provider using the provided parent class
-   * loader.
-   *
-   * @param parent
-   *          The parent class loader.
-   * @throws InitializationException
-   *           If the class loader provider could not initialize
-   *           successfully.
-   * @throws IllegalStateException
-   *           If this class loader provider is already enabled.
-   */
-  public synchronized void enable(ClassLoader parent)
-      throws InitializationException, IllegalStateException {
-    if (loader != null) {
-      throw new IllegalStateException(
-          "Class loader provider already enabled.");
-    }
-
-    if (parent != null) {
-      loader = new MyURLClassLoader(parent);
-    } else {
-      loader = new MyURLClassLoader();
-    }
-
-    // Forcefully load all configuration definition classes in
-    // OpenDS.jar.
-    initializeCoreComponents();
-
-    // Put extensions jars into the class loader and load all
-    // configuration definition classes in that they contain.
-    // First load the extension from the install directory, then
-    // from the instance directory.
-    File libDir ;
-    File installExtensionsPath ;
-    File instanceExtensionsPath ;
-
-
-    // load install dir extension
-    libDir = new File(DirectoryServer.getServerRoot(), LIB_DIR);
-    try
-    {
-      installExtensionsPath =
-        new File(libDir, EXTENSIONS_DIR).getCanonicalFile();
-    }
-    catch (Exception e)
-    {
-      installExtensionsPath = new File(libDir, EXTENSIONS_DIR);
-    }
-    initializeAllExtensions(installExtensionsPath);
-
-    // load instance dir extension
-    libDir = new File(DirectoryServer.getInstanceRoot(),LIB_DIR);
-    try
-    {
-      instanceExtensionsPath =
-        new File(libDir, EXTENSIONS_DIR).getCanonicalFile();
-    }
-    catch (Exception e)
-    {
-      instanceExtensionsPath = new File(libDir, EXTENSIONS_DIR);
-    }
-    if (! installExtensionsPath.getAbsolutePath().equals(
-        instanceExtensionsPath.getAbsolutePath()))
-    {
-      initializeAllExtensions(instanceExtensionsPath);
-    }
-  }
-
-
-
-  /**
-   * Gets the class loader which should be used for loading classes
-   * and resources. When this class loader provider is disabled, the
-   * system default class loader will be returned by default.
-   * <p>
-   * Applications <b>MUST NOT</b> maintain persistent references to
-   * the class loader as it can change at run-time.
-   *
-   * @return Returns the class loader which should be used for loading
-   *         classes and resources.
-   */
-  public synchronized ClassLoader getClassLoader() {
-    if (loader != null) {
-      return loader;
-    } else {
-      return ClassLoader.getSystemClassLoader();
-    }
-  }
-
-
-
-  /**
-   * Indicates whether this class loader provider is enabled.
-   *
-   * @return Returns <code>true</code> if this class loader provider
-   *         is enabled.
-   */
-  public synchronized boolean isEnabled() {
-    return loader != null;
-  }
-
-
-
-  /**
-   * Add the named extensions to this class loader.
-   *
-   * @param extensions
-   *          The names of the extensions to be loaded.
-   * @throws InitializationException
-   *           If one of the extensions could not be loaded and
-   *           initialized.
-   */
-  private synchronized void addExtension(File... extensions)
-      throws InitializationException {
-    // First add the Jar files to the class loader.
-    List<JarFile> jars = new LinkedList<JarFile>();
-    for (File extension : extensions) {
-      if (jarFiles.contains(extension)) {
-        // Skip this file as it is already loaded.
-        continue;
-      }
-
-      // Attempt to load it.
-      jars.add(loadJarFile(extension));
-
-      // Register the Jar file with the class loader.
-      try {
-        loader.addJarFile(extension);
-      } catch (Exception e) {
-        if (debugEnabled()) {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
-        }
-
-        LocalizableMessage message = ERR_ADMIN_CANNOT_OPEN_JAR_FILE.
-            get(extension.getName(), extension.getParent(),
-                stackTraceToSingleLineString(e));
-        throw new InitializationException(message);
-      }
-      jarFiles.add(extension);
-    }
-
-    // Now forcefully load the configuration definition classes.
-    for (JarFile jar : jars) {
-      initializeExtension(jar);
-    }
-  }
-
-
-
-  /**
-   * Prints out all information about extensions.
-   *
-   * @return a String instance representing all information about extensions;
-   *         <code>null</code> if there is no information available.
-   */
-  public String printExtensionInformation() {
-    File extensionsPath =
-            new File(new StringBuilder(DirectoryServer.getServerRoot()).
-                                append(File.separator).
-                                append(LIB_DIR).
-                                append(File.separator).
-                                append(EXTENSIONS_DIR).
-                                toString());
-
-    if (!extensionsPath.exists() || !extensionsPath.isDirectory()) {
-      // no extensions' directory
-      return null;
-    }
-
-    File[] extensions = extensionsPath.listFiles(new FileFilter(){
-      public boolean accept(File pathname) {
-        // only files with names ending with ".jar"
-        return pathname.isFile() && pathname.getName().endsWith(".jar");
-      }
-    });
-
-    if ( extensions.length == 0 ) {
-      return null;
-    }
-
-    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-    PrintStream ps = new PrintStream(baos);
-    // prints:
-    // --
-    //            Name                 Build number         Revision number
-    ps.printf("--%s           %-20s %-20s %-20s%s",
-              EOL,
-              "Name",
-              "Build number",
-              "Revision number",
-              EOL);
-
-    for(File extension : extensions) {
-      // retrieve MANIFEST entry and display name, build number and revision
-      // number
-      try {
-        JarFile jarFile = new JarFile(extension);
-        JarEntry entry = jarFile.getJarEntry("admin/" + EXTENSION_MANIFEST);
-        if (entry == null)
-        {
-          continue;
-        }
-
-        String[] information = getBuildInformation(jarFile);
-
-        ps.append("Extension: ");
-        boolean addBlank = false;
-        for(String name : information) {
-          if ( addBlank ) {
-            ps.append(addBlank ? " " : ""); // add blank if not first append
-          } else {
-            addBlank = true;
-          }
-
-          ps.printf("%-20s", name);
-        }
-        ps.append(EOL);
-      } catch(Exception e) {
-        // ignore extra information for this extension
-      }
-    }
-
-    return baos.toString();
-  }
-
-
-
-  /**
-   * Returns a String array with the following information :
-   * <br>index 0: the name of the extension.
-   * <br>index 1: the build number of the extension.
-   * <br>index 2: the revision number of the extension.
-   *
-   * @param extension the jar file of the extension
-   * @return a String array containing the name, the build number and the
-   *         revision number of the extension given in argument
-   * @throws java.io.IOException thrown if the jar file has been closed.
-   */
-  private String[] getBuildInformation(JarFile extension) throws IOException {
-    String[] result = new String[3];
-
-    // retrieve MANIFEST entry and display name, version and revision
-    Manifest manifest = extension.getManifest();
-
-    if ( manifest != null ) {
-      Attributes attributes = manifest.getMainAttributes();
-
-      int index = 0;
-      for(String name : BUILD_INFORMATION_ATTRIBUTE_NAMES) {
-        String value = attributes.getValue(name);
-        if ( value == null ) {
-          value = "<unknown>";
-        }
-        result[index++] = value;
-      }
-    }
-
-    return result;
-  }
-
-
-
-  /**
-   * Put extensions jars into the class loader and load all
-   * configuration definition classes in that they contain.
-   * @param extensionsPath Indicates where extensions are located.
-   *
-   * @throws InitializationException
-   *           If the extensions folder could not be accessed or if a
-   *           extension jar file could not be accessed or if one of
-   *           the configuration definition classes could not be
-   *           initialized.
-   */
-  private void initializeAllExtensions(File extensionsPath)
-      throws InitializationException {
-
-    try {
-      if (!extensionsPath.exists()) {
-        // The extensions directory does not exist. This is not a
-        // critical problem.
-        LocalizableMessage message = ERR_ADMIN_NO_EXTENSIONS_DIR.get(
-                String.valueOf(extensionsPath));
-        logError(message);
-        return;
-      }
-
-      if (!extensionsPath.isDirectory()) {
-        // The extensions directory is not a directory. This is more
-        // critical.
-        LocalizableMessage message =
-            ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY.get(
-                    String.valueOf(extensionsPath));
-        throw new InitializationException(message);
-      }
-
-      // Get each extension file name.
-      FileFilter filter = new FileFilter() {
+    private static final class MyURLClassLoader extends URLClassLoader {
 
         /**
-         * Must be a Jar file.
+         * Create a class loader with the default parent class loader.
          */
-        public boolean accept(File pathname) {
-          if (!pathname.isFile()) {
-            return false;
-          }
-
-          String name = pathname.getName();
-          return name.endsWith(".jar");
+        public MyURLClassLoader() {
+            super(new URL[0]);
         }
 
-      };
-
-      // Add and initialize the extensions.
-      addExtension(extensionsPath.listFiles(filter));
-    } catch (InitializationException e) {
-      if (debugEnabled()) {
-        TRACER.debugCaught(DebugLogLevel.ERROR, e);
-      }
-      throw e;
-    } catch (Exception e) {
-      if (debugEnabled()) {
-        TRACER.debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      LocalizableMessage message = ERR_ADMIN_EXTENSIONS_CANNOT_LIST_FILES.get(
-          String.valueOf(extensionsPath), stackTraceToSingleLineString(e));
-      throw new InitializationException(message, e);
-    }
-  }
-
-
-
-  /**
-   * Make sure all core configuration definitions are loaded.
-   *
-   * @throws InitializationException
-   *           If the core manifest file could not be read or if one
-   *           of the configuration definition classes could not be
-   *           initialized.
-   */
-  private void initializeCoreComponents()
-      throws InitializationException {
-    InputStream is = RootCfgDefn.class.getResourceAsStream("/admin/"
-        + CORE_MANIFEST);
-
-    if (is == null) {
-      LocalizableMessage message = ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST.get(CORE_MANIFEST);
-      throw new InitializationException(message);
-    }
-
-    try {
-      loadDefinitionClasses(is);
-    } catch (InitializationException e) {
-      if (debugEnabled()) {
-        TRACER.debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      LocalizableMessage message = ERR_CLASS_LOADER_CANNOT_LOAD_CORE.get(CORE_MANIFEST,
-          stackTraceToSingleLineString(e));
-      throw new InitializationException(message);
-    }
-  }
-
-
-
-  /**
-   * Make sure all the configuration definition classes in a extension
-   * are loaded.
-   *
-   * @param jarFile
-   *          The extension's Jar file.
-   * @throws InitializationException
-   *           If the extension jar file could not be accessed or if
-   *           one of the configuration definition classes could not
-   *           be initialized.
-   */
-  private void initializeExtension(JarFile jarFile)
-      throws InitializationException {
-    JarEntry entry = jarFile.getJarEntry("admin/"
-        + EXTENSION_MANIFEST);
-    if (entry != null) {
-      InputStream is;
-      try {
-        is = jarFile.getInputStream(entry);
-      } catch (Exception e) {
-        if (debugEnabled()) {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
+        /**
+         * Create a class loader with the provided parent class loader.
+         *
+         * @param parent
+         *            The parent class loader.
+         */
+        public MyURLClassLoader(ClassLoader parent) {
+            super(new URL[0], parent);
         }
 
-        LocalizableMessage message = ERR_ADMIN_CANNOT_READ_EXTENSION_MANIFEST.get(
-            EXTENSION_MANIFEST, jarFile.getName(),
-            stackTraceToSingleLineString(e));
-        throw new InitializationException(message);
-      }
-
-      try {
-        loadDefinitionClasses(is);
-      } catch (InitializationException e) {
-        if (debugEnabled()) {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
+        /**
+         * Add a Jar file to this class loader.
+         *
+         * @param jarFile
+         *            The name of the Jar file.
+         * @throws MalformedURLException
+         *             If a protocol handler for the URL could not be found, or
+         *             if some other error occurred while constructing the URL.
+         * @throws SecurityException
+         *             If a required system property value cannot be accessed.
+         */
+        public void addJarFile(File jarFile) throws SecurityException, MalformedURLException {
+            addURL(jarFile.toURI().toURL());
         }
 
-        LocalizableMessage message = ERR_CLASS_LOADER_CANNOT_LOAD_EXTENSION.get(jarFile
-            .getName(), EXTENSION_MANIFEST, stackTraceToSingleLineString(e));
-        throw new InitializationException(message);
-      }
-      try {
-        // Log build information of extensions in the error log
-        String[] information = getBuildInformation(jarFile);
-        logError(
-          NOTE_LOG_EXTENSION_INFORMATION.
-            get(jarFile.getName(),
-                information[1],
-                information[2]));
-      } catch(Exception e) {
-        // Do not log information for that extension
-      }
     }
-  }
 
+    // The name of the manifest file listing the core configuration
+    // definition classes.
+    private static final String CORE_MANIFEST = "core.manifest";
 
+    // The name of the manifest file listing a extension's configuration
+    // definition classes.
+    private static final String EXTENSION_MANIFEST = "extension.manifest";
 
-  /**
-   * Forcefully load configuration definition classes named in a
-   * manifest file.
-   *
-   * @param is
-   *          The manifest file input stream.
-   * @throws InitializationException
-   *           If the definition classes could not be loaded and
-   *           initialized.
-   */
-  private void loadDefinitionClasses(InputStream is)
-      throws InitializationException {
-    BufferedReader reader = new BufferedReader(new InputStreamReader(
-        is));
-    List<AbstractManagedObjectDefinition<?, ?>> definitions =
-      new LinkedList<AbstractManagedObjectDefinition<?,?>>();
-    while (true) {
-      String className;
-      try {
-        className = reader.readLine();
-      } catch (IOException e) {
-        LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_READ_MANIFEST_FILE.get(String
-            .valueOf(e.getLocalizableMessage()));
-        throw new InitializationException(msg, e);
-      }
+    // The name of the lib directory.
+    private static final String LIB_DIR = "lib";
 
-      // Break out when the end of the manifest is reached.
-      if (className == null) {
-        break;
-      }
+    // The name of the extensions directory.
+    private static final String EXTENSIONS_DIR = "extensions";
 
-      // Skip blank lines.
-      className = className.trim();
-      if (className.length() == 0) {
-        continue;
-      }
+    // The singleton instance.
+    private static final ClassLoaderProvider INSTANCE = new ClassLoaderProvider();
 
-      // Skip lines beginning with #.
-      if (className.startsWith("#")) {
-        continue;
-      }
+    // Attribute name in jar's MANIFEST corresponding to the revision number.
+    private static final String REVISION_NUMBER = "Revision-Number";
 
-      TRACER.debugLocalizableMessage(DebugLogLevel.INFO, "Loading class " + className);
+    // The attribute names for build information is name, version and revision
+    // number
+    private static final String[] BUILD_INFORMATION_ATTRIBUTE_NAMES = new String[] {
+            Attributes.Name.EXTENSION_NAME.toString(), Attributes.Name.IMPLEMENTATION_VERSION.toString(),
+            REVISION_NUMBER };
 
-      // Load the class and get an instance of it if it is a definition.
-      Class<?> theClass;
-      try {
-        theClass = Class.forName(className, true, loader);
-      } catch (Exception e) {
-        LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_LOAD_CLASS.get(className, String
-            .valueOf(e.getLocalizableMessage()));
-        throw new InitializationException(msg, e);
-      }
-      if (AbstractManagedObjectDefinition.class.isAssignableFrom(theClass)) {
-        // We need to instantiate it using its getInstance() static method.
-        Method method;
+    /**
+     * Get the single application wide class loader provider instance.
+     *
+     * @return Returns the single application wide class loader provider
+     *         instance.
+     */
+    public static ClassLoaderProvider getInstance() {
+        return INSTANCE;
+    }
+
+    // Set of registered Jar files.
+    private Set<File> jarFiles = new HashSet<File>();
+
+    // Underlying class loader used to load classes and resources (null
+    // if disabled).
+    //
+    // We contain a reference to the URLClassLoader rather than
+    // sub-class it so that it is possible to replace the loader at
+    // run-time. For example, when removing or replacing extension Jar
+    // files (the URLClassLoader only supports adding new
+    // URLs, not removal).
+    private MyURLClassLoader loader = null;
+
+    // Private constructor.
+    private ClassLoaderProvider() {
+        // No implementation required.
+    }
+
+    /**
+     * Add the named extensions to this class loader provider.
+     *
+     * @param extensions
+     *            The names of the extensions to be loaded. The names should not
+     *            contain any path elements and must be located within the
+     *            extensions folder.
+     * @throws InitializationException
+     *             If one of the extensions could not be loaded and initialized.
+     * @throws IllegalStateException
+     *             If this class loader provider is disabled.
+     * @throws IllegalArgumentException
+     *             If one of the extension names was not a single relative path
+     *             name element or was an absolute path.
+     */
+    public synchronized void addExtension(String... extensions) throws InitializationException, IllegalStateException,
+            IllegalArgumentException {
+        ensureNotNull(extensions);
+
+        if (loader == null) {
+            throw new IllegalStateException("Class loader provider is disabled.");
+        }
+
+        File libPath = new File(DirectoryServer.getInstanceRoot(), LIB_DIR);
+        File extensionsPath = new File(libPath, EXTENSIONS_DIR);
+
+        ArrayList<File> files = new ArrayList<File>(extensions.length);
+        for (String extension : extensions) {
+            File file = new File(extensionsPath, extension);
+
+            // For security reasons we need to make sure that the file name
+            // passed in did not contain any path elements and names a file
+            // in the extensions folder.
+
+            // Can handle potential null parent.
+            if (!extensionsPath.equals(file.getParentFile())) {
+                throw new IllegalArgumentException("Illegal file name: " + extension);
+            }
+
+            // The file is valid.
+            files.add(file);
+        }
+
+        // Add the extensions.
+        addExtension(files.toArray(new File[files.size()]));
+    }
+
+    /**
+     * Disable this class loader provider and removed any registered extensions.
+     *
+     * @throws IllegalStateException
+     *             If this class loader provider is already disabled.
+     */
+    public synchronized void disable() throws IllegalStateException {
+        if (loader == null) {
+            throw new IllegalStateException("Class loader provider already disabled.");
+        }
+        loader = null;
+        jarFiles = new HashSet<File>();
+    }
+
+    /**
+     * Enable this class loader provider using the application's class loader as
+     * the parent class loader.
+     *
+     * @throws InitializationException
+     *             If the class loader provider could not initialize
+     *             successfully.
+     * @throws IllegalStateException
+     *             If this class loader provider is already enabled.
+     */
+    public synchronized void enable() throws InitializationException, IllegalStateException {
+        enable(RootCfgDefn.class.getClassLoader());
+    }
+
+    /**
+     * Enable this class loader provider using the provided parent class loader.
+     *
+     * @param parent
+     *            The parent class loader.
+     * @throws InitializationException
+     *             If the class loader provider could not initialize
+     *             successfully.
+     * @throws IllegalStateException
+     *             If this class loader provider is already enabled.
+     */
+    public synchronized void enable(ClassLoader parent) throws InitializationException, IllegalStateException {
+        if (loader != null) {
+            throw new IllegalStateException("Class loader provider already enabled.");
+        }
+
+        if (parent != null) {
+            loader = new MyURLClassLoader(parent);
+        } else {
+            loader = new MyURLClassLoader();
+        }
+
+        // Forcefully load all configuration definition classes in
+        // OpenDS.jar.
+        initializeCoreComponents();
+
+        // Put extensions jars into the class loader and load all
+        // configuration definition classes in that they contain.
+        // First load the extension from the install directory, then
+        // from the instance directory.
+        File libDir;
+        File installExtensionsPath;
+        File instanceExtensionsPath;
+
+        // load install dir extension
+        libDir = new File(DirectoryServer.getServerRoot(), LIB_DIR);
         try {
-          method = theClass.getMethod("getInstance");
+            installExtensionsPath = new File(libDir, EXTENSIONS_DIR).getCanonicalFile();
         } catch (Exception e) {
-          LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_FIND_GET_INSTANCE_METHOD.get(
-              className, String.valueOf(e.getLocalizableMessage()));
-          throw new InitializationException(msg, e);
+            installExtensionsPath = new File(libDir, EXTENSIONS_DIR);
         }
+        initializeAllExtensions(installExtensionsPath);
 
-        // Get the definition instance.
-        AbstractManagedObjectDefinition<?, ?> d;
+        // load instance dir extension
+        libDir = new File(DirectoryServer.getInstanceRoot(), LIB_DIR);
         try {
-          d = (AbstractManagedObjectDefinition<?, ?>) method.invoke(null);
+            instanceExtensionsPath = new File(libDir, EXTENSIONS_DIR).getCanonicalFile();
         } catch (Exception e) {
-          LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_INVOKE_GET_INSTANCE_METHOD.get(
-              className, String.valueOf(e.getLocalizableMessage()));
-          throw new InitializationException(msg, e);
+            instanceExtensionsPath = new File(libDir, EXTENSIONS_DIR);
         }
-        definitions.add(d);
-      }
+        if (!installExtensionsPath.getAbsolutePath().equals(instanceExtensionsPath.getAbsolutePath())) {
+            initializeAllExtensions(instanceExtensionsPath);
+        }
     }
 
-    // Initialize any definitions that were loaded.
-    for (AbstractManagedObjectDefinition<?, ?> d : definitions) {
-      try {
-        d.initialize();
-      } catch (Exception e) {
-        LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_INITIALIZE_DEFN.get(d.getName(),
-            d.getClass().getName(), String.valueOf(e.getLocalizableMessage()));
-        throw new InitializationException(msg, e);
-      }
+    /**
+     * Gets the class loader which should be used for loading classes and
+     * resources. When this class loader provider is disabled, the system
+     * default class loader will be returned by default.
+     * <p>
+     * Applications <b>MUST NOT</b> maintain persistent references to the class
+     * loader as it can change at run-time.
+     *
+     * @return Returns the class loader which should be used for loading classes
+     *         and resources.
+     */
+    public synchronized ClassLoader getClassLoader() {
+        if (loader != null) {
+            return loader;
+        } else {
+            return ClassLoader.getSystemClassLoader();
+        }
     }
-  }
 
-
-
-  /**
-   * Load the named Jar file.
-   *
-   * @param jar
-   *          The name of the Jar file to load.
-   * @return Returns the loaded Jar file.
-   * @throws InitializationException
-   *           If the Jar file could not be loaded.
-   */
-  private JarFile loadJarFile(File jar)
-      throws InitializationException {
-    JarFile jarFile;
-
-    try {
-      // Load the extension jar file.
-      jarFile = new JarFile(jar);
-    } catch (Exception e) {
-      if (debugEnabled()) {
-        TRACER.debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      LocalizableMessage message = ERR_ADMIN_CANNOT_OPEN_JAR_FILE.get(
-          jar.getName(), jar.getParent(), stackTraceToSingleLineString(e));
-      throw new InitializationException(message);
+    /**
+     * Indicates whether this class loader provider is enabled.
+     *
+     * @return Returns <code>true</code> if this class loader provider is
+     *         enabled.
+     */
+    public synchronized boolean isEnabled() {
+        return loader != null;
     }
-    return jarFile;
-  }
+
+    /**
+     * Add the named extensions to this class loader.
+     *
+     * @param extensions
+     *            The names of the extensions to be loaded.
+     * @throws InitializationException
+     *             If one of the extensions could not be loaded and initialized.
+     */
+    private synchronized void addExtension(File... extensions) throws InitializationException {
+        // First add the Jar files to the class loader.
+        List<JarFile> jars = new LinkedList<JarFile>();
+        for (File extension : extensions) {
+            if (jarFiles.contains(extension)) {
+                // Skip this file as it is already loaded.
+                continue;
+            }
+
+            // Attempt to load it.
+            jars.add(loadJarFile(extension));
+
+            // Register the Jar file with the class loader.
+            try {
+                loader.addJarFile(extension);
+            } catch (Exception e) {
+                debugLogger.trace("Unable to register the jar file with the class loader", e);
+                LocalizableMessage message = ERR_ADMIN_CANNOT_OPEN_JAR_FILE.get(extension.getName(),
+                        extension.getParent(), stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD));
+                throw new InitializationException(message);
+            }
+            jarFiles.add(extension);
+        }
+
+        // Now forcefully load the configuration definition classes.
+        for (JarFile jar : jars) {
+            initializeExtension(jar);
+        }
+    }
+
+    /**
+     * Prints out all information about extensions.
+     *
+     * @return a String instance representing all information about extensions;
+     *         <code>null</code> if there is no information available.
+     */
+    public String printExtensionInformation() {
+        File extensionsPath = new File(new StringBuilder(DirectoryServer.getServerRoot()).append(File.separator)
+                .append(LIB_DIR).append(File.separator).append(EXTENSIONS_DIR).toString());
+
+        if (!extensionsPath.exists() || !extensionsPath.isDirectory()) {
+            // no extensions' directory
+            return null;
+        }
+
+        File[] extensions = extensionsPath.listFiles(new FileFilter() {
+            public boolean accept(File pathname) {
+                // only files with names ending with ".jar"
+                return pathname.isFile() && pathname.getName().endsWith(".jar");
+            }
+        });
+
+        if (extensions.length == 0) {
+            return null;
+        }
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream(baos);
+        // prints:
+        // --
+        // Name Build number Revision number
+        ps.printf("--%s           %-20s %-20s %-20s%s", EOL, "Name", "Build number", "Revision number", EOL);
+
+        for (File extension : extensions) {
+            // retrieve MANIFEST entry and display name, build number and
+            // revision
+            // number
+            try {
+                JarFile jarFile = new JarFile(extension);
+                JarEntry entry = jarFile.getJarEntry("admin/" + EXTENSION_MANIFEST);
+                if (entry == null) {
+                    continue;
+                }
+
+                String[] information = getBuildInformation(jarFile);
+
+                ps.append("Extension: ");
+                boolean addBlank = false;
+                for (String name : information) {
+                    if (addBlank) {
+                        ps.append(addBlank ? " " : ""); // add blank if not
+                                                        // first append
+                    } else {
+                        addBlank = true;
+                    }
+
+                    ps.printf("%-20s", name);
+                }
+                ps.append(EOL);
+            } catch (Exception e) {
+                // ignore extra information for this extension
+            }
+        }
+
+        return baos.toString();
+    }
+
+    /**
+     * Returns a String array with the following information : <br>
+     * index 0: the name of the extension. <br>
+     * index 1: the build number of the extension. <br>
+     * index 2: the revision number of the extension.
+     *
+     * @param extension
+     *            the jar file of the extension
+     * @return a String array containing the name, the build number and the
+     *         revision number of the extension given in argument
+     * @throws java.io.IOException
+     *             thrown if the jar file has been closed.
+     */
+    private String[] getBuildInformation(JarFile extension) throws IOException {
+        String[] result = new String[3];
+
+        // retrieve MANIFEST entry and display name, version and revision
+        Manifest manifest = extension.getManifest();
+
+        if (manifest != null) {
+            Attributes attributes = manifest.getMainAttributes();
+
+            int index = 0;
+            for (String name : BUILD_INFORMATION_ATTRIBUTE_NAMES) {
+                String value = attributes.getValue(name);
+                if (value == null) {
+                    value = "<unknown>";
+                }
+                result[index++] = value;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Put extensions jars into the class loader and load all configuration
+     * definition classes in that they contain.
+     *
+     * @param extensionsPath
+     *            Indicates where extensions are located.
+     * @throws InitializationException
+     *             If the extensions folder could not be accessed or if a
+     *             extension jar file could not be accessed or if one of the
+     *             configuration definition classes could not be initialized.
+     */
+    private void initializeAllExtensions(File extensionsPath) throws InitializationException {
+
+        try {
+            if (!extensionsPath.exists()) {
+                // The extensions directory does not exist. This is not a
+                // critical problem.
+                adminLogger.error(ERR_ADMIN_NO_EXTENSIONS_DIR, String.valueOf(extensionsPath));
+                return;
+            }
+
+            if (!extensionsPath.isDirectory()) {
+                // The extensions directory is not a directory. This is more
+                // critical.
+                LocalizableMessage message = ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY.get(String.valueOf(extensionsPath));
+                throw new InitializationException(message);
+            }
+
+            // Get each extension file name.
+            FileFilter filter = new FileFilter() {
+
+                /**
+                 * Must be a Jar file.
+                 */
+                public boolean accept(File pathname) {
+                    if (!pathname.isFile()) {
+                        return false;
+                    }
+
+                    String name = pathname.getName();
+                    return name.endsWith(".jar");
+                }
+
+            };
+
+            // Add and initialize the extensions.
+            addExtension(extensionsPath.listFiles(filter));
+        } catch (InitializationException e) {
+            debugLogger.trace("Unable to initialize all extensions", e);
+            throw e;
+        } catch (Exception e) {
+            debugLogger.trace("Unable to initialize all extensions", e);
+            LocalizableMessage message = ERR_ADMIN_EXTENSIONS_CANNOT_LIST_FILES.get(String.valueOf(extensionsPath),
+                    stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD));
+            throw new InitializationException(message, e);
+        }
+    }
+
+    /**
+     * Make sure all core configuration definitions are loaded.
+     *
+     * @throws InitializationException
+     *             If the core manifest file could not be read or if one of the
+     *             configuration definition classes could not be initialized.
+     */
+    private void initializeCoreComponents() throws InitializationException {
+        InputStream is = RootCfgDefn.class.getResourceAsStream("/admin/" + CORE_MANIFEST);
+
+        if (is == null) {
+            LocalizableMessage message = ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST.get(CORE_MANIFEST);
+            throw new InitializationException(message);
+        }
+
+        try {
+            loadDefinitionClasses(is);
+        } catch (InitializationException e) {
+            debugLogger.trace("Unable to initialize core components", e);
+            LocalizableMessage message = ERR_CLASS_LOADER_CANNOT_LOAD_CORE.get(CORE_MANIFEST,
+                    stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD));
+            throw new InitializationException(message);
+        }
+    }
+
+    /**
+     * Make sure all the configuration definition classes in a extension are
+     * loaded.
+     *
+     * @param jarFile
+     *            The extension's Jar file.
+     * @throws InitializationException
+     *             If the extension jar file could not be accessed or if one of
+     *             the configuration definition classes could not be
+     *             initialized.
+     */
+    private void initializeExtension(JarFile jarFile) throws InitializationException {
+        JarEntry entry = jarFile.getJarEntry("admin/" + EXTENSION_MANIFEST);
+        if (entry != null) {
+            InputStream is;
+            try {
+                is = jarFile.getInputStream(entry);
+            } catch (Exception e) {
+                debugLogger.trace("Unable to get input stream from jar", e);
+                LocalizableMessage message = ERR_ADMIN_CANNOT_READ_EXTENSION_MANIFEST.get(EXTENSION_MANIFEST,
+                        jarFile.getName(), stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD));
+                throw new InitializationException(message);
+            }
+
+            try {
+                loadDefinitionClasses(is);
+            } catch (InitializationException e) {
+                debugLogger.trace("Unable to load classes from input stream", e);
+                LocalizableMessage message = ERR_CLASS_LOADER_CANNOT_LOAD_EXTENSION.get(jarFile.getName(),
+                        EXTENSION_MANIFEST, stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD));
+                throw new InitializationException(message);
+            }
+            try {
+                // Log build information of extensions in the error log
+                String[] information = getBuildInformation(jarFile);
+                LocalizableMessage message = NOTE_LOG_EXTENSION_INFORMATION.get(jarFile.getName(), information[1],
+                        information[2]);
+                LocalizedLogger.getLocalizedLogger(message.resourceName()).error(message);
+            } catch (Exception e) {
+                // Do not log information for that extension
+            }
+        }
+    }
+
+    /**
+     * Forcefully load configuration definition classes named in a manifest
+     * file.
+     *
+     * @param is
+     *            The manifest file input stream.
+     * @throws InitializationException
+     *             If the definition classes could not be loaded and
+     *             initialized.
+     */
+    private void loadDefinitionClasses(InputStream is) throws InitializationException {
+        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+        List<AbstractManagedObjectDefinition<?, ?>> definitions = new LinkedList<AbstractManagedObjectDefinition<?, ?>>();
+        while (true) {
+            String className;
+            try {
+                className = reader.readLine();
+            } catch (IOException e) {
+                LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_READ_MANIFEST_FILE.get(String.valueOf(e.getMessage()));
+                throw new InitializationException(msg, e);
+            }
+
+            // Break out when the end of the manifest is reached.
+            if (className == null) {
+                break;
+            }
+
+            // Skip blank lines.
+            className = className.trim();
+            if (className.length() == 0) {
+                continue;
+            }
+
+            // Skip lines beginning with #.
+            if (className.startsWith("#")) {
+                continue;
+            }
+
+            debugLogger.trace("Loading class " + className);
+
+            // Load the class and get an instance of it if it is a definition.
+            Class<?> theClass;
+            try {
+                theClass = Class.forName(className, true, loader);
+            } catch (Exception e) {
+                LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_LOAD_CLASS.get(className,
+                        String.valueOf(e.getMessage()));
+                throw new InitializationException(msg, e);
+            }
+            if (AbstractManagedObjectDefinition.class.isAssignableFrom(theClass)) {
+                // We need to instantiate it using its getInstance() static
+                // method.
+                Method method;
+                try {
+                    method = theClass.getMethod("getInstance");
+                } catch (Exception e) {
+                    LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_FIND_GET_INSTANCE_METHOD.get(className,
+                            String.valueOf(e.getMessage()));
+                    throw new InitializationException(msg, e);
+                }
+
+                // Get the definition instance.
+                AbstractManagedObjectDefinition<?, ?> d;
+                try {
+                    d = (AbstractManagedObjectDefinition<?, ?>) method.invoke(null);
+                } catch (Exception e) {
+                    LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_INVOKE_GET_INSTANCE_METHOD.get(className,
+                            String.valueOf(e.getMessage()));
+                    throw new InitializationException(msg, e);
+                }
+                definitions.add(d);
+            }
+        }
+
+        // Initialize any definitions that were loaded.
+        for (AbstractManagedObjectDefinition<?, ?> d : definitions) {
+            try {
+                d.initialize();
+            } catch (Exception e) {
+                LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_INITIALIZE_DEFN.get(d.getName(), d.getClass()
+                        .getName(), String.valueOf(e.getMessage()));
+                throw new InitializationException(msg, e);
+            }
+        }
+    }
+
+    /**
+     * Load the named Jar file.
+     *
+     * @param jar
+     *            The name of the Jar file to load.
+     * @return Returns the loaded Jar file.
+     * @throws InitializationException
+     *             If the Jar file could not be loaded.
+     */
+    private JarFile loadJarFile(File jar) throws InitializationException {
+        JarFile jarFile;
+
+        try {
+            // Load the extension jar file.
+            jarFile = new JarFile(jar);
+        } catch (Exception e) {
+            debugLogger.trace("Unable to load jar file: " + jar, e);
+
+            LocalizableMessage message = ERR_ADMIN_CANNOT_OPEN_JAR_FILE.get(jar.getName(), jar.getParent(),
+                    stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD));
+            throw new InitializationException(message);
+        }
+        return jarFile;
+    }
 
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/DefaultBehaviorException.java b/opendj-admin/src/main/java/org/opends/server/admin/DefaultBehaviorException.java
index 6e26c89..707c965 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/DefaultBehaviorException.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/DefaultBehaviorException.java
@@ -27,6 +27,8 @@
 
 package org.opends.server.admin;
 
+import static com.forgerock.opendj.ldap.AdminMessages.*;
+
 /**
  * This exception is thrown when a property's default values cannot be
  * determined. This can occur in the following situations:
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectPath.java b/opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectPath.java
index a38d04a..c6c7144 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectPath.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectPath.java
@@ -28,8 +28,6 @@
 
 package org.opends.server.admin;
 
-
-
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
@@ -43,67 +41,58 @@
 import org.forgerock.opendj.ldap.RDN;
 import org.forgerock.opendj.ldap.schema.AttributeType;
 import org.opends.server.core.DirectoryServer;
-import org.opends.server.types.DirectoryException;
-
 
 /**
- * A path which can be used to determine the location of a managed
- * object instance.
+ * A path which can be used to determine the location of a managed object
+ * instance.
  * <p>
- * A path is made up of zero or more elements each of which represents
- * a managed object. Managed objects are arranged hierarchically with
- * the root configuration being the top-most managed object. Elements
- * are ordered such that the root configuration managed object is the
- * first element and subsequent elements representing managed objects
- * further down the hierarchy.
+ * A path is made up of zero or more elements each of which represents a managed
+ * object. Managed objects are arranged hierarchically with the root
+ * configuration being the top-most managed object. Elements are ordered such
+ * that the root configuration managed object is the first element and
+ * subsequent elements representing managed objects further down the hierarchy.
  * <p>
  * A path can be encoded into a string representation using the
- * {@link #toString()} and {@link #toString(StringBuilder)} methods.
- * Conversely, this string representation can be parsed using the
- * {@link #valueOf(String)} method.
+ * {@link #toString()} and {@link #toString(StringBuilder)} methods. Conversely,
+ * this string representation can be parsed using the {@link #valueOf(String)}
+ * method.
  * <p>
- * The string representation of a managed object path is similar in
- * principle to a UNIX file-system path and is defined as follows:
+ * The string representation of a managed object path is similar in principle to
+ * a UNIX file-system path and is defined as follows:
  * <ul>
  * <li>the root element is represented by the string <code>/</code>
- * <li>subordinate elements are arranged in big-endian order
- * separated by a forward slash <code>/</code> character
- * <li>an element representing a managed object associated with a
- * one-to-one (singleton) or one-to-zero-or-one (optional) relation
- * has the form <code>relation=</code><i>relation</i>
- * <code>[+type=</code><i>definition</i><code>]</code>, where
- * <i>relation</i> is the name of the relation and <i>definition</i>
- * is the name of the referenced managed object's definition if
- * required (usually this is implied by the relation itself)
- * <li>an element representing a managed object associated with a
- * one-to-many (instantiable) relation has the form
- * <code>relation=</code><i>relation</i><code>[+type=</code>
- * <i>definition</i><code>]</code><code>+name=</code><i>name</i>,
- * where <i>relation</i> is the name of the relation and
- * <i>definition</i> is the name of the referenced managed object's
- * definition if required (usually this is implied by the relation
- * itself), and <i>name</i> is the name of the managed object
- * instance
- * <li>an element representing a managed object associated with a
- * one-to-many (set) relation has the form
- * <code>relation=</code><i>relation</i><code>[+type=</code>
- * <i>definition</i><code>]</code>,
- * where <i>relation</i> is the name of the relation and
- * <i>definition</i> is the name of the referenced managed object's
- * definition.
+ * <li>subordinate elements are arranged in big-endian order separated by a
+ * forward slash <code>/</code> character
+ * <li>an element representing a managed object associated with a one-to-one
+ * (singleton) or one-to-zero-or-one (optional) relation has the form
+ * <code>relation=</code><i>relation</i> <code>[+type=</code><i>definition</i>
+ * <code>]</code>, where <i>relation</i> is the name of the relation and
+ * <i>definition</i> is the name of the referenced managed object's definition
+ * if required (usually this is implied by the relation itself)
+ * <li>an element representing a managed object associated with a one-to-many
+ * (instantiable) relation has the form <code>relation=</code><i>relation</i>
+ * <code>[+type=</code> <i>definition</i><code>]</code><code>+name=</code>
+ * <i>name</i>, where <i>relation</i> is the name of the relation and
+ * <i>definition</i> is the name of the referenced managed object's definition
+ * if required (usually this is implied by the relation itself), and <i>name</i>
+ * is the name of the managed object instance
+ * <li>an element representing a managed object associated with a one-to-many
+ * (set) relation has the form <code>relation=</code><i>relation</i>
+ * <code>[+type=</code> <i>definition</i><code>]</code>, where <i>relation</i>
+ * is the name of the relation and <i>definition</i> is the name of the
+ * referenced managed object's definition.
  * </ul>
- * The following path string representation identifies a connection
- * handler instance (note that the <code>type</code> is not
- * specified indicating that the path identifies a connection handler
- * called <i>my handler</i> which can be any type of connection
- * handler):
+ * The following path string representation identifies a connection handler
+ * instance (note that the <code>type</code> is not specified indicating that
+ * the path identifies a connection handler called <i>my handler</i> which can
+ * be any type of connection handler):
  *
  * <pre>
  *  /relation=connection-handler+name=my handler
  * </pre>
  *
- * If the identified connection handler must be an LDAP connection
- * handler then the above path should include the <code>type</code>:
+ * If the identified connection handler must be an LDAP connection handler then
+ * the above path should include the <code>type</code>:
  *
  * <pre>
  *  /relation=connection-handler+type=ldap-connection-handler+name=my handler
@@ -116,1333 +105,1079 @@
  * </pre>
  *
  * @param <C>
- *          The type of client managed object configuration that this
- *          path references.
+ *            The type of client managed object configuration that this path
+ *            references.
  * @param <S>
- *          The type of server managed object configuration that this
- *          path references.
+ *            The type of server managed object configuration that this path
+ *            references.
  */
-public final class ManagedObjectPath<C extends ConfigurationClient,
-    S extends Configuration> {
-
-  /**
-   * A serialize which is used to generate the toDN representation.
-   */
-  private static final class DNSerializer implements
-      ManagedObjectPathSerializer {
-
-    // The current DN.
-    private DN dn;
-
-    // The LDAP profile.
-    private final LDAPProfile profile;
-
-
-
-    // Create a new DN builder.
-    private DNSerializer() {
-      this.dn = DN.rootDN();
-      this.profile = LDAPProfile.getInstance();
-    }
-
-
+public final class ManagedObjectPath<C extends ConfigurationClient, S extends Configuration> {
 
     /**
-     * {@inheritDoc}
+     * A serialize which is used to generate the toDN representation.
      */
-    public <C extends ConfigurationClient, S extends Configuration>
-    void appendManagedObjectPathElement(
-        InstantiableRelationDefinition<? super C, ? super S> r,
-        AbstractManagedObjectDefinition<C, S> d, String name) {
-      // Add the RDN sequence representing the relation.
-      appendManagedObjectPathElement(r);
+    private static final class DNSerializer implements ManagedObjectPathSerializer {
 
-      // Now add the single RDN representing the named instance.
-      String type = profile.getRelationChildRDNType(r);
-      AttributeType atype = DirectoryServer.getAttributeType(
-          type.toLowerCase(), true);
-      AttributeValue avalue = AttributeValues.create(atype, name);
-      dn = dn.concat(RDN.create(atype, avalue));
+        // The current DN.
+        private DN dn;
+
+        // The LDAP profile.
+        private final LDAPProfile profile;
+
+        // Create a new DN builder.
+        private DNSerializer() {
+            this.dn = DN.rootDN();
+            this.profile = LDAPProfile.getInstance();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement(
+                InstantiableRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d,
+                String name) {
+            // Add the RDN sequence representing the relation.
+            appendManagedObjectPathElement(r);
+
+            // Now add the single RDN representing the named instance.
+            String type = profile.getRelationChildRDNType(r);
+            AttributeType attrType = DirectoryServer.getAttributeType(type.toLowerCase(), true);
+            dn = dn.child(new RDN(attrType, name));
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement(
+                SetRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) {
+            // Add the RDN sequence representing the relation.
+            appendManagedObjectPathElement(r);
+
+            // Now add the single RDN representing the instance.
+            String type = profile.getRelationChildRDNType(r);
+            AttributeType attrType = DirectoryServer.getAttributeType(type.toLowerCase(), true);
+            dn = dn.child(new RDN(attrType, d.getName()));
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement(
+                OptionalRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) {
+            // Add the RDN sequence representing the relation.
+            appendManagedObjectPathElement(r);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement(
+                SingletonRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) {
+            // Add the RDN sequence representing the relation.
+            appendManagedObjectPathElement(r);
+        }
+
+        // Appends the RDN sequence representing the provided relation.
+        private void appendManagedObjectPathElement(RelationDefinition<?, ?> r) {
+            DN localName = DN.valueOf(profile.getRelationRDNSequence(r));
+            dn = dn.child(localName);
+        }
+
+        // Gets the serialized DN value.
+        private DN toDN() {
+            return dn;
+        }
     }
 
-
-
     /**
-     * {@inheritDoc}
+     * Abstract path element.
      */
-    public <C extends ConfigurationClient, S extends Configuration>
-    void appendManagedObjectPathElement(
-        SetRelationDefinition<? super C, ? super S> r,
-        AbstractManagedObjectDefinition<C, S> d) {
-      // Add the RDN sequence representing the relation.
-      appendManagedObjectPathElement(r);
+    private static abstract class Element<C extends ConfigurationClient, S extends Configuration> {
 
-      // Now add the single RDN representing the instance.
-      String type = profile.getRelationChildRDNType(r);
-      AttributeType atype = DirectoryServer.getAttributeType(
-          type.toLowerCase(), true);
-      AttributeValue avalue = AttributeValues.create(atype, d.getName());
-      dn = dn.concat(RDN.create(atype, avalue));
+        // The type of managed object referenced by this element.
+        private final AbstractManagedObjectDefinition<C, S> definition;
+
+        /**
+         * Protected constructor.
+         *
+         * @param definition
+         *            The type of managed object referenced by this element.
+         */
+        protected Element(AbstractManagedObjectDefinition<C, S> definition) {
+            this.definition = definition;
+        }
+
+        /**
+         * Get the managed object definition associated with this element.
+         *
+         * @return Returns the managed object definition associated with this
+         *         element.
+         */
+        public final AbstractManagedObjectDefinition<C, S> getManagedObjectDefinition() {
+            return definition;
+        }
+
+        /**
+         * Get the name associated with this element if applicable.
+         *
+         * @return Returns the name associated with this element if applicable.
+         */
+        public String getName() {
+            return null;
+        }
+
+        /**
+         * Get the relation definition associated with this element.
+         *
+         * @return Returns the relation definition associated with this element.
+         */
+        public abstract RelationDefinition<? super C, ? super S> getRelationDefinition();
+
+        /**
+         * Serialize this path element using the provided serialization
+         * strategy.
+         *
+         * @param serializer
+         *            The managed object path serialization strategy.
+         */
+        public abstract void serialize(ManagedObjectPathSerializer serializer);
     }
 
-
-
     /**
-     * {@inheritDoc}
+     * A path element representing an instantiable managed object.
      */
-    public <C extends ConfigurationClient, S extends Configuration>
-    void appendManagedObjectPathElement(
-        OptionalRelationDefinition<? super C, ? super S> r,
-        AbstractManagedObjectDefinition<C, S> d) {
-      // Add the RDN sequence representing the relation.
-      appendManagedObjectPathElement(r);
+    private static final class InstantiableElement<C extends ConfigurationClient, S extends Configuration> extends
+            Element<C, S> {
+
+        // Factory method.
+        private static final <C extends ConfigurationClient, S extends Configuration> InstantiableElement<C, S> create(
+                InstantiableRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d,
+                String name) {
+            return new InstantiableElement<C, S>(r, d, name);
+        }
+
+        // The name of the managed object.
+        private final String name;
+
+        // The instantiable relation.
+        private final InstantiableRelationDefinition<? super C, ? super S> r;
+
+        // Private constructor.
+        private InstantiableElement(InstantiableRelationDefinition<? super C, ? super S> r,
+                AbstractManagedObjectDefinition<C, S> d, String name) {
+            super(d);
+            this.r = r;
+            this.name = name;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public String getName() {
+            return name;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public InstantiableRelationDefinition<? super C, ? super S> getRelationDefinition() {
+            return r;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void serialize(ManagedObjectPathSerializer serializer) {
+            serializer.appendManagedObjectPathElement(r, getManagedObjectDefinition(), name);
+        }
     }
 
-
-
     /**
-     * {@inheritDoc}
+     * A path element representing an optional managed object.
      */
-    public <C extends ConfigurationClient, S extends Configuration>
-    void appendManagedObjectPathElement(
-        SingletonRelationDefinition<? super C, ? super S> r,
-        AbstractManagedObjectDefinition<C, S> d) {
-      // Add the RDN sequence representing the relation.
-      appendManagedObjectPathElement(r);
+    private static final class OptionalElement<C extends ConfigurationClient, S extends Configuration> extends
+            Element<C, S> {
+
+        // Factory method.
+        private static final <C extends ConfigurationClient, S extends Configuration> OptionalElement<C, S> create(
+                OptionalRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) {
+            return new OptionalElement<C, S>(r, d);
+        }
+
+        // The optional relation.
+        private final OptionalRelationDefinition<? super C, ? super S> r;
+
+        // Private constructor.
+        private OptionalElement(OptionalRelationDefinition<? super C, ? super S> r,
+                AbstractManagedObjectDefinition<C, S> d) {
+            super(d);
+            this.r = r;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public OptionalRelationDefinition<? super C, ? super S> getRelationDefinition() {
+            return r;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void serialize(ManagedObjectPathSerializer serializer) {
+            serializer.appendManagedObjectPathElement(r, getManagedObjectDefinition());
+        }
     }
 
-
-
-    // Appends the RDN sequence representing the provided relation.
-    private void appendManagedObjectPathElement(RelationDefinition<?, ?> r) {
-      // Add the RDN sequence representing the relation.
-      try {
-        DN localName = DN.decode(profile.getRelationRDNSequence(r));
-        dn = dn.concat(localName);
-      } catch (DirectoryException e) {
-        throw new RuntimeException(e);
-      }
-    }
-
-
-
-    // Gets the serialized DN value.
-    private DN toDN() {
-      return dn;
-    }
-  }
-
-
-
-  /**
-   * Abstract path element.
-   */
-  private static abstract class Element<C extends ConfigurationClient,
-      S extends Configuration> {
-
-    // The type of managed object referenced by this element.
-    private final AbstractManagedObjectDefinition<C, S> definition;
-
-
-
     /**
-     * Protected constructor.
+     * A path element representing an set managed object.
+     */
+    private static final class SetElement<C extends ConfigurationClient, S extends Configuration> extends Element<C, S> {
+
+        // Factory method.
+        private static final <C extends ConfigurationClient, S extends Configuration> SetElement<C, S> create(
+                SetRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) {
+            return new SetElement<C, S>(r, d);
+        }
+
+        // The set relation.
+        private final SetRelationDefinition<? super C, ? super S> r;
+
+        // Private constructor.
+        private SetElement(SetRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) {
+            super(d);
+            this.r = r;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public SetRelationDefinition<? super C, ? super S> getRelationDefinition() {
+            return r;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void serialize(ManagedObjectPathSerializer serializer) {
+            serializer.appendManagedObjectPathElement(r, getManagedObjectDefinition());
+        }
+    }
+
+    /**
+     * A path element representing a singleton managed object.
+     */
+    private static final class SingletonElement<C extends ConfigurationClient, S extends Configuration> extends
+            Element<C, S> {
+
+        // Factory method.
+        private static final <C extends ConfigurationClient, S extends Configuration> SingletonElement<C, S> create(
+                SingletonRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) {
+            return new SingletonElement<C, S>(r, d);
+        }
+
+        // The singleton relation.
+        private final SingletonRelationDefinition<? super C, ? super S> r;
+
+        // Private constructor.
+        private SingletonElement(SingletonRelationDefinition<? super C, ? super S> r,
+                AbstractManagedObjectDefinition<C, S> d) {
+            super(d);
+            this.r = r;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public SingletonRelationDefinition<? super C, ? super S> getRelationDefinition() {
+            return r;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void serialize(ManagedObjectPathSerializer serializer) {
+            serializer.appendManagedObjectPathElement(r, getManagedObjectDefinition());
+        }
+    }
+
+    /**
+     * A serialize which is used to generate the toString representation.
+     */
+    private static final class StringSerializer implements ManagedObjectPathSerializer {
+
+        // Serialize to this string builder.
+        private final StringBuilder builder;
+
+        // Private constructor.
+        private StringSerializer(StringBuilder builder) {
+            this.builder = builder;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public <M extends ConfigurationClient, N extends Configuration> void appendManagedObjectPathElement(
+                InstantiableRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d,
+                String name) {
+            serializeElement(r, d);
+
+            // Be careful to escape any forward slashes in the name.
+            builder.append("+name=");
+            builder.append(name.replace("/", "//"));
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public <M extends ConfigurationClient, N extends Configuration> void appendManagedObjectPathElement(
+                OptionalRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d) {
+            serializeElement(r, d);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public <M extends ConfigurationClient, N extends Configuration> void appendManagedObjectPathElement(
+                SingletonRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d) {
+            serializeElement(r, d);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public <M extends ConfigurationClient, N extends Configuration> void appendManagedObjectPathElement(
+                SetRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d) {
+            serializeElement(r, d);
+        }
+
+        // Common element serialization.
+        private <M, N> void serializeElement(RelationDefinition<?, ?> r, AbstractManagedObjectDefinition<?, ?> d) {
+            // Always specify the relation name.
+            builder.append("/relation=");
+            builder.append(r.getName());
+
+            // Only specify the type if it is a sub-type of the relation's
+            // type.
+            if (r.getChildDefinition() != d) {
+                builder.append("+type=");
+                builder.append(d.getName());
+            }
+        }
+    }
+
+    // Single instance of a root path.
+    private static final ManagedObjectPath<RootCfgClient, RootCfg> EMPTY_PATH = new ManagedObjectPath<RootCfgClient, RootCfg>(
+            new LinkedList<Element<?, ?>>(), null, RootCfgDefn.getInstance());
+
+    // A regular expression used to parse path elements.
+    private static final Pattern PE_REGEXP = Pattern.compile("^\\s*relation=\\s*([^+]+)\\s*"
+            + "(\\+\\s*type=\\s*([^+]+)\\s*)?" + "(\\+\\s*name=\\s*([^+]+)\\s*)?$");
+
+    /**
+     * Creates a new managed object path representing the configuration root.
      *
-     * @param definition
-     *          The type of managed object referenced by this element.
+     * @return Returns a new managed object path representing the configuration
+     *         root.
      */
-    protected Element(AbstractManagedObjectDefinition<C, S> definition) {
-      this.definition = definition;
+    public static ManagedObjectPath<RootCfgClient, RootCfg> emptyPath() {
+        return EMPTY_PATH;
     }
 
-
-
     /**
-     * Get the managed object definition associated with this element.
+     * Returns a managed object path holding the value of the specified string.
      *
-     * @return Returns the managed object definition associated with
-     *         this element.
+     * @param s
+     *            The string to be parsed.
+     * @return Returns a managed object path holding the value of the specified
+     *         string.
+     * @throws IllegalArgumentException
+     *             If the string could not be parsed.
      */
-    public final AbstractManagedObjectDefinition<C, S>
-        getManagedObjectDefinition() {
-      return definition;
+    public static ManagedObjectPath<?, ?> valueOf(String s) throws IllegalArgumentException {
+        String ns = s.trim();
+
+        // Check for root special case.
+        if (ns.equals("/")) {
+            return EMPTY_PATH;
+        }
+
+        // Parse the elements.
+        LinkedList<Element<?, ?>> elements = new LinkedList<Element<?, ?>>();
+        Element<?, ?> lastElement = null;
+        AbstractManagedObjectDefinition<?, ?> definition = RootCfgDefn.getInstance();
+
+        if (!ns.startsWith("/")) {
+            throw new IllegalArgumentException("Invalid path \"" + ns + "\": must begin with a \"/\"");
+        }
+
+        int start = 1;
+        while (true) {
+            // Get the next path element.
+            int end;
+            for (end = start; end < ns.length(); end++) {
+                char c = ns.charAt(end);
+                if (c == '/') {
+                    if (end == (ns.length() - 1)) {
+                        throw new IllegalArgumentException("Invalid path \"" + ns
+                                + "\": must not end with a trailing \"/\"");
+                    }
+
+                    if (ns.charAt(end + 1) == '/') {
+                        // Found an escaped forward slash.
+                        end++;
+                    } else {
+                        // Found the end of this path element.
+                        break;
+                    }
+                }
+            }
+
+            // Get the next element.
+            String es = ns.substring(start, end);
+
+            Matcher m = PE_REGEXP.matcher(es);
+            if (!m.matches()) {
+                throw new IllegalArgumentException("Invalid path element \"" + es + "\" in path \"" + ns + "\"");
+            }
+
+            // Mandatory.
+            String relation = m.group(1);
+
+            // Optional.
+            String type = m.group(3);
+
+            // Mandatory if relation is instantiable.
+            String name = m.group(5);
+
+            // Get the relation definition.
+            RelationDefinition<?, ?> r;
+            try {
+                r = definition.getRelationDefinition(relation);
+            } catch (IllegalArgumentException e) {
+                throw new IllegalArgumentException("Invalid path element \"" + es + "\" in path \"" + ns
+                        + "\": unknown relation \"" + relation + "\"");
+            }
+
+            // Append the next element.
+            lastElement = createElement(r, ns, es, type, name);
+            elements.add(lastElement);
+            definition = lastElement.getManagedObjectDefinition();
+
+            // Update start to point to the beginning of the next element.
+            if (end < ns.length()) {
+                // Skip to the beginning of the next element
+                start = end + 1;
+            } else {
+                // We reached the end of the string.
+                break;
+            }
+        }
+
+        // Construct the new path.
+        return create(elements, lastElement);
     }
 
+    // Factory method required in order to allow generic wild-card
+    // construction of new paths.
+    private static <C extends ConfigurationClient, S extends Configuration> ManagedObjectPath<C, S> create(
+            LinkedList<Element<?, ?>> elements, Element<C, S> lastElement) {
+        return new ManagedObjectPath<C, S>(elements, lastElement.getRelationDefinition(),
+                lastElement.getManagedObjectDefinition());
+    }
 
+    // Decode an element.
+    private static <C extends ConfigurationClient, S extends Configuration> Element<? extends C, ? extends S> createElement(
+            RelationDefinition<C, S> r, String path, String element, String type, String name) {
+        // First determine the managed object definition.
+        AbstractManagedObjectDefinition<? extends C, ? extends S> d = null;
+
+        if (type != null) {
+            for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : r.getChildDefinition()
+                    .getAllChildren()) {
+                if (child.getName().equals(type)) {
+                    d = child;
+                    break;
+                }
+            }
+
+            if (d == null) {
+                throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path
+                        + "\": unknown sub-type \"" + type + "\"");
+            }
+        } else {
+            d = r.getChildDefinition();
+        }
+
+        if (r instanceof InstantiableRelationDefinition) {
+            InstantiableRelationDefinition<C, S> ir = (InstantiableRelationDefinition<C, S>) r;
+
+            if (name == null) {
+                throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path
+                        + "\": no instance name for instantiable relation");
+            }
+
+            return InstantiableElement.create(ir, d, name);
+        } else if (r instanceof SetRelationDefinition) {
+            SetRelationDefinition<C, S> ir = (SetRelationDefinition<C, S>) r;
+
+            if (name != null) {
+                throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path
+                        + "\": instance name specified for set relation");
+            }
+
+            return SetElement.create(ir, d);
+        } else if (r instanceof OptionalRelationDefinition) {
+            OptionalRelationDefinition<C, S> or = (OptionalRelationDefinition<C, S>) r;
+
+            if (name != null) {
+                throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path
+                        + "\": instance name specified for optional relation");
+            }
+
+            return OptionalElement.create(or, d);
+        } else if (r instanceof SingletonRelationDefinition) {
+            SingletonRelationDefinition<C, S> sr = (SingletonRelationDefinition<C, S>) r;
+
+            if (name != null) {
+                throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path
+                        + "\": instance name specified for singleton relation");
+            }
+
+            return SingletonElement.create(sr, d);
+        } else {
+            throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path
+                    + "\": unsupported relation type");
+        }
+    }
+
+    // The managed object definition in this path.
+    private final AbstractManagedObjectDefinition<C, S> d;
+
+    // The list of path elements in this path.
+    private final List<Element<?, ?>> elements;
+
+    // The last relation definition in this path.
+    private final RelationDefinition<? super C, ? super S> r;
+
+    // Private constructor.
+    private ManagedObjectPath(LinkedList<Element<?, ?>> elements, RelationDefinition<? super C, ? super S> r,
+            AbstractManagedObjectDefinition<C, S> d) {
+        this.elements = Collections.unmodifiableList(elements);
+        this.r = r;
+        this.d = d;
+    }
 
     /**
-     * Get the name associated with this element if applicable.
+     * Creates a new managed object path which has the same structure as this
+     * path except that the final path element is associated with the specified
+     * managed object definition.
      *
-     * @return Returns the name associated with this element if
-     *         applicable.
+     * @param <CC>
+     *            The type of client managed object configuration that this path
+     *            will reference.
+     * @param <SS>
+     *            The type of server managed object configuration that this path
+     *            will reference.
+     * @param nd
+     *            The new managed object definition.
+     * @return Returns a new managed object path which has the same structure as
+     *         this path except that the final path element is associated with
+     *         the specified managed object definition.
+     */
+    @SuppressWarnings("unchecked")
+    public <CC extends C, SS extends S> ManagedObjectPath<CC, SS> asSubType(AbstractManagedObjectDefinition<CC, SS> nd) {
+        if (r instanceof InstantiableRelationDefinition) {
+            InstantiableRelationDefinition<? super C, ? super S> ir = (InstantiableRelationDefinition<? super C, ? super S>) r;
+            if (elements.size() == 0) {
+                return parent().child(ir, nd, "null");
+            } else {
+                return parent().child(ir, nd, elements.get(elements.size() - 1).getName());
+            }
+        } else if (r instanceof SetRelationDefinition) {
+            SetRelationDefinition<? super C, ? super S> sr = (SetRelationDefinition<? super C, ? super S>) r;
+            return parent().child(sr, nd);
+        } else if (r instanceof OptionalRelationDefinition) {
+            OptionalRelationDefinition<? super C, ? super S> or = (OptionalRelationDefinition<? super C, ? super S>) r;
+            return parent().child(or, nd);
+        } else {
+            SingletonRelationDefinition<? super C, ? super S> sr = (SingletonRelationDefinition<? super C, ? super S>) r;
+            return parent().child(sr, nd);
+        }
+    }
+
+    /**
+     * Creates a new child managed object path beneath the provided parent path
+     * having the specified managed object definition.
+     *
+     * @param <M>
+     *            The type of client managed object configuration that the child
+     *            path references.
+     * @param <N>
+     *            The type of server managed object configuration that the child
+     *            path references.
+     * @param r
+     *            The instantiable relation referencing the child.
+     * @param d
+     *            The managed object definition associated with the child (must
+     *            be a sub-type of the relation).
+     * @param name
+     *            The relative name of the child managed object.
+     * @return Returns a new child managed object path beneath the provided
+     *         parent path.
+     * @throws IllegalArgumentException
+     *             If the provided name is empty or blank.
+     */
+    public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child(
+            InstantiableRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d, String name)
+            throws IllegalArgumentException {
+        if (name.trim().length() == 0) {
+            throw new IllegalArgumentException("Empty or blank managed object names are not allowed");
+        }
+        LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(elements);
+        celements.add(new InstantiableElement<M, N>(r, d, name));
+        return new ManagedObjectPath<M, N>(celements, r, d);
+    }
+
+    /**
+     * Creates a new child managed object path beneath the provided parent path
+     * using the relation's child managed object definition.
+     *
+     * @param <M>
+     *            The type of client managed object configuration that the child
+     *            path references.
+     * @param <N>
+     *            The type of server managed object configuration that the child
+     *            path references.
+     * @param r
+     *            The instantiable relation referencing the child.
+     * @param name
+     *            The relative name of the child managed object.
+     * @return Returns a new child managed object path beneath the provided
+     *         parent path.
+     * @throws IllegalArgumentException
+     *             If the provided name is empty or blank.
+     */
+    public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child(
+            InstantiableRelationDefinition<M, N> r, String name) throws IllegalArgumentException {
+        return child(r, r.getChildDefinition(), name);
+    }
+
+    /**
+     * Creates a new child managed object path beneath the provided parent path
+     * having the specified managed object definition.
+     *
+     * @param <M>
+     *            The type of client managed object configuration that the child
+     *            path references.
+     * @param <N>
+     *            The type of server managed object configuration that the child
+     *            path references.
+     * @param r
+     *            The optional relation referencing the child.
+     * @param d
+     *            The managed object definition associated with the child (must
+     *            be a sub-type of the relation).
+     * @return Returns a new child managed object path beneath the provided
+     *         parent path.
+     */
+    public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child(
+            OptionalRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d) {
+        LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(elements);
+        celements.add(new OptionalElement<M, N>(r, d));
+        return new ManagedObjectPath<M, N>(celements, r, d);
+    }
+
+    /**
+     * Creates a new child managed object path beneath the provided parent path
+     * using the relation's child managed object definition.
+     *
+     * @param <M>
+     *            The type of client managed object configuration that the child
+     *            path references.
+     * @param <N>
+     *            The type of server managed object configuration that the child
+     *            path references.
+     * @param r
+     *            The optional relation referencing the child.
+     * @return Returns a new child managed object path beneath the provided
+     *         parent path.
+     */
+    public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child(
+            OptionalRelationDefinition<M, N> r) {
+        return child(r, r.getChildDefinition());
+    }
+
+    /**
+     * Creates a new child managed object path beneath the provided parent path
+     * having the specified managed object definition.
+     *
+     * @param <M>
+     *            The type of client managed object configuration that the child
+     *            path references.
+     * @param <N>
+     *            The type of server managed object configuration that the child
+     *            path references.
+     * @param r
+     *            The singleton relation referencing the child.
+     * @param d
+     *            The managed object definition associated with the child (must
+     *            be a sub-type of the relation).
+     * @return Returns a new child managed object path beneath the provided
+     *         parent path.
+     */
+    public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child(
+            SingletonRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d) {
+        LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(elements);
+        celements.add(new SingletonElement<M, N>(r, d));
+        return new ManagedObjectPath<M, N>(celements, r, d);
+    }
+
+    /**
+     * Creates a new child managed object path beneath the provided parent path
+     * using the relation's child managed object definition.
+     *
+     * @param <M>
+     *            The type of client managed object configuration that the child
+     *            path references.
+     * @param <N>
+     *            The type of server managed object configuration that the child
+     *            path references.
+     * @param r
+     *            The singleton relation referencing the child.
+     * @return Returns a new child managed object path beneath the provided
+     *         parent path.
+     */
+    public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child(
+            SingletonRelationDefinition<M, N> r) {
+        return child(r, r.getChildDefinition());
+    }
+
+    /**
+     * Creates a new child managed object path beneath the provided parent path
+     * having the specified managed object definition.
+     *
+     * @param <M>
+     *            The type of client managed object configuration that the child
+     *            path references.
+     * @param <N>
+     *            The type of server managed object configuration that the child
+     *            path references.
+     * @param r
+     *            The set relation referencing the child.
+     * @param d
+     *            The managed object definition associated with the child (must
+     *            be a sub-type of the relation).
+     * @return Returns a new child managed object path beneath the provided
+     *         parent path.
+     * @throws IllegalArgumentException
+     *             If the provided name is empty or blank.
+     */
+    public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child(
+            SetRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d)
+            throws IllegalArgumentException {
+        LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(elements);
+        celements.add(new SetElement<M, N>(r, d));
+        return new ManagedObjectPath<M, N>(celements, r, d);
+    }
+
+    /**
+     * Creates a new child managed object path beneath the provided parent path
+     * having the managed object definition indicated by <code>name</code>.
+     *
+     * @param <M>
+     *            The type of client managed object configuration that the path
+     *            references.
+     * @param <N>
+     *            The type of server managed object configuration that the path
+     *            references.
+     * @param r
+     *            The set relation referencing the child.
+     * @param name
+     *            The name of the managed object definition associated with the
+     *            child (must be a sub-type of the relation).
+     * @return Returns a new child managed object path beneath the provided
+     *         parent path.
+     * @throws IllegalArgumentException
+     *             If the provided name is empty or blank or specifies a managed
+     *             object definition which is not a sub-type of the relation's
+     *             child definition.
+     */
+    public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<? extends M, ? extends N> child(
+            SetRelationDefinition<M, N> r, String name) throws IllegalArgumentException {
+        AbstractManagedObjectDefinition<M, N> d = r.getChildDefinition();
+        return child(r, d.getChild(name));
+    }
+
+    /**
+     * Creates a new child managed object path beneath the provided parent path
+     * using the relation's child managed object definition.
+     *
+     * @param <M>
+     *            The type of client managed object configuration that the child
+     *            path references.
+     * @param <N>
+     *            The type of server managed object configuration that the child
+     *            path references.
+     * @param r
+     *            The set relation referencing the child.
+     * @return Returns a new child managed object path beneath the provided
+     *         parent path.
+     * @throws IllegalArgumentException
+     *             If the provided name is empty or blank.
+     */
+    public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child(
+            SetRelationDefinition<M, N> r) throws IllegalArgumentException {
+        return child(r, r.getChildDefinition());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        } else if (obj instanceof ManagedObjectPath) {
+            ManagedObjectPath<?, ?> other = (ManagedObjectPath<?, ?>) obj;
+            return toString().equals(other.toString());
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Get the definition of the managed object referred to by this path.
+     * <p>
+     * When the path is empty, the {@link RootCfgDefn} is returned.
+     *
+     * @return Returns the definition of the managed object referred to by this
+     *         path, or the {@link RootCfgDefn} if the path is empty.
+     */
+    public AbstractManagedObjectDefinition<C, S> getManagedObjectDefinition() {
+        return d;
+    }
+
+    /**
+     * Get the name of the managed object referred to by this path if
+     * applicable.
+     * <p>
+     * If there path does not refer to an instantiable managed object
+     * <code>null</code> is returned.
+     *
+     * @return Returns the name of the managed object referred to by this path,
+     *         or <code>null</code> if the managed object does not have a name.
      */
     public String getName() {
-      return null;
+        if (elements.isEmpty()) {
+            return null;
+        } else {
+            return elements.get(elements.size() - 1).getName();
+        }
     }
 
-
-
     /**
-     * Get the relation definition associated with this element.
+     * Get the relation definition of the managed object referred to by this
+     * path.
+     * <p>
+     * When the path is empty, the <code>null</code> is returned.
      *
-     * @return Returns the relation definition associated with this
-     *         element.
+     * @return Returns the relation definition of the managed object referred to
+     *         by this path, or the <code>null</code> if the path is empty.
      */
-    public abstract RelationDefinition<? super C, ? super S>
-        getRelationDefinition();
-
-
+    public RelationDefinition<? super C, ? super S> getRelationDefinition() {
+        return r;
+    }
 
     /**
-     * Serialize this path element using the provided serialization
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode() {
+        return toString().hashCode();
+    }
+
+    /**
+     * Determine whether or not this path contains any path elements.
+     *
+     * @return Returns <code>true</code> if this path does not contain any path
+     *         elements.
+     */
+    public boolean isEmpty() {
+        return elements.isEmpty();
+    }
+
+    /**
+     * Determines whether this managed object path references the same location
+     * as the provided managed object path.
+     * <p>
+     * This method differs from <code>equals</code> in that it ignores sub-type
+     * definitions.
+     *
+     * @param other
+     *            The managed object path to be compared.
+     * @return Returns <code>true</code> if this managed object path references
+     *         the same location as the provided managed object path.
+     */
+    public boolean matches(ManagedObjectPath<?, ?> other) {
+        DN thisDN = toDN();
+        DN otherDN = other.toDN();
+        return thisDN.equals(otherDN);
+    }
+
+    /**
+     * Creates a new parent managed object path representing the immediate
+     * parent of this path. This method is a short-hand for
+     * <code>parent(1)</code>.
+     *
+     * @return Returns a new parent managed object path representing the
+     *         immediate parent of this path.
+     * @throws IllegalArgumentException
+     *             If this path does not have a parent (i.e. it is the empty
+     *             path).
+     */
+    public ManagedObjectPath<?, ?> parent() throws IllegalArgumentException {
+        return parent(1);
+    }
+
+    /**
+     * Creates a new parent managed object path the specified number of path
+     * elements above this path.
+     *
+     * @param offset
+     *            The number of path elements (0 - means no offset, 1 means the
+     *            parent, and 2 means the grand-parent).
+     * @return Returns a new parent managed object path the specified number of
+     *         path elements above this path.
+     * @throws IllegalArgumentException
+     *             If the offset is less than 0, or greater than the number of
+     *             path elements in this path.
+     */
+    public ManagedObjectPath<?, ?> parent(int offset) throws IllegalArgumentException {
+        if (offset < 0) {
+            throw new IllegalArgumentException("Negative offset");
+        }
+
+        if (offset > elements.size()) {
+            throw new IllegalArgumentException("Offset is greater than the number of path elements");
+        }
+
+        // An offset of 0 leaves the path unchanged.
+        if (offset == 0) {
+            return this;
+        }
+
+        // Return the empty path if the parent has zero elements.
+        if (elements.size() == offset) {
+            return emptyPath();
+        }
+
+        LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(elements.subList(0, elements.size()
+                - offset));
+        return create(celements, celements.getLast());
+    }
+
+    /**
+     * Creates a new managed object path which has the same structure as this
+     * path except that the final path element is renamed. The final path
+     * element must comprise of an instantiable relation.
+     *
+     * @param newName
+     *            The new name of the final path element.
+     * @return Returns a new managed object path which has the same structure as
+     *         this path except that the final path element is renamed.
+     * @throws IllegalStateException
+     *             If this managed object path is empty or if its final path
+     *             element does not comprise of an instantiable relation.
+     */
+    @SuppressWarnings("unchecked")
+    public ManagedObjectPath<C, S> rename(String newName) throws IllegalStateException {
+        if (elements.size() == 0) {
+            throw new IllegalStateException("Cannot rename an empty path");
+        }
+
+        if (r instanceof InstantiableRelationDefinition) {
+            InstantiableRelationDefinition<? super C, ? super S> ir = (InstantiableRelationDefinition<? super C, ? super S>) r;
+            return parent().child(ir, d, newName);
+        } else {
+            throw new IllegalStateException("Not an instantiable relation");
+        }
+    }
+
+    /**
+     * Serialize this managed object path using the provided serialization
      * strategy.
+     * <p>
+     * The path elements will be passed to the serializer in big-endian order:
+     * starting from the root element and proceeding down to the leaf.
      *
      * @param serializer
-     *          The managed object path serialization strategy.
+     *            The managed object path serialization strategy.
      */
-    public abstract void serialize(ManagedObjectPathSerializer serializer);
-  }
-
-
-
-  /**
-   * A path element representing an instantiable managed object.
-   */
-  private static final class InstantiableElement
-      <C extends ConfigurationClient, S extends Configuration>
-      extends Element<C, S> {
-
-    // Factory method.
-    private static final <C extends ConfigurationClient,
-        S extends Configuration>
-        InstantiableElement<C, S> create(
-        InstantiableRelationDefinition<? super C, ? super S> r,
-        AbstractManagedObjectDefinition<C, S> d, String name) {
-      return new InstantiableElement<C, S>(r, d, name);
-    }
-
-    // The name of the managed object.
-    private final String name;
-
-    // The instantiable relation.
-    private final InstantiableRelationDefinition<? super C, ? super S> r;
-
-
-
-    // Private constructor.
-    private InstantiableElement(
-        InstantiableRelationDefinition<? super C, ? super S> r,
-        AbstractManagedObjectDefinition<C, S> d, String name) {
-      super(d);
-      this.r = r;
-      this.name = name;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getName() {
-      return name;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public InstantiableRelationDefinition<? super C, ? super S>
-        getRelationDefinition() {
-      return r;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
     public void serialize(ManagedObjectPathSerializer serializer) {
-      serializer.appendManagedObjectPathElement(r,
-          getManagedObjectDefinition(), name);
-    }
-  }
-
-
-
-  /**
-   * A path element representing an optional managed object.
-   */
-  private static final class OptionalElement
-      <C extends ConfigurationClient, S extends Configuration>
-      extends Element<C, S> {
-
-    // Factory method.
-    private static final <C extends ConfigurationClient,
-        S extends Configuration> OptionalElement<C, S> create(
-        OptionalRelationDefinition<? super C, ? super S> r,
-        AbstractManagedObjectDefinition<C, S> d) {
-      return new OptionalElement<C, S>(r, d);
-    }
-
-    // The optional relation.
-    private final OptionalRelationDefinition<? super C, ? super S> r;
-
-
-
-    // Private constructor.
-    private OptionalElement(OptionalRelationDefinition<? super C, ? super S> r,
-        AbstractManagedObjectDefinition<C, S> d) {
-      super(d);
-      this.r = r;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public OptionalRelationDefinition<? super C, ? super S>
-        getRelationDefinition() {
-      return r;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void serialize(ManagedObjectPathSerializer serializer) {
-      serializer
-          .appendManagedObjectPathElement(r, getManagedObjectDefinition());
-    }
-  }
-
-
-
-  /**
-   * A path element representing an set managed object.
-   */
-  private static final class SetElement
-      <C extends ConfigurationClient, S extends Configuration>
-      extends Element<C, S> {
-
-    // Factory method.
-    private static final <C extends ConfigurationClient,
-        S extends Configuration>
-        SetElement<C, S> create(
-        SetRelationDefinition<? super C, ? super S> r,
-        AbstractManagedObjectDefinition<C, S> d) {
-      return new SetElement<C, S>(r, d);
-    }
-
-    // The set relation.
-    private final SetRelationDefinition<? super C, ? super S> r;
-
-
-
-    // Private constructor.
-    private SetElement(
-        SetRelationDefinition<? super C, ? super S> r,
-        AbstractManagedObjectDefinition<C, S> d) {
-      super(d);
-      this.r = r;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public SetRelationDefinition<? super C, ? super S>
-        getRelationDefinition() {
-      return r;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void serialize(ManagedObjectPathSerializer serializer) {
-      serializer.appendManagedObjectPathElement(r,
-          getManagedObjectDefinition());
-    }
-  }
-
-
-
-  /**
-   * A path element representing a singleton managed object.
-   */
-  private static final class SingletonElement
-      <C extends ConfigurationClient, S extends Configuration>
-      extends Element<C, S> {
-
-    // Factory method.
-    private static final <C extends ConfigurationClient,
-        S extends Configuration> SingletonElement<C, S> create(
-        SingletonRelationDefinition<? super C, ? super S> r,
-        AbstractManagedObjectDefinition<C, S> d) {
-      return new SingletonElement<C, S>(r, d);
-    }
-
-    // The singleton relation.
-    private final SingletonRelationDefinition<? super C, ? super S> r;
-
-
-
-    // Private constructor.
-    private SingletonElement(
-        SingletonRelationDefinition<? super C, ? super S> r,
-        AbstractManagedObjectDefinition<C, S> d) {
-      super(d);
-      this.r = r;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public SingletonRelationDefinition<? super C, ? super S>
-        getRelationDefinition() {
-      return r;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void serialize(ManagedObjectPathSerializer serializer) {
-      serializer
-          .appendManagedObjectPathElement(r, getManagedObjectDefinition());
-    }
-  }
-
-
-
-  /**
-   * A serialize which is used to generate the toString
-   * representation.
-   */
-  private static final class StringSerializer implements
-      ManagedObjectPathSerializer {
-
-    // Serialize to this string builder.
-    private final StringBuilder builder;
-
-
-
-    // Private constructor.
-    private StringSerializer(StringBuilder builder) {
-      this.builder = builder;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public <M extends ConfigurationClient, N extends Configuration>
-        void appendManagedObjectPathElement(
-        InstantiableRelationDefinition<? super M, ? super N> r,
-        AbstractManagedObjectDefinition<M, N> d, String name) {
-      serializeElement(r, d);
-
-      // Be careful to escape any forward slashes in the name.
-      builder.append("+name=");
-      builder.append(name.replace("/", "//"));
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public <M extends ConfigurationClient, N extends Configuration>
-        void appendManagedObjectPathElement(
-        OptionalRelationDefinition<? super M, ? super N> r,
-        AbstractManagedObjectDefinition<M, N> d) {
-      serializeElement(r, d);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public <M extends ConfigurationClient, N extends Configuration>
-        void appendManagedObjectPathElement(
-        SingletonRelationDefinition<? super M, ? super N> r,
-        AbstractManagedObjectDefinition<M, N> d) {
-      serializeElement(r, d);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public <M extends ConfigurationClient, N extends Configuration>
-        void appendManagedObjectPathElement(
-        SetRelationDefinition<? super M, ? super N> r,
-        AbstractManagedObjectDefinition<M, N> d) {
-      serializeElement(r, d);
-    }
-
-
-
-    // Common element serialization.
-    private <M, N> void serializeElement(RelationDefinition<?, ?> r,
-        AbstractManagedObjectDefinition<?, ?> d) {
-      // Always specify the relation name.
-      builder.append("/relation=");
-      builder.append(r.getName());
-
-      // Only specify the type if it is a sub-type of the relation's
-      // type.
-      if (r.getChildDefinition() != d) {
-        builder.append("+type=");
-        builder.append(d.getName());
-      }
-    }
-  }
-
-  // Single instance of a root path.
-  private static final ManagedObjectPath<RootCfgClient, RootCfg> EMPTY_PATH =
-      new ManagedObjectPath<RootCfgClient, RootCfg>(
-      new LinkedList<Element<?, ?>>(), null, RootCfgDefn.getInstance());
-
-  // A regular expression used to parse path elements.
-  private static final Pattern PE_REGEXP = Pattern
-      .compile("^\\s*relation=\\s*([^+]+)\\s*"
-          + "(\\+\\s*type=\\s*([^+]+)\\s*)?"
-          + "(\\+\\s*name=\\s*([^+]+)\\s*)?$");
-
-
-
-  /**
-   * Creates a new managed object path representing the configuration
-   * root.
-   *
-   * @return Returns a new managed object path representing the
-   *         configuration root.
-   */
-  public static ManagedObjectPath<RootCfgClient, RootCfg> emptyPath() {
-    return EMPTY_PATH;
-  }
-
-
-
-  /**
-   * Returns a managed object path holding the value of the specified
-   * string.
-   *
-   * @param s
-   *          The string to be parsed.
-   * @return Returns a managed object path holding the value of the
-   *         specified string.
-   * @throws IllegalArgumentException
-   *           If the string could not be parsed.
-   */
-  public static ManagedObjectPath<?, ?> valueOf(String s)
-      throws IllegalArgumentException {
-    String ns = s.trim();
-
-    // Check for root special case.
-    if (ns.equals("/")) {
-      return EMPTY_PATH;
-    }
-
-    // Parse the elements.
-    LinkedList<Element<?, ?>> elements = new LinkedList<Element<?, ?>>();
-    Element<?, ?> lastElement = null;
-    AbstractManagedObjectDefinition<?, ?> definition = RootCfgDefn
-        .getInstance();
-
-    if (!ns.startsWith("/")) {
-      throw new IllegalArgumentException("Invalid path \"" + ns
-          + "\": must begin with a \"/\"");
-    }
-
-    int start = 1;
-    while (true) {
-      // Get the next path element.
-      int end;
-      for (end = start; end < ns.length(); end++) {
-        char c = ns.charAt(end);
-        if (c == '/') {
-          if (end == (ns.length() - 1)) {
-            throw new IllegalArgumentException("Invalid path \"" + ns
-                + "\": must not end with a trailing \"/\"");
-          }
-
-          if (ns.charAt(end + 1) == '/') {
-            // Found an escaped forward slash.
-            end++;
-          } else {
-            // Found the end of this path element.
-            break;
-          }
+        for (Element<?, ?> element : elements) {
+            element.serialize(serializer);
         }
-      }
-
-      // Get the next element.
-      String es = ns.substring(start, end);
-
-      Matcher m = PE_REGEXP.matcher(es);
-      if (!m.matches()) {
-        throw new IllegalArgumentException("Invalid path element \"" + es
-            + "\" in path \"" + ns + "\"");
-      }
-
-      // Mandatory.
-      String relation = m.group(1);
-
-      // Optional.
-      String type = m.group(3);
-
-      // Mandatory if relation is instantiable.
-      String name = m.group(5);
-
-      // Get the relation definition.
-      RelationDefinition<?, ?> r;
-      try {
-        r = definition.getRelationDefinition(relation);
-      } catch (IllegalArgumentException e) {
-        throw new IllegalArgumentException("Invalid path element \"" + es
-            + "\" in path \"" + ns + "\": unknown relation \"" + relation
-            + "\"");
-      }
-
-      // Append the next element.
-      lastElement = createElement(r, ns, es, type, name);
-      elements.add(lastElement);
-      definition = lastElement.getManagedObjectDefinition();
-
-      // Update start to point to the beginning of the next element.
-      if (end < ns.length()) {
-        // Skip to the beginning of the next element
-        start = end + 1;
-      } else {
-        // We reached the end of the string.
-        break;
-      }
     }
 
-    // Construct the new path.
-    return create(elements, lastElement);
-  }
+    /**
+     * Get the number of path elements in this managed object path.
+     *
+     * @return Returns the number of path elements (0 - means no offset, 1 means
+     *         the parent, and 2 means the grand-parent).
+     */
+    public int size() {
+        return elements.size();
+    }
 
+    /**
+     * Creates a DN representation of this managed object path.
+     *
+     * @return Returns a DN representation of this managed object path.
+     */
+    public DN toDN() {
+        // Use a simple serializer to create the contents.
+        DNSerializer serializer = new DNSerializer();
+        serialize(serializer);
+        return serializer.toDN();
+    }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        toString(builder);
+        return builder.toString();
+    }
 
-  // Factory method required in order to allow generic wild-card
-  // construction of new paths.
-  private static <C extends ConfigurationClient, S extends Configuration>
-      ManagedObjectPath<C, S> create(
-      LinkedList<Element<?, ?>> elements, Element<C, S> lastElement) {
-    return new ManagedObjectPath<C, S>(elements, lastElement
-        .getRelationDefinition(), lastElement.getManagedObjectDefinition());
-  }
-
-
-
-  // Decode an element.
-  private static <C extends ConfigurationClient, S extends Configuration>
-      Element<? extends C, ? extends S> createElement(
-      RelationDefinition<C, S> r, String path, String element, String type,
-      String name) {
-    // First determine the managed object definition.
-    AbstractManagedObjectDefinition<? extends C, ? extends S> d = null;
-
-    if (type != null) {
-      for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : r
-          .getChildDefinition().getAllChildren()) {
-        if (child.getName().equals(type)) {
-          d = child;
-          break;
+    /**
+     * Appends a string representation of this managed object path to the
+     * provided string builder.
+     *
+     * @param builder
+     *            Append the string representation to this builder.
+     * @see #toString()
+     */
+    public void toString(final StringBuilder builder) {
+        if (isEmpty()) {
+            // Special treatment of root configuration paths.
+            builder.append('/');
+        } else {
+            // Use a simple serializer to create the contents.
+            ManagedObjectPathSerializer serializer = new StringSerializer(builder);
+            serialize(serializer);
         }
-      }
-
-      if (d == null) {
-        throw new IllegalArgumentException("Invalid path element \"" + element
-            + "\" in path \"" + path + "\": unknown sub-type \"" + type + "\"");
-      }
-    } else {
-      d = r.getChildDefinition();
     }
 
-    if (r instanceof InstantiableRelationDefinition) {
-      InstantiableRelationDefinition<C, S> ir =
-        (InstantiableRelationDefinition<C, S>) r;
-
-      if (name == null) {
-        throw new IllegalArgumentException("Invalid path element \"" + element
-            + "\" in path \"" + path
-            + "\": no instance name for instantiable relation");
-      }
-
-      return InstantiableElement.create(ir, d, name);
-    } else if (r instanceof SetRelationDefinition) {
-      SetRelationDefinition<C, S> ir = (SetRelationDefinition<C, S>) r;
-
-      if (name != null) {
-        throw new IllegalArgumentException("Invalid path element \"" + element
-            + "\" in path \"" + path
-            + "\": instance name specified for set relation");
-      }
-
-      return SetElement.create(ir, d);
-    } else if (r instanceof OptionalRelationDefinition) {
-      OptionalRelationDefinition<C, S> or =
-        (OptionalRelationDefinition<C, S>) r;
-
-      if (name != null) {
-        throw new IllegalArgumentException("Invalid path element \"" + element
-            + "\" in path \"" + path
-            + "\": instance name specified for optional relation");
-      }
-
-      return OptionalElement.create(or, d);
-    } else if (r instanceof SingletonRelationDefinition) {
-      SingletonRelationDefinition<C, S> sr =
-        (SingletonRelationDefinition<C, S>) r;
-
-      if (name != null) {
-        throw new IllegalArgumentException("Invalid path element \"" + element
-            + "\" in path \"" + path
-            + "\": instance name specified for singleton relation");
-      }
-
-      return SingletonElement.create(sr, d);
-    } else {
-      throw new IllegalArgumentException("Invalid path element \"" + element
-          + "\" in path \"" + path + "\": unsupported relation type");
-    }
-  }
-
-  // The managed object definition in this path.
-  private final AbstractManagedObjectDefinition<C, S> d;
-
-  // The list of path elements in this path.
-  private final List<Element<?, ?>> elements;
-
-  // The last relation definition in this path.
-  private final RelationDefinition<? super C, ? super S> r;
-
-
-
-  // Private constructor.
-  private ManagedObjectPath(LinkedList<Element<?, ?>> elements,
-      RelationDefinition<? super C, ? super S> r,
-      AbstractManagedObjectDefinition<C, S> d) {
-    this.elements = Collections.unmodifiableList(elements);
-    this.r = r;
-    this.d = d;
-  }
-
-
-
-  /**
-   * Creates a new managed object path which has the same structure as
-   * this path except that the final path element is associated with
-   * the specified managed object definition.
-   *
-   * @param <CC>
-   *          The type of client managed object configuration that
-   *          this path will reference.
-   * @param <SS>
-   *          The type of server managed object configuration that
-   *          this path will reference.
-   * @param nd
-   *          The new managed object definition.
-   * @return Returns a new managed object path which has the same
-   *         structure as this path except that the final path element
-   *         is associated with the specified managed object
-   *         definition.
-   */
-  @SuppressWarnings("unchecked")
-  public <CC extends C, SS extends S> ManagedObjectPath<CC, SS> asSubType(
-      AbstractManagedObjectDefinition<CC, SS> nd) {
-    if (r instanceof InstantiableRelationDefinition) {
-      InstantiableRelationDefinition<? super C, ? super S> ir =
-        (InstantiableRelationDefinition<? super C, ? super S>) r;
-      if (elements.size() == 0) {
-        return parent().child(ir, nd, "null");
-      } else {
-        return parent().child(ir, nd,
-            elements.get(elements.size() - 1).getName());
-      }
-    } else if (r instanceof SetRelationDefinition) {
-      SetRelationDefinition<? super C, ? super S> sr =
-        (SetRelationDefinition<? super C, ? super S>) r;
-      return parent().child(sr, nd);
-    } else if (r instanceof OptionalRelationDefinition) {
-      OptionalRelationDefinition<? super C, ? super S> or =
-        (OptionalRelationDefinition<? super C, ? super S>) r;
-      return parent().child(or, nd);
-    } else {
-      SingletonRelationDefinition<? super C, ? super S> sr =
-        (SingletonRelationDefinition<? super C, ? super S>) r;
-      return parent().child(sr, nd);
-    }
-  }
-
-
-
-  /**
-   * Creates a new child managed object path beneath the provided
-   * parent path having the specified managed object definition.
-   *
-   * @param <M>
-   *          The type of client managed object configuration that the
-   *          child path references.
-   * @param <N>
-   *          The type of server managed object configuration that the
-   *          child path references.
-   * @param r
-   *          The instantiable relation referencing the child.
-   * @param d
-   *          The managed object definition associated with the child
-   *          (must be a sub-type of the relation).
-   * @param name
-   *          The relative name of the child managed object.
-   * @return Returns a new child managed object path beneath the
-   *         provided parent path.
-   * @throws IllegalArgumentException
-   *           If the provided name is empty or blank.
-   */
-  public <M extends ConfigurationClient, N extends Configuration>
-      ManagedObjectPath<M, N> child(
-      InstantiableRelationDefinition<? super M, ? super N> r,
-      AbstractManagedObjectDefinition<M, N> d, String name)
-      throws IllegalArgumentException {
-    if (name.trim().length() == 0) {
-      throw new IllegalArgumentException(
-          "Empty or blank managed object names are not allowed");
-    }
-    LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(
-        elements);
-    celements.add(new InstantiableElement<M, N>(r, d, name));
-    return new ManagedObjectPath<M, N>(celements, r, d);
-  }
-
-
-
-  /**
-   * Creates a new child managed object path beneath the provided
-   * parent path using the relation's child managed object definition.
-   *
-   * @param <M>
-   *          The type of client managed object configuration that the
-   *          child path references.
-   * @param <N>
-   *          The type of server managed object configuration that the
-   *          child path references.
-   * @param r
-   *          The instantiable relation referencing the child.
-   * @param name
-   *          The relative name of the child managed object.
-   * @return Returns a new child managed object path beneath the
-   *         provided parent path.
-   * @throws IllegalArgumentException
-   *           If the provided name is empty or blank.
-   */
-  public <M extends ConfigurationClient, N extends Configuration>
-      ManagedObjectPath<M, N> child(
-      InstantiableRelationDefinition<M, N> r, String name)
-      throws IllegalArgumentException {
-    return child(r, r.getChildDefinition(), name);
-  }
-
-
-
-  /**
-   * Creates a new child managed object path beneath the provided
-   * parent path having the specified managed object definition.
-   *
-   * @param <M>
-   *          The type of client managed object configuration that the
-   *          child path references.
-   * @param <N>
-   *          The type of server managed object configuration that the
-   *          child path references.
-   * @param r
-   *          The optional relation referencing the child.
-   * @param d
-   *          The managed object definition associated with the child
-   *          (must be a sub-type of the relation).
-   * @return Returns a new child managed object path beneath the
-   *         provided parent path.
-   */
-  public <M extends ConfigurationClient, N extends Configuration>
-      ManagedObjectPath<M, N> child(
-      OptionalRelationDefinition<? super M, ? super N> r,
-      AbstractManagedObjectDefinition<M, N> d) {
-    LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(
-        elements);
-    celements.add(new OptionalElement<M, N>(r, d));
-    return new ManagedObjectPath<M, N>(celements, r, d);
-  }
-
-
-
-  /**
-   * Creates a new child managed object path beneath the provided
-   * parent path using the relation's child managed object definition.
-   *
-   * @param <M>
-   *          The type of client managed object configuration that the
-   *          child path references.
-   * @param <N>
-   *          The type of server managed object configuration that the
-   *          child path references.
-   * @param r
-   *          The optional relation referencing the child.
-   * @return Returns a new child managed object path beneath the
-   *         provided parent path.
-   */
-  public <M extends ConfigurationClient, N extends Configuration>
-      ManagedObjectPath<M, N> child(OptionalRelationDefinition<M, N> r) {
-    return child(r, r.getChildDefinition());
-  }
-
-
-
-  /**
-   * Creates a new child managed object path beneath the provided
-   * parent path having the specified managed object definition.
-   *
-   * @param <M>
-   *          The type of client managed object configuration that the
-   *          child path references.
-   * @param <N>
-   *          The type of server managed object configuration that the
-   *          child path references.
-   * @param r
-   *          The singleton relation referencing the child.
-   * @param d
-   *          The managed object definition associated with the child
-   *          (must be a sub-type of the relation).
-   * @return Returns a new child managed object path beneath the
-   *         provided parent path.
-   */
-  public <M extends ConfigurationClient, N extends Configuration>
-      ManagedObjectPath<M, N> child(
-      SingletonRelationDefinition<? super M, ? super N> r,
-      AbstractManagedObjectDefinition<M, N> d) {
-    LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(
-        elements);
-    celements.add(new SingletonElement<M, N>(r, d));
-    return new ManagedObjectPath<M, N>(celements, r, d);
-  }
-
-
-
-  /**
-   * Creates a new child managed object path beneath the provided
-   * parent path using the relation's child managed object definition.
-   *
-   * @param <M>
-   *          The type of client managed object configuration that the
-   *          child path references.
-   * @param <N>
-   *          The type of server managed object configuration that the
-   *          child path references.
-   * @param r
-   *          The singleton relation referencing the child.
-   * @return Returns a new child managed object path beneath the
-   *         provided parent path.
-   */
-  public <M extends ConfigurationClient, N extends Configuration>
-      ManagedObjectPath<M, N> child(SingletonRelationDefinition<M, N> r) {
-    return child(r, r.getChildDefinition());
-  }
-
-
-
-  /**
-   * Creates a new child managed object path beneath the provided
-   * parent path having the specified managed object definition.
-   *
-   * @param <M>
-   *          The type of client managed object configuration that the
-   *          child path references.
-   * @param <N>
-   *          The type of server managed object configuration that the
-   *          child path references.
-   * @param r
-   *          The set relation referencing the child.
-   * @param d
-   *          The managed object definition associated with the child
-   *          (must be a sub-type of the relation).
-   * @return Returns a new child managed object path beneath the
-   *         provided parent path.
-   * @throws IllegalArgumentException
-   *           If the provided name is empty or blank.
-   */
-  public <M extends ConfigurationClient, N extends Configuration>
-      ManagedObjectPath<M, N> child(
-      SetRelationDefinition<? super M, ? super N> r,
-      AbstractManagedObjectDefinition<M, N> d)
-      throws IllegalArgumentException {
-    LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(
-        elements);
-    celements.add(new SetElement<M, N>(r, d));
-    return new ManagedObjectPath<M, N>(celements, r, d);
-  }
-
-
-
-  /**
-   * Creates a new child managed object path beneath the provided parent
-   * path having the managed object definition indicated by
-   * <code>name</code>.
-   *
-   * @param <M>
-   *          The type of client managed object configuration that the
-   *          path references.
-   * @param <N>
-   *          The type of server managed object configuration that the
-   *          path references.
-   * @param r
-   *          The set relation referencing the child.
-   * @param name
-   *          The name of the managed object definition associated with
-   *          the child (must be a sub-type of the relation).
-   * @return Returns a new child managed object path beneath the
-   *         provided parent path.
-   * @throws IllegalArgumentException
-   *           If the provided name is empty or blank or specifies a
-   *           managed object definition which is not a sub-type of the
-   *           relation's child definition.
-   */
-  public <M extends ConfigurationClient, N extends Configuration>
-      ManagedObjectPath<? extends M, ? extends N> child(
-      SetRelationDefinition<M, N> r,
-      String name)
-      throws IllegalArgumentException {
-    AbstractManagedObjectDefinition<M, N> d = r.getChildDefinition();
-    return child(r, d.getChild(name));
-  }
-
-
-
-  /**
-   * Creates a new child managed object path beneath the provided
-   * parent path using the relation's child managed object definition.
-   *
-   * @param <M>
-   *          The type of client managed object configuration that the
-   *          child path references.
-   * @param <N>
-   *          The type of server managed object configuration that the
-   *          child path references.
-   * @param r
-   *          The set relation referencing the child.
-   * @return Returns a new child managed object path beneath the
-   *         provided parent path.
-   * @throws IllegalArgumentException
-   *           If the provided name is empty or blank.
-   */
-  public <M extends ConfigurationClient, N extends Configuration>
-      ManagedObjectPath<M, N> child(
-      SetRelationDefinition<M, N> r)
-      throws IllegalArgumentException {
-    return child(r, r.getChildDefinition());
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public boolean equals(Object obj) {
-    if (obj == this) {
-      return true;
-    } else if (obj instanceof ManagedObjectPath) {
-      ManagedObjectPath<?, ?> other = (ManagedObjectPath<?, ?>) obj;
-      return toString().equals(other.toString());
-    } else {
-      return false;
-    }
-  }
-
-
-
-  /**
-   * Get the definition of the managed object referred to by this
-   * path.
-   * <p>
-   * When the path is empty, the {@link RootCfgDefn} is returned.
-   *
-   * @return Returns the definition of the managed object referred to
-   *         by this path, or the {@link RootCfgDefn} if the path is
-   *         empty.
-   */
-  public AbstractManagedObjectDefinition<C, S> getManagedObjectDefinition() {
-    return d;
-  }
-
-
-
-  /**
-   * Get the name of the managed object referred to by this path if
-   * applicable.
-   * <p>
-   * If there path does not refer to an instantiable managed object
-   * <code>null</code> is returned.
-   *
-   * @return Returns the name of the managed object referred to by
-   *         this path, or <code>null</code> if the managed object
-   *         does not have a name.
-   */
-  public String getName() {
-    if (elements.isEmpty()) {
-      return null;
-    } else {
-      return elements.get(elements.size() - 1).getName();
-    }
-  }
-
-
-
-  /**
-   * Get the relation definition of the managed object referred to by
-   * this path.
-   * <p>
-   * When the path is empty, the <code>null</code> is returned.
-   *
-   * @return Returns the relation definition of the managed object
-   *         referred to by this path, or the <code>null</code> if
-   *         the path is empty.
-   */
-  public RelationDefinition<? super C, ? super S> getRelationDefinition() {
-    return r;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public int hashCode() {
-    return toString().hashCode();
-  }
-
-
-
-  /**
-   * Determine whether or not this path contains any path elements.
-   *
-   * @return Returns <code>true</code> if this path does not contain
-   *         any path elements.
-   */
-  public boolean isEmpty() {
-    return elements.isEmpty();
-  }
-
-
-
-  /**
-   * Determines whether this managed object path references the same
-   * location as the provided managed object path.
-   * <p>
-   * This method differs from <code>equals</code> in that it ignores
-   * sub-type definitions.
-   *
-   * @param other
-   *          The managed object path to be compared.
-   * @return Returns <code>true</code> if this managed object path
-   *         references the same location as the provided managed
-   *         object path.
-   */
-  public boolean matches(ManagedObjectPath<?, ?> other) {
-    DN thisDN = toDN();
-    DN otherDN = other.toDN();
-    return thisDN.equals(otherDN);
-  }
-
-
-
-  /**
-   * Creates a new parent managed object path representing the
-   * immediate parent of this path. This method is a short-hand for
-   * <code>parent(1)</code>.
-   *
-   * @return Returns a new parent managed object path representing the
-   *         immediate parent of this path.
-   * @throws IllegalArgumentException
-   *           If this path does not have a parent (i.e. it is the
-   *           empty path).
-   */
-  public ManagedObjectPath<?, ?> parent() throws IllegalArgumentException {
-    return parent(1);
-  }
-
-
-
-  /**
-   * Creates a new parent managed object path the specified number of
-   * path elements above this path.
-   *
-   * @param offset
-   *          The number of path elements (0 - means no offset, 1
-   *          means the parent, and 2 means the grand-parent).
-   * @return Returns a new parent managed object path the specified
-   *         number of path elements above this path.
-   * @throws IllegalArgumentException
-   *           If the offset is less than 0, or greater than the
-   *           number of path elements in this path.
-   */
-  public ManagedObjectPath<?, ?> parent(int offset)
-      throws IllegalArgumentException {
-    if (offset < 0) {
-      throw new IllegalArgumentException("Negative offset");
-    }
-
-    if (offset > elements.size()) {
-      throw new IllegalArgumentException(
-          "Offset is greater than the number of path elements");
-    }
-
-    // An offset of 0 leaves the path unchanged.
-    if (offset == 0) {
-      return this;
-    }
-
-    // Return the empty path if the parent has zero elements.
-    if (elements.size() == offset) {
-      return emptyPath();
-    }
-
-    LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(
-        elements.subList(0, elements.size() - offset));
-    return create(celements, celements.getLast());
-  }
-
-
-
-  /**
-   * Creates a new managed object path which has the same structure as
-   * this path except that the final path element is renamed. The
-   * final path element must comprise of an instantiable relation.
-   *
-   * @param newName
-   *          The new name of the final path element.
-   * @return Returns a new managed object path which has the same
-   *         structure as this path except that the final path element
-   *         is renamed.
-   * @throws IllegalStateException
-   *           If this managed object path is empty or if its final
-   *           path element does not comprise of an instantiable
-   *           relation.
-   */
-  @SuppressWarnings("unchecked")
-  public ManagedObjectPath<C, S> rename(String newName)
-      throws IllegalStateException {
-    if (elements.size() == 0) {
-      throw new IllegalStateException("Cannot rename an empty path");
-    }
-
-    if (r instanceof InstantiableRelationDefinition) {
-      InstantiableRelationDefinition<? super C, ? super S> ir =
-        (InstantiableRelationDefinition<? super C, ? super S>) r;
-      return parent().child(ir, d, newName);
-    } else {
-      throw new IllegalStateException("Not an instantiable relation");
-    }
-  }
-
-
-
-  /**
-   * Serialize this managed object path using the provided
-   * serialization strategy.
-   * <p>
-   * The path elements will be passed to the serializer in big-endian
-   * order: starting from the root element and proceeding down to the
-   * leaf.
-   *
-   * @param serializer
-   *          The managed object path serialization strategy.
-   */
-  public void serialize(ManagedObjectPathSerializer serializer) {
-    for (Element<?, ?> element : elements) {
-      element.serialize(serializer);
-    }
-  }
-
-
-
-  /**
-   * Get the number of path elements in this managed object path.
-   *
-   * @return Returns the number of path elements (0 - means no offset,
-   *         1 means the parent, and 2 means the grand-parent).
-   */
-  public int size() {
-    return elements.size();
-  }
-
-
-
-  /**
-   * Creates a DN representation of this managed object path.
-   *
-   * @return Returns a DN representation of this managed object path.
-   */
-  public DN toDN() {
-    // Use a simple serializer to create the contents.
-    DNSerializer serializer = new DNSerializer();
-    serialize(serializer);
-    return serializer.toDN();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public String toString() {
-    StringBuilder builder = new StringBuilder();
-    toString(builder);
-    return builder.toString();
-  }
-
-
-
-  /**
-   * Appends a string representation of this managed object path to
-   * the provided string builder.
-   *
-   * @param builder
-   *          Append the string representation to this builder.
-   * @see #toString()
-   */
-  public void toString(final StringBuilder builder) {
-    if (isEmpty()) {
-      // Special treatment of root configuration paths.
-      builder.append('/');
-    } else {
-      // Use a simple serializer to create the contents.
-      ManagedObjectPathSerializer serializer = new StringSerializer(builder);
-      serialize(serializer);
-    }
-  }
-
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/Reference.java b/opendj-admin/src/main/java/org/opends/server/admin/Reference.java
index cf1cfbd..78a3ad9 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/Reference.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/Reference.java
@@ -26,220 +26,182 @@
  */
 package org.opends.server.admin;
 
+import static com.forgerock.opendj.util.StaticUtils.*;
 
-
-import org.opends.server.types.AttributeValue;
 import org.forgerock.opendj.ldap.DN;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.RDN;
-import org.opends.server.util.StaticUtils;
-
-
+import org.forgerock.opendj.ldap.RDN;
 
 /**
  * A reference to another managed object.
  *
  * @param <C>
- *          The type of client managed object configuration that this
- *          reference refers to.
+ *            The type of client managed object configuration that this
+ *            reference refers to.
  * @param <S>
- *          The type of server managed object configuration that this
- *          reference refers to.
+ *            The type of server managed object configuration that this
+ *            reference refers to.
  */
-public final class Reference<C extends ConfigurationClient,
-                             S extends Configuration> {
+public final class Reference<C extends ConfigurationClient, S extends Configuration> {
 
-  /**
-   * Parses a DN string value as a reference using the provided
-   * managed object path and relation definition.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that
-   *          this reference refers to.
-   * @param <S>
-   *          The type of server managed object configuration that
-   *          this reference refers to.
-   * @param p
-   *          The path of the referenced managed object's parent.
-   * @param rd
-   *          The instantiable relation in the parent which contains
-   *          the referenced managed object.
-   * @param s
-   *          The DN string value.
-   * @return Returns the new reference based on the provided DN string
-   *         value.
-   * @throws IllegalArgumentException
-   *           If the DN string value could not be decoded as a DN or
-   *           if the provided DN did not correspond to the provided
-   *           path and relation.
-   */
-  public static <C extends ConfigurationClient, S extends Configuration>
-  Reference<C, S> parseDN(
-      ManagedObjectPath<?, ?> p, InstantiableRelationDefinition<C, S> rd,
-      String s) throws IllegalArgumentException {
-    AbstractManagedObjectDefinition<?, ?> d = p.getManagedObjectDefinition();
-    RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName());
-    if (tmp != rd) {
-      throw new IllegalArgumentException("The relation \"" + rd.getName()
-          + "\" is not associated with the definition \"" + d.getName() + "\"");
+    /**
+     * Parses a DN string value as a reference using the provided managed object
+     * path and relation definition.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that this
+     *            reference refers to.
+     * @param <S>
+     *            The type of server managed object configuration that this
+     *            reference refers to.
+     * @param path
+     *            The path of the referenced managed object's parent.
+     * @param relationDef
+     *            The instantiable relation in the parent which contains the
+     *            referenced managed object.
+     * @param dnAsString
+     *            The DN string value.
+     * @return Returns the new reference based on the provided DN string value.
+     * @throws IllegalArgumentException
+     *             If the DN string value could not be decoded as a DN or if the
+     *             provided DN did not correspond to the provided path and
+     *             relation.
+     */
+    public static <C extends ConfigurationClient, S extends Configuration> Reference<C, S> parseDN(
+            ManagedObjectPath<?, ?> path, InstantiableRelationDefinition<C, S> relationDef, String dnAsString)
+            throws IllegalArgumentException {
+        AbstractManagedObjectDefinition<?, ?> definition = path.getManagedObjectDefinition();
+        RelationDefinition<?, ?> tmp = definition.getRelationDefinition(relationDef.getName());
+        if (tmp != relationDef) {
+            // TODO : i18n ?
+            throw new IllegalArgumentException("The relation \"" + relationDef.getName()
+                    + "\" is not associated with the definition \"" + definition.getName() + "\"");
+        }
+
+        DN dn = DN.valueOf(dnAsString);
+        RDN rdn = dn.rdn();
+        if (rdn == null) {
+            // TODO : i18n ?
+            throw new IllegalArgumentException("Unabled to decode the DN string: \"" + dnAsString + "\"");
+        }
+
+        // Check that the DN was valid.
+        String name = rdn.getFirstAVA().getAttributeValue().toString();
+        DN expected = path.child(relationDef, name).toDN();
+        if (!dn.equals(expected)) {
+            // TODO : i18n ?
+            throw new IllegalArgumentException("Unabled to decode the DN string: \"" + dnAsString + "\"");
+        }
+
+        return new Reference<C, S>(path, relationDef, name);
     }
 
-    DN dn;
-    try {
-      dn = DN.decode(s);
-    } catch (DirectoryException e) {
-      throw new IllegalArgumentException("Unabled to decode the DN string: \""
-          + s + "\"");
+    /**
+     * Parses a name as a reference using the provided managed object path and
+     * relation definition.
+     *
+     * @param <C>
+     *            The type of client managed object configuration that this
+     *            reference refers to.
+     * @param <S>
+     *            The type of server managed object configuration that this
+     *            reference refers to.
+     * @param p
+     *            The path of the referenced managed object's parent.
+     * @param rd
+     *            The instantiable relation in the parent which contains the
+     *            referenced managed object.
+     * @param s
+     *            The name of the referenced managed object.
+     * @return Returns the new reference based on the provided name.
+     * @throws IllegalArgumentException
+     *             If the relation is not associated with the provided parent's
+     *             definition, or if the provided name is empty.
+     */
+    public static <C extends ConfigurationClient, S extends Configuration> Reference<C, S> parseName(
+            ManagedObjectPath<?, ?> p, InstantiableRelationDefinition<C, S> rd, String s)
+            throws IllegalArgumentException {
+        // Sanity checks.
+        AbstractManagedObjectDefinition<?, ?> d = p.getManagedObjectDefinition();
+        RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName());
+        if (tmp != rd) {
+            throw new IllegalArgumentException("The relation \"" + rd.getName()
+                    + "\" is not associated with the definition \"" + d.getName() + "\"");
+        }
+
+        if (s.trim().length() == 0) {
+            throw new IllegalArgumentException("Empty names are not allowed");
+        }
+
+        return new Reference<C, S>(p, rd, s);
     }
 
-    RDN rdn = dn.getRDN();
-    if (rdn == null) {
-      throw new IllegalArgumentException("Unabled to decode the DN string: \""
-          + s + "\"");
+    // The name of the referenced managed object.
+    private final String name;
+
+    // The path of the referenced managed object.
+    private final ManagedObjectPath<C, S> path;
+
+    // The instantiable relation in the parent which contains the
+    // referenced managed object.
+    private final InstantiableRelationDefinition<C, S> relation;
+
+    // Private constructor.
+    private Reference(ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> relation, String name)
+            throws IllegalArgumentException {
+        this.relation = relation;
+        this.name = name;
+        this.path = parent.child(relation, name);
     }
 
-    AttributeValue av = rdn.getAttributeValue(0);
-    if (av == null) {
-      throw new IllegalArgumentException("Unabled to decode the DN string: \""
-          + s + "\"");
+    /**
+     * Gets the name of the referenced managed object.
+     *
+     * @return Returns the name of the referenced managed object.
+     */
+    public String getName() {
+        return name;
     }
 
-    String name = av.getValue().toString();
-
-    // Check that the DN was valid.
-    DN expected = p.child(rd, name).toDN();
-    if (!dn.equals(expected)) {
-      throw new IllegalArgumentException("Unabled to decode the DN string: \""
-          + s + "\"");
+    /**
+     * Gets the normalized name of the referenced managed object.
+     *
+     * @return Returns the normalized name of the referenced managed object.
+     */
+    public String getNormalizedName() {
+        PropertyDefinition<?> pd = relation.getNamingPropertyDefinition();
+        return normalizeName(pd);
     }
 
-    return new Reference<C, S>(p, rd, name);
-  }
-
-
-
-  /**
-   * Parses a name as a reference using the provided managed object
-   * path and relation definition.
-   *
-   * @param <C>
-   *          The type of client managed object configuration that
-   *          this reference refers to.
-   * @param <S>
-   *          The type of server managed object configuration that
-   *          this reference refers to.
-   * @param p
-   *          The path of the referenced managed object's parent.
-   * @param rd
-   *          The instantiable relation in the parent which contains
-   *          the referenced managed object.
-   * @param s
-   *          The name of the referenced managed object.
-   * @return Returns the new reference based on the provided name.
-   * @throws IllegalArgumentException
-   *           If the relation is not associated with the provided
-   *           parent's definition, or if the provided name is empty.
-   */
-  public static <C extends ConfigurationClient, S extends Configuration>
-  Reference<C, S> parseName(
-      ManagedObjectPath<?, ?> p, InstantiableRelationDefinition<C, S> rd,
-      String s) throws IllegalArgumentException {
-    // Sanity checks.
-    AbstractManagedObjectDefinition<?, ?> d = p.getManagedObjectDefinition();
-    RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName());
-    if (tmp != rd) {
-      throw new IllegalArgumentException("The relation \"" + rd.getName()
-          + "\" is not associated with the definition \"" + d.getName() + "\"");
+    /**
+     * Gets the DN of the referenced managed object.
+     *
+     * @return Returns the DN of the referenced managed object.
+     */
+    public DN toDN() {
+        return path.toDN();
     }
 
-    if (s.trim().length() == 0) {
-      throw new IllegalArgumentException("Empty names are not allowed");
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return name;
     }
 
-    return new Reference<C, S>(p, rd, s);
-  }
+    // Normalize a value using the specified naming property definition
+    // if defined.
+    private <T> String normalizeName(PropertyDefinition<T> pd) {
+        if (pd != null) {
+            try {
+                T tvalue = pd.decodeValue(name);
+                return pd.normalizeValue(tvalue);
+            } catch (IllegalPropertyValueStringException e) {
+                // Fall through to default normalization.
+            }
+        }
 
-  // The name of the referenced managed object.
-  private final String name;
-
-  // The path of the referenced managed object.
-  private final ManagedObjectPath<C, S> path;
-
-  // The instantiable relation in the parent which contains the
-  // referenced managed object.
-  private final InstantiableRelationDefinition<C, S> relation;
-
-
-
-  // Private constructor.
-  private Reference(ManagedObjectPath<?, ?> parent,
-      InstantiableRelationDefinition<C, S> relation, String name)
-      throws IllegalArgumentException {
-    this.relation = relation;
-    this.name = name;
-    this.path = parent.child(relation, name);
-  }
-
-
-
-  /**
-   * Gets the name of the referenced managed object.
-   *
-   * @return Returns the name of the referenced managed object.
-   */
-  public String getName() {
-    return name;
-  }
-
-
-
-  /**
-   * Gets the normalized name of the referenced managed object.
-   *
-   * @return Returns the normalized name of the referenced managed
-   *         object.
-   */
-  public String getNormalizedName() {
-    PropertyDefinition<?> pd = relation.getNamingPropertyDefinition();
-    return normalizeName(pd);
-  }
-
-
-
-  /**
-   * Gets the DN of the referenced managed object.
-   *
-   * @return Returns the DN of the referenced managed object.
-   */
-  public DN toDN() {
-    return path.toDN();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public String toString() {
-    return name;
-  }
-
-
-
-  // Normalize a value using the specified naming property definition
-  // if defined.
-  private <T> String normalizeName(PropertyDefinition<T> pd) {
-    if (pd != null) {
-      try {
-        T tvalue = pd.decodeValue(name);
-        return pd.normalizeValue(tvalue);
-      } catch (IllegalPropertyValueStringException e) {
-        // Fall through to default normalization.
-      }
+        // FIXME: should really use directory string normalizer.
+        String s = name.trim().replaceAll(" +", " ");
+        return toLowerCase(s);
     }
-
-    // FIXME: should really use directory string normalizer.
-    String s = name.trim().replaceAll(" +", " ");
-    return StaticUtils.toLowerCase(s);
-  }
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java b/opendj-admin/src/main/java/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java
index 7764f2a..df7834c 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java
@@ -27,8 +27,6 @@
  */
 package org.opends.server.admin.client.ldap;
 
-
-
 import java.util.Collection;
 import java.util.Hashtable;
 import java.util.LinkedList;
@@ -48,290 +46,245 @@
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
 
-import org.opends.admin.ads.util.BlindTrustManager;
-import org.opends.admin.ads.util.ConnectionUtils;
-import org.opends.admin.ads.util.TrustedSocketFactory;
 import org.opends.server.admin.client.AuthenticationException;
 import org.opends.server.admin.client.AuthenticationNotSupportedException;
 import org.opends.server.admin.client.CommunicationException;
-import org.opends.server.schema.SchemaConstants;
-
-
 
 /**
- * An LDAP connection adaptor which maps LDAP requests onto an
- * underlying JNDI connection context.
+ * An LDAP connection adaptor which maps LDAP requests onto an underlying JNDI
+ * connection context.
  */
 public final class JNDIDirContextAdaptor extends LDAPConnection {
 
-  /**
-   * Adapts the provided JNDI <code>DirContext</code>.
-   *
-   * @param dirContext
-   *          The JNDI connection.
-   * @return Returns a new JNDI connection adaptor.
-   */
-  public static JNDIDirContextAdaptor adapt(DirContext dirContext) {
-    return new JNDIDirContextAdaptor(dirContext);
-  }
-
-
-
-  /**
-   * Creates a new JNDI connection adaptor by performing a simple bind
-   * operation to the specified LDAP server.
-   *
-   * @param host
-   *          The host.
-   * @param port
-   *          The port.
-   * @param name
-   *          The LDAP bind DN.
-   * @param password
-   *          The LDAP bind password.
-   * @return Returns a new JNDI connection adaptor.
-   * @throws CommunicationException
-   *           If the client cannot contact the server due to an
-   *           underlying communication problem.
-   * @throws AuthenticationNotSupportedException
-   *           If the server does not support simple authentication.
-   * @throws AuthenticationException
-   *           If authentication failed for some reason, usually due
-   *           to invalid credentials.
-   */
-  public static JNDIDirContextAdaptor simpleBind(String host, int port,
-      String name, String password) throws CommunicationException,
-      AuthenticationNotSupportedException, AuthenticationException {
-    Hashtable<String, Object> env = new Hashtable<String, Object>();
-    env
-        .put(Context.INITIAL_CONTEXT_FACTORY,
-            "com.sun.jndi.ldap.LdapCtxFactory");
-    String hostname = ConnectionUtils.getHostNameForLdapUrl(host) ;
-    env.put(Context.PROVIDER_URL, "ldap://" + hostname + ":" + port);
-    env.put(Context.SECURITY_PRINCIPAL, name);
-    env.put(Context.SECURITY_CREDENTIALS, password);
-
-    DirContext ctx;
-    try {
-      ctx = new InitialLdapContext(env, null);
-    } catch (javax.naming.CommunicationException e) {
-      throw new CommunicationException(e);
-    } catch (javax.naming.AuthenticationException e) {
-      throw new AuthenticationException(e);
-    } catch (javax.naming.AuthenticationNotSupportedException e) {
-      throw new AuthenticationNotSupportedException(e);
-    } catch (NamingException e) {
-      // Assume some kind of communication problem.
-      throw new CommunicationException(e);
+    /**
+     * Adapts the provided JNDI <code>DirContext</code>.
+     *
+     * @param dirContext
+     *            The JNDI connection.
+     * @return Returns a new JNDI connection adaptor.
+     */
+    public static JNDIDirContextAdaptor adapt(DirContext dirContext) {
+        return new JNDIDirContextAdaptor(dirContext);
     }
 
-    return new JNDIDirContextAdaptor(ctx);
-  }
+    /**
+     * Creates a new JNDI connection adaptor by performing a simple bind
+     * operation to the specified LDAP server.
+     *
+     * @param host
+     *            The host.
+     * @param port
+     *            The port.
+     * @param name
+     *            The LDAP bind DN.
+     * @param password
+     *            The LDAP bind password.
+     * @return Returns a new JNDI connection adaptor.
+     * @throws CommunicationException
+     *             If the client cannot contact the server due to an underlying
+     *             communication problem.
+     * @throws AuthenticationNotSupportedException
+     *             If the server does not support simple authentication.
+     * @throws AuthenticationException
+     *             If authentication failed for some reason, usually due to
+     *             invalid credentials.
+     */
+    public static JNDIDirContextAdaptor simpleBind(String host, int port, String name, String password)
+            throws CommunicationException, AuthenticationNotSupportedException, AuthenticationException {
+        Hashtable<String, Object> env = new Hashtable<String, Object>();
+        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+        String hostname = ConnectionUtils.getHostNameForLdapUrl(host);
+        env.put(Context.PROVIDER_URL, "ldap://" + hostname + ":" + port);
+        env.put(Context.SECURITY_PRINCIPAL, name);
+        env.put(Context.SECURITY_CREDENTIALS, password);
 
-  /**
-   * Creates a new JNDI connection adaptor by performing a simple bind
-   * operation to the specified LDAP server.
-   *
-   * @param host
-   *          The host.
-   * @param port
-   *          The port.
-   * @param name
-   *          The LDAP bind DN.
-   * @param password
-   *          The LDAP bind password.
-   * @return Returns a new JNDI connection adaptor.
-   * @throws CommunicationException
-   *           If the client cannot contact the server due to an
-   *           underlying communication problem.
-   * @throws AuthenticationNotSupportedException
-   *           If the server does not support simple authentication.
-   * @throws AuthenticationException
-   *           If authentication failed for some reason, usually due
-   *           to invalid credentials.
-   */
-  public static JNDIDirContextAdaptor simpleSSLBind(String host, int port,
-      String name, String password) throws CommunicationException,
-      AuthenticationNotSupportedException, AuthenticationException {
-    Hashtable<String, Object> env = new Hashtable<String, Object>();
-    env.put(Context.INITIAL_CONTEXT_FACTORY,
-            "com.sun.jndi.ldap.LdapCtxFactory");
-    String hostname = ConnectionUtils.getHostNameForLdapUrl(host) ;
-    env.put(Context.PROVIDER_URL, "ldaps://" + hostname + ":" + port);
-    env.put(Context.SECURITY_PRINCIPAL, name);
-    env.put(Context.SECURITY_CREDENTIALS, password);
-    env.put(Context.SECURITY_AUTHENTICATION, "simple");
-    // Specify SSL
-    env.put(Context.SECURITY_PROTOCOL, "ssl");
-    env.put("java.naming.ldap.factory.socket",
-        org.opends.admin.ads.util.TrustedSocketFactory.class.getName());
-    TrustedSocketFactory.setCurrentThreadTrustManager(new BlindTrustManager(),
-              null);
-    DirContext ctx;
-    try {
-      ctx = new InitialLdapContext(env, null);
-    } catch (javax.naming.CommunicationException e) {
-      throw new CommunicationException(e);
-    } catch (javax.naming.AuthenticationException e) {
-      throw new AuthenticationException(e);
-    } catch (javax.naming.AuthenticationNotSupportedException e) {
-      throw new AuthenticationNotSupportedException(e);
-    } catch (NamingException e) {
-      // Assume some kind of communication problem.
-      throw new CommunicationException(e);
-    }
-
-    return new JNDIDirContextAdaptor(ctx);
-  }
-
-
-  // The JNDI connection context.
-  private final DirContext dirContext;
-
-
-
-  // Create a new JNDI connection adaptor using the provider JNDI
-  // DirContext.
-  private JNDIDirContextAdaptor(DirContext dirContext) {
-    this.dirContext = dirContext;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void createEntry(LdapName dn, Attributes attributes)
-      throws NamingException {
-    dirContext.createSubcontext(dn, attributes).close();
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void deleteSubtree(LdapName dn) throws NamingException {
-    // Delete the children first.
-    for (LdapName child : listEntries(dn, null)) {
-      deleteSubtree(child);
-    }
-
-    // Delete the named entry.
-    dirContext.destroySubcontext(dn);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public boolean entryExists(LdapName dn) throws NamingException {
-    boolean entryExists = false;
-    String filter = "(objectClass=*)";
-    SearchControls controls = new SearchControls();
-    controls.setSearchScope(SearchControls.OBJECT_SCOPE);
-    controls
-        .setReturningAttributes(new String[] { SchemaConstants.NO_ATTRIBUTES });
-    try {
-      NamingEnumeration<SearchResult> results = dirContext.search(dn, filter,
-          controls);
-      try
-      {
-        while (results.hasMore()) {
-          // To avoid having a systematic abandon in the server.
-          results.next();
-          entryExists = true;
+        DirContext ctx;
+        try {
+            ctx = new InitialLdapContext(env, null);
+        } catch (javax.naming.CommunicationException e) {
+            throw new CommunicationException(e);
+        } catch (javax.naming.AuthenticationException e) {
+            throw new AuthenticationException(e);
+        } catch (javax.naming.AuthenticationNotSupportedException e) {
+            throw new AuthenticationNotSupportedException(e);
+        } catch (NamingException e) {
+            // Assume some kind of communication problem.
+            throw new CommunicationException(e);
         }
-      }
-      finally
-      {
-        results.close();
-      }
-    } catch (NameNotFoundException e) {
-      // Fall through - entry not found.
-    }
-    return entryExists;
-  }
 
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public Collection<LdapName> listEntries(LdapName dn, String filter)
-      throws NamingException {
-    if (filter == null) {
-      filter = "(objectClass=*)";
+        return new JNDIDirContextAdaptor(ctx);
     }
 
-    SearchControls controls = new SearchControls();
-    controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+    /**
+     * Creates a new JNDI connection adaptor by performing a simple bind
+     * operation to the specified LDAP server.
+     *
+     * @param host
+     *            The host.
+     * @param port
+     *            The port.
+     * @param name
+     *            The LDAP bind DN.
+     * @param password
+     *            The LDAP bind password.
+     * @return Returns a new JNDI connection adaptor.
+     * @throws CommunicationException
+     *             If the client cannot contact the server due to an underlying
+     *             communication problem.
+     * @throws AuthenticationNotSupportedException
+     *             If the server does not support simple authentication.
+     * @throws AuthenticationException
+     *             If authentication failed for some reason, usually due to
+     *             invalid credentials.
+     */
+    public static JNDIDirContextAdaptor simpleSSLBind(String host, int port, String name, String password)
+            throws CommunicationException, AuthenticationNotSupportedException, AuthenticationException {
+        Hashtable<String, Object> env = new Hashtable<String, Object>();
+        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+        String hostname = ConnectionUtils.getHostNameForLdapUrl(host);
+        env.put(Context.PROVIDER_URL, "ldaps://" + hostname + ":" + port);
+        env.put(Context.SECURITY_PRINCIPAL, name);
+        env.put(Context.SECURITY_CREDENTIALS, password);
+        env.put(Context.SECURITY_AUTHENTICATION, "simple");
+        // Specify SSL
+        env.put(Context.SECURITY_PROTOCOL, "ssl");
+        env.put("java.naming.ldap.factory.socket", org.opends.admin.ads.util.TrustedSocketFactory.class.getName());
+        TrustedSocketFactory.setCurrentThreadTrustManager(new BlindTrustManager(), null);
+        DirContext ctx;
+        try {
+            ctx = new InitialLdapContext(env, null);
+        } catch (javax.naming.CommunicationException e) {
+            throw new CommunicationException(e);
+        } catch (javax.naming.AuthenticationException e) {
+            throw new AuthenticationException(e);
+        } catch (javax.naming.AuthenticationNotSupportedException e) {
+            throw new AuthenticationNotSupportedException(e);
+        } catch (NamingException e) {
+            // Assume some kind of communication problem.
+            throw new CommunicationException(e);
+        }
 
-    List<LdapName> children = new LinkedList<LdapName>();
-    NamingEnumeration<SearchResult> results = dirContext.search(dn, filter,
-        controls);
-    try
-    {
-      while (results.hasMore()) {
-        SearchResult sr = results.next();
-        LdapName child = new LdapName(dn.getRdns());
-        child.add(new Rdn(sr.getName()));
-        children.add(child);
-      }
-    }
-    finally
-    {
-      results.close();
+        return new JNDIDirContextAdaptor(ctx);
     }
 
-    return children;
-  }
+    // The JNDI connection context.
+    private final DirContext dirContext;
 
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void modifyEntry(LdapName dn, Attributes mods) throws NamingException {
-    ModificationItem[] modList = new ModificationItem[mods.size()];
-    NamingEnumeration<? extends Attribute> ne = mods.getAll();
-    for (int i = 0; ne.hasMore(); i++) {
-      ModificationItem modItem = new ModificationItem(
-          DirContext.REPLACE_ATTRIBUTE, ne.next());
-      modList[i] = modItem;
+    // Create a new JNDI connection adaptor using the provider JNDI
+    // DirContext.
+    private JNDIDirContextAdaptor(DirContext dirContext) {
+        this.dirContext = dirContext;
     }
-    dirContext.modifyAttributes(dn, modList);
-  }
 
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public Attributes readEntry(LdapName dn, Collection<String> attrIds)
-      throws NamingException {
-    String[] attrIdList = attrIds.toArray(new String[attrIds.size()]);
-    return dirContext.getAttributes(dn, attrIdList);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void unbind() {
-    try {
-      dirContext.close();
-    } catch (NamingException e) {
-      // nothing to do
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void createEntry(LdapName dn, Attributes attributes) throws NamingException {
+        dirContext.createSubcontext(dn, attributes).close();
     }
-  }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void deleteSubtree(LdapName dn) throws NamingException {
+        // Delete the children first.
+        for (LdapName child : listEntries(dn, null)) {
+            deleteSubtree(child);
+        }
+
+        // Delete the named entry.
+        dirContext.destroySubcontext(dn);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean entryExists(LdapName dn) throws NamingException {
+        boolean entryExists = false;
+        String filter = "(objectClass=*)";
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope(SearchControls.OBJECT_SCOPE);
+        controls.setReturningAttributes(new String[] { SchemaConstants.NO_ATTRIBUTES });
+        try {
+            NamingEnumeration<SearchResult> results = dirContext.search(dn, filter, controls);
+            try {
+                while (results.hasMore()) {
+                    // To avoid having a systematic abandon in the server.
+                    results.next();
+                    entryExists = true;
+                }
+            } finally {
+                results.close();
+            }
+        } catch (NameNotFoundException e) {
+            // Fall through - entry not found.
+        }
+        return entryExists;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Collection<LdapName> listEntries(LdapName dn, String filter) throws NamingException {
+        if (filter == null) {
+            filter = "(objectClass=*)";
+        }
+
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+
+        List<LdapName> children = new LinkedList<LdapName>();
+        NamingEnumeration<SearchResult> results = dirContext.search(dn, filter, controls);
+        try {
+            while (results.hasMore()) {
+                SearchResult sr = results.next();
+                LdapName child = new LdapName(dn.getRdns());
+                child.add(new Rdn(sr.getName()));
+                children.add(child);
+            }
+        } finally {
+            results.close();
+        }
+
+        return children;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void modifyEntry(LdapName dn, Attributes mods) throws NamingException {
+        ModificationItem[] modList = new ModificationItem[mods.size()];
+        NamingEnumeration<? extends Attribute> ne = mods.getAll();
+        for (int i = 0; ne.hasMore(); i++) {
+            ModificationItem modItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, ne.next());
+            modList[i] = modItem;
+        }
+        dirContext.modifyAttributes(dn, modList);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Attributes readEntry(LdapName dn, Collection<String> attrIds) throws NamingException {
+        String[] attrIdList = attrIds.toArray(new String[attrIds.size()]);
+        return dirContext.getAttributes(dn, attrIdList);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void unbind() {
+        try {
+            dirContext.close();
+        } catch (NamingException e) {
+            // nothing to do
+        }
+    }
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/server/ConfigAddListenerAdaptor.java b/opendj-admin/src/main/java/org/opends/server/admin/server/ConfigAddListenerAdaptor.java
index 3adf831..4d5d13b 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/server/ConfigAddListenerAdaptor.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/server/ConfigAddListenerAdaptor.java
@@ -207,8 +207,7 @@
   public boolean configAddIsAcceptable(ConfigEntry configEntry,
       LocalizableMessageBuilder unacceptableReason) {
     DN dn = configEntry.getDN();
-    AttributeValue av = dn.rdn().getAttributeValue(0);
-    String name = av.getValue().toString().trim();
+    String name = dn.rdn().getFirstAVA().getAttributeValue().toString().trim();
 
     try {
       ManagedObjectPath<?, ? extends S> childPath;
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java b/opendj-admin/src/main/java/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java
index 5b56f11..a7eeef8 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java
@@ -33,7 +33,6 @@
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.LocalizableMessageBuilder;
-import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.opends.server.admin.Configuration;
 import org.opends.server.admin.Constraint;
 import org.opends.server.admin.DecodingException;
@@ -187,8 +186,7 @@
      */
     public boolean configDeleteIsAcceptable(ConfigEntry configEntry, LocalizableMessageBuilder unacceptableReason) {
         DN dn = configEntry.getDN();
-        AttributeValue av = dn.rdn().getAttributeValue(0);
-        String name = av.getValue().toString().trim();
+        String name = dn.rdn().getFirstAVA().getAttributeValue().toString().trim();
 
         try {
             ManagedObjectPath<?, ? extends S> childPath;
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagedObject.java b/opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagedObject.java
index 678eb14..6cc8211 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagedObject.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagedObject.java
@@ -60,6 +60,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
 /**
  * A server-side managed object.
  *
@@ -246,8 +247,7 @@
                 ConfigChangeListenerAdaptor<?> adaptor = (ConfigChangeListenerAdaptor<?>) l;
                 ServerManagedObjectChangeListener<?> l2 = adaptor.getServerManagedObjectChangeListener();
                 if (l2 instanceof ServerManagedObjectChangeListenerAdaptor<?>) {
-                    ServerManagedObjectChangeListenerAdaptor<?> adaptor2 =
-                            (ServerManagedObjectChangeListenerAdaptor<?>) l2;
+                    ServerManagedObjectChangeListenerAdaptor<?> adaptor2 = (ServerManagedObjectChangeListenerAdaptor<?>) l2;
                     if (adaptor2.getConfigurationChangeListener() == listener) {
                         adaptor.finalizeChangeListener();
                         configEntry.deregisterChangeListener(adaptor);
@@ -797,6 +797,10 @@
         ConfigChangeListener adaptor = new ConfigChangeListenerAdaptor<S>(path, listener);
         configEntry.registerChangeListener(adaptor);
 
+        // TODO : go toward this
+        // Entry entry;
+        // configBackend.registerChangeListener(entry.getName(), adapter));
+
         // Change listener registration usually signifies that a managed
         // object has been accepted and added to the server configuration
         // during initialization post-add.
@@ -1030,8 +1034,7 @@
                         ConfigAddListenerAdaptor<?> adaptor = (ConfigAddListenerAdaptor<?>) l;
                         ServerManagedObjectAddListener<?> l2 = adaptor.getServerManagedObjectAddListener();
                         if (l2 instanceof ServerManagedObjectAddListenerAdaptor<?>) {
-                            ServerManagedObjectAddListenerAdaptor<?> adaptor2 =
-                                    (ServerManagedObjectAddListenerAdaptor<?>) l2;
+                            ServerManagedObjectAddListenerAdaptor<?> adaptor2 = (ServerManagedObjectAddListenerAdaptor<?>) l2;
                             if (adaptor2.getConfigurationAddListener() == listener) {
                                 configEntry.deregisterAddListener(adaptor);
                             }
@@ -1050,8 +1053,7 @@
     }
 
     // Deregister an add listener.
-    private <M extends Configuration> void deregisterAddListener(DN baseDN,
-            ServerManagedObjectAddListener<M> listener) {
+    private <M extends Configuration> void deregisterAddListener(DN baseDN, ServerManagedObjectAddListener<M> listener) {
         try {
             ConfigEntry configEntry = getListenerConfigEntry(baseDN);
             if (configEntry != null) {
@@ -1075,8 +1077,7 @@
     }
 
     // Deregister a delete listener.
-    private <M extends Configuration> void deregisterDeleteListener(DN baseDN,
-            ConfigurationDeleteListener<M> listener) {
+    private <M extends Configuration> void deregisterDeleteListener(DN baseDN, ConfigurationDeleteListener<M> listener) {
         try {
             ConfigEntry configEntry = getListenerConfigEntry(baseDN);
             if (configEntry != null) {
@@ -1085,8 +1086,7 @@
                         ConfigDeleteListenerAdaptor<?> adaptor = (ConfigDeleteListenerAdaptor<?>) l;
                         ServerManagedObjectDeleteListener<?> l2 = adaptor.getServerManagedObjectDeleteListener();
                         if (l2 instanceof ServerManagedObjectDeleteListenerAdaptor<?>) {
-                            ServerManagedObjectDeleteListenerAdaptor<?> adaptor2 =
-                                    (ServerManagedObjectDeleteListenerAdaptor<?>) l2;
+                            ServerManagedObjectDeleteListenerAdaptor<?> adaptor2 = (ServerManagedObjectDeleteListenerAdaptor<?>) l2;
                             if (adaptor2.getConfigurationDeleteListener() == listener) {
                                 configEntry.deregisterDeleteListener(adaptor);
                             }
@@ -1183,8 +1183,7 @@
 
     // Deregister a delayed listener with the nearest existing parent
     // entry to the provided base DN.
-    private <M extends Configuration> void deregisterDelayedAddListener(DN baseDN,
-            ConfigurationAddListener<M> listener)
+    private <M extends Configuration> void deregisterDelayedAddListener(DN baseDN, ConfigurationAddListener<M> listener)
             throws ConfigException {
         DN parentDN = baseDN.parent();
         int delayWrappers = 0;
@@ -1222,8 +1221,7 @@
                             ConfigAddListenerAdaptor<?> adaptor = (ConfigAddListenerAdaptor<?>) delayedListener;
                             ServerManagedObjectAddListener<?> l2 = adaptor.getServerManagedObjectAddListener();
                             if (l2 instanceof ServerManagedObjectAddListenerAdaptor<?>) {
-                                ServerManagedObjectAddListenerAdaptor<?> adaptor2 =
-                                        (ServerManagedObjectAddListenerAdaptor<?>) l2;
+                                ServerManagedObjectAddListenerAdaptor<?> adaptor2 = (ServerManagedObjectAddListenerAdaptor<?>) l2;
                                 if (adaptor2.getConfigurationAddListener() == listener) {
                                     relationEntry.deregisterAddListener(l);
                                 }
@@ -1276,8 +1274,7 @@
                             ConfigDeleteListenerAdaptor<?> adaptor = (ConfigDeleteListenerAdaptor<?>) delayedListener;
                             ServerManagedObjectDeleteListener<?> l2 = adaptor.getServerManagedObjectDeleteListener();
                             if (l2 instanceof ServerManagedObjectDeleteListenerAdaptor<?>) {
-                                ServerManagedObjectDeleteListenerAdaptor<?> adaptor2 =
-                                        (ServerManagedObjectDeleteListenerAdaptor<?>) l2;
+                                ServerManagedObjectDeleteListenerAdaptor<?> adaptor2 = (ServerManagedObjectDeleteListenerAdaptor<?>) l2;
                                 if (adaptor2.getConfigurationDeleteListener() == listener) {
                                     relationEntry.deregisterAddListener(l);
                                 }
diff --git a/opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagementContext.java b/opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagementContext.java
index f923f4d..7956f5f 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagementContext.java
+++ b/opendj-admin/src/main/java/org/opends/server/admin/server/ServerManagementContext.java
@@ -28,11 +28,13 @@
 package org.opends.server.admin.server;
 
 import static com.forgerock.opendj.ldap.AdminMessages.*;
+import static com.forgerock.opendj.util.StaticUtils.*;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -54,7 +56,6 @@
 import org.opends.server.admin.DefinitionResolver;
 import org.opends.server.admin.IllegalPropertyValueException;
 import org.opends.server.admin.IllegalPropertyValueStringException;
-import org.opends.server.admin.InstantiableRelationDefinition;
 import org.opends.server.admin.LDAPProfile;
 import org.opends.server.admin.ManagedObjectDefinition;
 import org.opends.server.admin.ManagedObjectPath;
@@ -68,7 +69,6 @@
 import org.opends.server.admin.Reference;
 import org.opends.server.admin.RelationDefinition;
 import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider;
-import org.opends.server.admin.SetRelationDefinition;
 import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
 import org.opends.server.admin.UnknownPropertyDefinitionException;
 import org.opends.server.admin.DefinitionDecodingException.Reason;
@@ -77,8 +77,13 @@
 import org.opends.server.core.DirectoryServer;
 import org.forgerock.opendj.admin.meta.RootCfgDefn;
 import org.forgerock.opendj.admin.server.RootCfg;
+import org.forgerock.opendj.ldap.Attribute;
+import org.forgerock.opendj.ldap.AttributeDescription;
 import org.forgerock.opendj.ldap.DN;
-import org.opends.server.types.DirectoryException;
+import org.forgerock.opendj.ldap.schema.AttributeType;
+import org.opends.server.util.DynamicConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Server management connection context.
@@ -173,9 +178,10 @@
         }
 
         // Find the default values for the next path/property.
-        private Collection<T> find(ManagedObjectPath<?, ?> p, PropertyDefinition<T> pd) throws DefaultBehaviorException {
-            nextPath = p;
-            nextProperty = pd;
+        private Collection<T> find(ManagedObjectPath<?, ?> path, PropertyDefinition<T> propertyDef)
+                throws DefaultBehaviorException {
+            nextPath = path;
+            nextProperty = propertyDef;
 
             Collection<T> values = nextProperty.getDefaultBehaviorProvider().accept(this, null);
 
@@ -183,8 +189,8 @@
                 throw exception;
             }
 
-            if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
-                throw new DefaultBehaviorException(pd, new PropertyIsSingleValuedException(pd));
+            if (values.size() > 1 && !propertyDef.hasOption(PropertyOption.MULTI_VALUED)) {
+                throw new DefaultBehaviorException(propertyDef, new PropertyIsSingleValuedException(propertyDef));
             }
 
             return values;
@@ -192,18 +198,19 @@
 
         // Get an inherited property value.
         @SuppressWarnings("unchecked")
-        private Collection<T> getInheritedProperty(ManagedObjectPath target, AbstractManagedObjectDefinition<?, ?> d,
-                String propertyName) throws DefaultBehaviorException {
+        private Collection<T> getInheritedProperty(ManagedObjectPath target,
+                AbstractManagedObjectDefinition<?, ?> definition, 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)) {
+            if (!supr.isParentOf(definition)) {
                 throw new DefaultBehaviorException(nextProperty, new DefinitionDecodingException(supr,
                         Reason.WRONG_TYPE_INFORMATION));
             }
 
             // Save the current property in case of recursion.
-            PropertyDefinition<T> pd1 = nextProperty;
+            PropertyDefinition<T> propDef1 = nextProperty;
 
             try {
                 // Get the actual managed object definition.
@@ -216,12 +223,12 @@
                 }
 
                 DefinitionResolver resolver = new MyDefinitionResolver(configEntry);
-                ManagedObjectDefinition<?, ?> mod = d.resolveManagedObjectDefinition(resolver);
+                ManagedObjectDefinition<?, ?> mod = definition.resolveManagedObjectDefinition(resolver);
 
-                PropertyDefinition<T> pd2;
+                PropertyDefinition<T> propDef2;
                 try {
-                    PropertyDefinition<?> pdTmp = mod.getPropertyDefinition(propertyName);
-                    pd2 = pd1.getClass().cast(pdTmp);
+                    PropertyDefinition<?> propDefTmp = mod.getPropertyDefinition(propertyName);
+                    propDef2 = propDef1.getClass().cast(propDefTmp);
                 } catch (IllegalArgumentException e) {
                     throw new PropertyNotFoundException(propertyName);
                 } catch (ClassCastException e) {
@@ -229,33 +236,33 @@
                     throw new PropertyNotFoundException(propertyName);
                 }
 
-                List<AttributeValue> values = getAttribute(mod, pd2, configEntry);
-                if (values.isEmpty()) {
-                    // Recursively retrieve this property's default values.
-                    Collection<T> tmp = find(target, pd2);
-                    Collection<T> pvalues = new ArrayList<T>(tmp.size());
-                    for (T value : tmp) {
-                        pd1.validateValue(value);
-                        pvalues.add(value);
+                Iterable<Attribute> attributes = getAttribute(mod, propDef2, configEntry);
+                if (attributes.iterator().hasNext()) {
+                    Collection<T> pvalues = new ArrayList<T>();
+                    for (Attribute attribute : attributes) {
+                        pvalues.add(ValueDecoder.decode(propDef1, attribute));
                     }
                     return pvalues;
                 } else {
-                    Collection<T> pvalues = new ArrayList<T>(values.size());
-                    for (AttributeValue value : values) {
-                        pvalues.add(ValueDecoder.decode(pd1, value));
+                    // Recursively retrieve this property's default values.
+                    Collection<T> tmp = find(target, propDef2);
+                    Collection<T> pvalues = new ArrayList<T>(tmp.size());
+                    for (T value : tmp) {
+                        propDef1.validateValue(value);
+                        pvalues.add(value);
                     }
                     return pvalues;
                 }
             } catch (DefinitionDecodingException e) {
-                throw new DefaultBehaviorException(pd1, e);
+                throw new DefaultBehaviorException(propDef1, e);
             } catch (PropertyNotFoundException e) {
-                throw new DefaultBehaviorException(pd1, e);
+                throw new DefaultBehaviorException(propDef1, e);
             } catch (IllegalPropertyValueException e) {
-                throw new DefaultBehaviorException(pd1, e);
+                throw new DefaultBehaviorException(propDef1, e);
             } catch (IllegalPropertyValueStringException e) {
-                throw new DefaultBehaviorException(pd1, e);
+                throw new DefaultBehaviorException(propDef1, e);
             } catch (ConfigException e) {
-                throw new DefaultBehaviorException(pd1, e);
+                throw new DefaultBehaviorException(propDef1, e);
             }
         }
     }
@@ -293,19 +300,19 @@
          *
          * @param <PD>
          *            The type of the property.
-         * @param pd
+         * @param propertyDef
          *            The property definition.
-         * @param value
+         * @param attribute
          *            The LDAP string representation.
          * @return Returns the decoded LDAP value.
          * @throws IllegalPropertyValueStringException
          *             If the property value could not be decoded because it was
          *             invalid.
          */
-        public static <PD> PD decode(PropertyDefinition<PD> pd, AttributeValue value)
+        public static <PD> PD decode(PropertyDefinition<PD> propertyDef, Attribute attribute)
                 throws IllegalPropertyValueStringException {
-            String s = value.getValue().toString();
-            return pd.castValue(pd.accept(new ValueDecoder(), s));
+            String value = attribute.firstValueAsString();
+            return propertyDef.castValue(propertyDef.accept(new ValueDecoder(), value));
         }
 
         // Prevent instantiation.
@@ -339,7 +346,9 @@
         }
     }
 
-    // Singleton instance.
+    private static final Logger debugLogger = LoggerFactory.getLogger(ServerManagementContext.class);
+
+    /** The singleton instance. **/
     private final static ServerManagementContext INSTANCE = new ServerManagementContext();
 
     /**
@@ -458,7 +467,7 @@
      *            The type of the property to be retrieved.
      * @param path
      *            The path of the managed object containing the property.
-     * @param pd
+     * @param propertyDef
      *            The property to be retrieved.
      * @return Returns the property's effective values, or an empty set if there
      *         are no values defined.
@@ -474,15 +483,15 @@
      */
     @SuppressWarnings("unchecked")
     public <C extends ConfigurationClient, S extends Configuration, PD> SortedSet<PD> getPropertyValues(
-            ManagedObjectPath<C, S> path, PropertyDefinition<PD> pd) throws IllegalArgumentException, ConfigException,
+            ManagedObjectPath<C, S> path, PropertyDefinition<PD> propertyDef) throws IllegalArgumentException, ConfigException,
             PropertyException {
         // Check that the requested property is from the definition
         // associated with the path.
-        AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition();
-        PropertyDefinition<?> tmp = d.getPropertyDefinition(pd.getName());
-        if (tmp != pd) {
-            throw new IllegalArgumentException("The property " + pd.getName() + " is not associated with a "
-                    + d.getName());
+        AbstractManagedObjectDefinition<C, S> definition = path.getManagedObjectDefinition();
+        PropertyDefinition<?> tmpPropertyDef = definition.getPropertyDefinition(propertyDef.getName());
+        if (tmpPropertyDef != propertyDef) {
+            throw new IllegalArgumentException("The property " + propertyDef.getName() + " is not associated with a "
+                    + definition.getName());
         }
 
         // Determine the exact type of managed object referenced by the
@@ -491,10 +500,10 @@
         ConfigEntry configEntry = getManagedObjectConfigEntry(dn);
 
         DefinitionResolver resolver = new MyDefinitionResolver(configEntry);
-        ManagedObjectDefinition<? extends C, ? extends S> mod;
+        ManagedObjectDefinition<? extends C, ? extends S> managedObjDef;
 
         try {
-            mod = d.resolveManagedObjectDefinition(resolver);
+            managedObjDef = definition.resolveManagedObjectDefinition(resolver);
         } catch (DefinitionDecodingException e) {
             throw ConfigExceptionFactory.getInstance().createDecodingExceptionAdaptor(dn, e);
         }
@@ -502,10 +511,10 @@
         // Make sure we use the correct property definition, the
         // provided one might have been overridden in the resolved
         // definition.
-        pd = (PropertyDefinition<PD>) mod.getPropertyDefinition(pd.getName());
+        propertyDef = (PropertyDefinition<PD>) managedObjDef.getPropertyDefinition(propertyDef.getName());
 
-        List<AttributeValue> values = getAttribute(mod, pd, configEntry);
-        return decodeProperty(path.asSubType(mod), pd, values, null);
+        Iterable<Attribute> attributes = getAttribute(managedObjDef, propertyDef, configEntry);
+        return decodeProperty(path.asSubType(managedObjDef), propertyDef, attributes, null);
     }
 
     /**
@@ -541,19 +550,19 @@
      *            relation definition refers to.
      * @param parent
      *            The path of the parent managed object.
-     * @param rd
-     *            The instantiable relation definition.
+     * @param relationDef
+     *            The 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.
      */
     public <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects(
-            ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd) throws IllegalArgumentException {
-        validateRelationDefinition(parent, rd);
+            ManagedObjectPath<?, ?> parent, RelationDefinition<C, S> relationDef) {
+        validateRelationDefinition(parent, relationDef);
 
         // Get the target entry.
-        DN targetDN = DNBuilder.create(parent, rd);
+        DN targetDN = DNBuilder.create(parent, relationDef);
         ConfigEntry configEntry;
         try {
             configEntry = DirectoryServer.getConfigEntry(targetDN);
@@ -566,59 +575,12 @@
         }
 
         // Retrieve the children.
-        Set<DN> children = configEntry.getChildren().keySet();
-        ArrayList<String> names = new ArrayList<String>(children.size());
+        Set<DN> children = configEntry.getChildren();
+        List<String> names = new ArrayList<String>(children.size());
         for (DN child : children) {
             // Assume that RDNs are single-valued and can be trimmed.
-            AttributeValue av = child.rdn().getAttributeValue(0);
-            names.add(av.getValue().toString().trim());
-        }
-
-        return names.toArray(new String[names.size()]);
-    }
-
-    /**
-     * 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.
-     */
-    public <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects(
-            ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd) throws IllegalArgumentException {
-        validateRelationDefinition(parent, rd);
-
-        // Get the target entry.
-        DN targetDN = DNBuilder.create(parent, rd);
-        ConfigEntry configEntry;
-        try {
-            configEntry = DirectoryServer.getConfigEntry(targetDN);
-        } catch (ConfigException e) {
-            return new String[0];
-        }
-
-        if (configEntry == null) {
-            return new String[0];
-        }
-
-        // Retrieve the children.
-        Set<DN> children = configEntry.getChildren().keySet();
-        ArrayList<String> names = new ArrayList<String>(children.size());
-        for (DN child : children) {
-            // Assume that RDNs are single-valued and can be trimmed.
-            AttributeValue av = child.rdn().getAttributeValue(0);
-            names.add(av.toString().trim());
+            String name = child.rdn().getFirstAVA().getAttributeValue().toString().trim();
+            names.add(name);
         }
 
         return names.toArray(new String[names.size()]);
@@ -710,11 +672,11 @@
         // Build the managed object's properties.
         List<PropertyException> exceptions = new LinkedList<PropertyException>();
         Map<PropertyDefinition<?>, SortedSet<?>> properties = new HashMap<PropertyDefinition<?>, SortedSet<?>>();
-        for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
-            List<AttributeValue> values = getAttribute(mod, pd, configEntry);
+        for (PropertyDefinition<?> propertyDef : mod.getAllPropertyDefinitions()) {
+            Iterable<Attribute> attributes = getAttribute(mod, propertyDef, configEntry);
             try {
-                SortedSet<?> pvalues = decodeProperty(path, pd, values, newConfigEntry);
-                properties.put(pd, pvalues);
+                SortedSet<?> pvalues = decodeProperty(path, propertyDef, attributes, newConfigEntry);
+                properties.put(propertyDef, pvalues);
             } catch (PropertyException e) {
                 exceptions.add(e);
             }
@@ -739,16 +701,17 @@
     }
 
     // Create a property using the provided string values.
-    private <T> SortedSet<T> decodeProperty(ManagedObjectPath<?, ?> path, PropertyDefinition<T> pd,
-            List<AttributeValue> values, ConfigEntry newConfigEntry) throws PropertyException {
+    private <T> SortedSet<T> decodeProperty(ManagedObjectPath<?, ?> path, PropertyDefinition<T> propertyDef,
+            Iterable<Attribute> attributes, ConfigEntry newConfigEntry) throws PropertyException {
         PropertyException exception = null;
-        SortedSet<T> pvalues = new TreeSet<T>(pd);
+        SortedSet<T> pvalues = new TreeSet<T>(propertyDef);
 
-        if (!values.isEmpty()) {
+        Iterator<Attribute> attributesIt = attributes.iterator();
+        if (attributesIt.hasNext()) {
             // The property has values defined for it.
-            for (AttributeValue value : values) {
+            for (Attribute attr : attributes) {
                 try {
-                    pvalues.add(ValueDecoder.decode(pd, value));
+                    pvalues.add(ValueDecoder.decode(propertyDef, attr));
                 } catch (IllegalPropertyValueStringException e) {
                     exception = e;
                 }
@@ -756,24 +719,24 @@
         } else {
             // No values defined so get the defaults.
             try {
-                pvalues.addAll(getDefaultValues(path, pd, newConfigEntry));
+                pvalues.addAll(getDefaultValues(path, propertyDef, newConfigEntry));
             } catch (DefaultBehaviorException e) {
                 exception = e;
             }
         }
 
-        if (pvalues.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
+        if (pvalues.size() > 1 && !propertyDef.hasOption(PropertyOption.MULTI_VALUED)) {
             // This exception takes precedence over previous exceptions.
-            exception = new PropertyIsSingleValuedException(pd);
+            exception = new PropertyIsSingleValuedException(propertyDef);
             T value = pvalues.first();
             pvalues.clear();
             pvalues.add(value);
         }
 
-        if (pvalues.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) {
+        if (pvalues.isEmpty() && propertyDef.hasOption(PropertyOption.MANDATORY)) {
             // The values maybe empty because of a previous exception.
             if (exception == null) {
-                exception = new PropertyIsMandatoryException(pd);
+                exception = new PropertyIsMandatoryException(propertyDef);
             }
         }
 
@@ -785,28 +748,14 @@
     }
 
     // Gets the attribute associated with a property from a ConfigEntry.
-    private List<AttributeValue> getAttribute(ManagedObjectDefinition<?, ?> d, PropertyDefinition<?> pd,
+    private Iterable<Attribute> getAttribute(ManagedObjectDefinition<?, ?> d, PropertyDefinition<?> pd,
             ConfigEntry configEntry) {
         // TODO: we create a default attribute type if it is
         // undefined. We should log a warning here if this is the case
         // since the attribute should have been defined.
         String attrID = LDAPProfile.getInstance().getAttributeName(d, pd);
         AttributeType type = DirectoryServer.getAttributeType(attrID, true);
-        AttributeValueDecoder<AttributeValue> decoder = new AttributeValueDecoder<AttributeValue>() {
-
-            public AttributeValue decode(AttributeValue value) throws DirectoryException {
-                return value;
-            }
-        };
-
-        List<AttributeValue> values = new LinkedList<AttributeValue>();
-        try {
-            configEntry.getEntry().getAttributeValues(type, decoder, values);
-        } catch (DirectoryException e) {
-            // Should not happen.
-            throw new RuntimeException(e);
-        }
-        return values;
+        return configEntry.getEntry().getAllAttributes(AttributeDescription.create(type));
     }
 
     // Get the default values for the specified property.
@@ -823,12 +772,10 @@
         try {
             configEntry = DirectoryServer.getConfigEntry(dn);
         } catch (ConfigException e) {
-            if (debugEnabled()) {
-                TRACER.debugCaught(DebugLogLevel.ERROR, e);
-            }
+            debugLogger.trace("Unable to perform post add", e);
 
             LocalizableMessage message = ERR_ADMIN_CANNOT_GET_MANAGED_OBJECT.get(String.valueOf(dn),
-                    stackTraceToSingleLineString(e));
+                    stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD));
             throw new ConfigException(message, e);
         }
 
diff --git a/opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/Aci.java b/opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/Aci.java
index 0cb5eb4..de1b5df 100644
--- a/opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/Aci.java
+++ b/opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/Aci.java
@@ -27,15 +27,21 @@
  */
 package org.opends.server.authorization.dseecompat;
 
+import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.DN;
+
 /**
  * The Aci class represents ACI strings.
  */
-public class Aci implements Comparable<Aci>
-{
+public class Aci implements Comparable<Aci> {
     // TODO : to complete when implementing Aci support.
 
     @Override
     public int compareTo(Aci o) {
         throw new RuntimeException("This class is not implemented");
     }
- }
+
+    public static Aci decode(ByteString valueOf, DN rootDN) throws AciException {
+        throw new RuntimeException("This class is not implemented");
+    }
+}
diff --git a/opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/AciException.java b/opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/AciException.java
new file mode 100644
index 0000000..9c637f6
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/authorization/dseecompat/AciException.java
@@ -0,0 +1,78 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2008 Sun Microsystems, Inc.
+ */
+package org.opends.server.authorization.dseecompat;
+import org.forgerock.i18n.LocalizableMessage;
+import org.opends.server.types.IdentifiedException;
+
+
+/**
+ * The AciException class defines an exception that may be thrown
+ * either during ACI syntax verification of an "aci" attribute type value
+ * or during evaluation of an LDAP operation using a set of applicable
+ * ACIs.
+ */
+public class AciException extends IdentifiedException {
+  /**
+   * The serial version identifier required to satisfy the compiler because this
+   * class extends <CODE>java.lang.Exception</CODE>, which implements the
+   * <CODE>java.io.Serializable</CODE> interface.  This value was generated
+   * using the <CODE>serialver</CODE> command-line utility included with the
+   * Java SDK.
+   */
+  private static final long serialVersionUID = -2763328522960628853L;
+
+    /**
+     * Constructs a new exception with <code>null</code> as its detail message.
+     * The cause is not initialized. Used to break out of a recursive bind rule
+     * decode and not print duplicate messages.
+     */
+    public AciException() {
+      super();
+    }
+
+    /**
+     * Creates a new ACI exception with the provided message.
+     *
+     * @param  message    The message to use for this ACI exception.
+     */
+    public AciException(LocalizableMessage message) {
+      super(message);
+    }
+
+    /**
+     * Creates a new ACI exception with the provided message and root
+     * cause.
+     *
+     * @param  message    The message that explains the problem that occurred.
+     * @param  cause      The exception that was caught to trigger this
+     *                    exception.
+     */
+    public AciException(LocalizableMessage message, Throwable cause) {
+      super(message, cause);
+    }
+
+}
diff --git a/opendj-admin/src/main/java/org/opends/server/config/ConfigEntry.java b/opendj-admin/src/main/java/org/opends/server/config/ConfigEntry.java
index a81424a..832668b 100644
--- a/opendj-admin/src/main/java/org/opends/server/config/ConfigEntry.java
+++ b/opendj-admin/src/main/java/org/opends/server/config/ConfigEntry.java
@@ -26,6 +26,7 @@
  */
 package org.opends.server.config;
 
+import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.forgerock.opendj.ldap.DN;
@@ -59,14 +60,17 @@
     /** The actual entry wrapped by this configuration entry. */
     private Entry entry;
 
+    private final ConfigurationRepository configRepository;
+
     /**
      * Creates a new config entry with the provided entry.
      *
      * @param entry
      *            The entry that will be encapsulated by this config entry.
      */
-    public ConfigEntry(Entry entry) {
+    public ConfigEntry(Entry entry, ConfigurationRepository configRepository) {
         this.entry = entry;
+        this.configRepository = configRepository;
         addListeners = new CopyOnWriteArrayList<ConfigAddListener>();
         changeListeners = new CopyOnWriteArrayList<ConfigChangeListener>();
         deleteListeners = new CopyOnWriteArrayList<ConfigDeleteListener>();
@@ -219,4 +223,13 @@
     public String toString() {
         return entry.getName().toNormalizedString();
     }
+
+    /**
+     * Retrieves the set of children associated with this configuration entry.
+     *
+     * @return  The set of children associated with this configuration entry.
+     */
+    public Set<DN> getChildren() {
+        return configRepository.getChildren(entry);
+    }
 }
diff --git a/opendj-admin/src/main/java/org/opends/server/config/ConfigurationRepository.java b/opendj-admin/src/main/java/org/opends/server/config/ConfigurationRepository.java
new file mode 100644
index 0000000..f6eb5cd
--- /dev/null
+++ b/opendj-admin/src/main/java/org/opends/server/config/ConfigurationRepository.java
@@ -0,0 +1,47 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2013 ForgeRock AS.
+ */
+package org.opends.server.config;
+
+import java.util.Set;
+
+import org.forgerock.opendj.ldap.DN;
+import org.forgerock.opendj.ldap.Entry;
+
+/**
+ * Provides the configuration elements.
+ */
+public interface ConfigurationRepository {
+
+    /**
+     * Returns the set of children of the provided entry.
+     *
+     * @param entry
+     *            The configuration entry.
+     * @return the set of children of the entry
+     */
+    Set<DN> getChildren(Entry entry);
+
+}
diff --git a/opendj-admin/src/main/resources/com/forgerock/opendj/ldap/admin.properties b/opendj-admin/src/main/resources/com/forgerock/opendj/ldap/admin.properties
index 0992c20..15d9a36 100644
--- a/opendj-admin/src/main/resources/com/forgerock/opendj/ldap/admin.properties
+++ b/opendj-admin/src/main/resources/com/forgerock/opendj/ldap/admin.properties
@@ -53,7 +53,7 @@
 ERR_ADMIN_CANNOT_OPEN_JAR_FILE_9=The Directory Server jar file %s in \
  directory %s cannot be loaded because an unexpected error occurred while \
  trying to open the file for reading:  %s
-MILD_ERR_ADMIN_NO_EXTENSIONS_DIR_12=The extensions directory %s does not \
+ERR_ADMIN_NO_EXTENSIONS_DIR_12=The extensions directory %s does not \
  exist, therefore no extensions will be loaded
 ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY_13=Unable to read the Directory \
  Server extensions because the extensions directory %s exists but is not a \
@@ -279,8 +279,7 @@
 ERR_ADMIN_CERTIFICATE_GENERATION_MISSING_FILES_136=The administration \
 connector self-signed certificate cannot be generated because the following \
 files are missing: %s
-SEVERE_WARN_ADMIN_SET_PERMISSIONS_FAILED_137=Failed to set permissions \
+WARN_ADMIN_SET_PERMISSIONS_FAILED_137=Failed to set permissions \
  on file %s
 ERR_ADMIN_MERGING_138=The registry information of the servers could not \
- be merged
-
+ be merged
\ No newline at end of file
diff --git a/opendj-admin/src/main/resources/com/forgerock/opendj/ldap/extension.properties b/opendj-admin/src/main/resources/com/forgerock/opendj/ldap/extension.properties
new file mode 100644
index 0000000..dcc339a
--- /dev/null
+++ b/opendj-admin/src/main/resources/com/forgerock/opendj/ldap/extension.properties
@@ -0,0 +1,1016 @@
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License").  You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at
+# trunk/opends/resource/legal-notices/OpenDS.LICENSE
+# or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at
+# trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+# add the following below this CDDL HEADER, with the fields enclosed
+# by brackets "[]" replaced with your own identifying information:
+#      Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#      Copyright 2006-2010 Sun Microsystems, Inc.
+#      Portions Copyright 2011-2013 ForgeRock AS
+
+#
+# Format string definitions
+#
+# Keys must be formatted as follows:
+#
+# [DESCRIPTION]_[ORDINAL]
+#
+# where:
+#
+# DESCRIPTION is an upper case string providing a hint as to the context of
+# the message in upper case with the underscore ('_') character serving as
+# word separator
+#
+# ORDINAL is an integer unique among other ordinals in this file
+#
+ERR_PWSCHEME_CANNOT_INITIALIZE_MESSAGE_DIGEST_1=An error occurred \
+ while attempting to initialize the message digest generator for the %s \
+ algorithm:  %s
+ERR_PWSCHEME_CANNOT_BASE64_DECODE_STORED_PASSWORD_2=An error occurred \
+ while attempting to base64-decode the password value %s:  %s
+ERR_PWSCHEME_NOT_REVERSIBLE_3=The %s password storage scheme is not \
+ reversible, so it is impossible to recover the plaintext version of an \
+ encoded password
+ERR_JMX_ALERT_HANDLER_CANNOT_REGISTER_4=An error occurred while trying \
+ to register the JMX alert handler with the MBean server:  %s
+ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD_5=An unexpected error occurred while \
+ attempting to encode a password using the storage scheme defined in class %s: \
+ %s
+ERR_CACHE_INVALID_INCLUDE_FILTER_6=The ds-cfg-include-filter \
+ attribute of configuration entry %s, which specifies a set of search filters \
+ that may be used to control which entries are included in the cache, has an \
+ invalid value of "%s":  %s
+ERR_CACHE_INVALID_EXCLUDE_FILTER_7=The ds-cfg-exclude-filter \
+ attribute of configuration entry %s, which specifies a set of search filters \
+ that may be used to control which entries are excluded from the cache, has an \
+ invalid value of "%s":  %s
+ERR_FIFOCACHE_CANNOT_INITIALIZE_8=A fatal error occurred while trying \
+ to initialize fifo entry cache:  %s
+ERR_SOFTREFCACHE_CANNOT_INITIALIZE_9=A fatal error occurred while \
+ trying to initialize soft reference entry cache:  %s
+NOTE_CACHE_PRELOAD_PROGRESS_START_10=Starting the entry cache preload for \
+ %s backend
+NOTE_CACHE_PRELOAD_PROGRESS_REPORT_11=The entry cache preload for %s backend \
+ has processed %d entries, %d MB free heap memory available
+NOTE_CACHE_PRELOAD_PROGRESS_DONE_12=The entry cache preload for %s backend \
+ is complete with the total of %d entries processed
+WARN_CACHE_PRELOAD_INTERRUPTED_13=The entry cache preload for %s \
+ backend has been interrupted
+WARN_CACHE_PRELOAD_BACKEND_FAILED_14=The entry cache preload is not \
+ supported by %s backend, and as a result no entries from this backend will \
+ be preloaded into the entry cache
+ERR_CACHE_PRELOAD_ENTRY_FAILED_15=Failed to preload %s entry into \
+ the entry cache:  %s
+ERR_EXTOP_PASSMOD_CANNOT_DECODE_REQUEST_33=An unexpected error occurred \
+ while attempting to decode the password modify extended request sequence:  %s
+ERR_EXTOP_PASSMOD_NO_AUTH_OR_USERID_34=The password modify extended \
+ request cannot be processed because it does not contain an authorization ID \
+ and the underlying connection is not authenticated
+ERR_EXTOP_PASSMOD_CANNOT_LOCK_USER_ENTRY_35=The password modify \
+ extended request cannot be processed because the server was unable to obtain \
+ a write lock on user entry %s after multiple attempts
+ERR_EXTOP_PASSMOD_CANNOT_DECODE_AUTHZ_DN_36=The password modify extended \
+ request cannot be processed because the server cannot decode "%s" as a valid \
+ DN for use in the authorization ID for the operation
+ERR_EXTOP_PASSMOD_INVALID_AUTHZID_STRING_37=The password modify extended \
+ request cannot be processed because it contained an invalid userIdentity \
+ field.  The provided userIdentity string was "%s"
+ERR_EXTOP_PASSMOD_NO_USER_ENTRY_BY_AUTHZID_38=The password modify \
+ extended request cannot be processed because it was not possible to identify \
+ the user entry to update based on the authorization DN of "%s"
+ERR_EXTOP_PASSMOD_INVALID_OLD_PASSWORD_41=The password modify extended \
+ operation cannot be processed because the current password provided for the \
+ user is invalid
+INFO_FILE_KEYMANAGER_DESCRIPTION_FILE_43=Path to the file \
+ containing the Directory Server keystore information.  Changes to this \
+ configuration attribute will take effect the next time that the key manager \
+ is accessed
+ERR_FILE_KEYMANAGER_NO_SUCH_FILE_45=The keystore file %s specified in \
+ attribute ds-cfg-key-store-file of configuration entry %s does  not exist
+ERR_FILE_KEYMANAGER_CANNOT_DETERMINE_FILE_46=An unexpected error \
+ occurred while trying to determine the value of configuration attribute \
+ ds-cfg-key-store-file in configuration entry %s:  %s
+ERR_FILE_KEYMANAGER_PIN_PROPERTY_NOT_SET_50=Java property %s which is \
+ specified in attribute ds-cfg-key-store-pin-property of configuration entry \
+ %s should contain the PIN needed to access the file-based key manager, but \
+ this property is not set
+ERR_FILE_KEYMANAGER_PIN_ENVAR_NOT_SET_53=Environment variable %s which \
+ is specified in attribute ds-cfg-key-store-pin-environment-variable of \
+ configuration entry %s should contain the PIN needed to access the file-based \
+ key manager, but this property is not set
+ERR_FILE_KEYMANAGER_PIN_NO_SUCH_FILE_56=File %s specified in attribute \
+ ds-cfg-key-store-pin-file of configuration entry %s should contain the PIN \
+ needed to access the file-based key manager, but this file does not exist
+ERR_FILE_KEYMANAGER_PIN_FILE_CANNOT_READ_57=An error occurred while \
+ trying to read the keystore PIN from file %s specified in configuration \
+ attribute ds-cfg-key-store-pin-file of configuration entry %s:  %s
+ERR_FILE_KEYMANAGER_PIN_FILE_EMPTY_58=File %s specified in attribute \
+ ds-cfg-key-store-pin-file of configuration entry %s should contain the PIN \
+ needed to access the file-based key manager, but this file is empty
+ERR_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_FROM_ATTR_60=An unexpected \
+ error occurred while trying to determine the value of configuration attribute \
+ ds-cfg-key-store-pin in configuration entry %s:  %s
+ERR_FILE_KEYMANAGER_CANNOT_LOAD_62=An error occurred while trying to \
+ load the keystore contents from file %s:  %s
+ERR_FILE_KEYMANAGER_INVALID_TYPE_63=The keystore type %s specified in \
+ attribute ds-cfg-key-store-type of configuration entry %s is not valid:  %s
+ERR_PKCS11_KEYMANAGER_PIN_PROPERTY_NOT_SET_68=Java property %s which \
+ is specified in attribute ds-cfg-key-store-pin-property of configuration \
+ entry %s should contain the PIN needed to access the PKCS#11 key manager, but \
+ this property is not set
+ERR_PKCS11_KEYMANAGER_PIN_ENVAR_NOT_SET_71=Environment variable %s \
+ which is specified in attribute ds-cfg-key-store-pin-environment-variable of \
+ configuration entry %s should contain the PIN needed to access the PKCS#11 \
+ key manager, but this property is not set
+ERR_PKCS11_KEYMANAGER_PIN_NO_SUCH_FILE_74=File %s specified in \
+ attribute ds-cfg-key-store-pin-file of configuration entry %s should contain \
+ the PIN needed to access the PKCS#11 key manager, but this file does not \
+ exist
+ERR_PKCS11_KEYMANAGER_PIN_FILE_CANNOT_READ_75=An error occurred while \
+ trying to read the keystore PIN from file %s specified in configuration \
+ attribute ds-cfg-key-store-pin-file of configuration entry %s:  %s
+ERR_PKCS11_KEYMANAGER_PIN_FILE_EMPTY_76=File %s specified in attribute \
+ ds-cfg-key-store-pin-file of configuration entry %s should contain the PIN \
+ needed to access the PKCS#11 key manager, but this file is empty
+ERR_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_FROM_ATTR_79=An unexpected \
+ error occurred while trying to determine the value of configuration attribute \
+ ds-cfg-key-store-pin in configuration entry %s:  %s
+ERR_PKCS11_KEYMANAGER_CANNOT_LOAD_81=An error occurred while trying to \
+ access the PKCS#11 key manager:  %s
+ERR_FILE_KEYMANAGER_CANNOT_CREATE_FACTORY_83=An error occurred while \
+ trying to create a key manager factory to access the contents of keystore \
+ file %s:  %s
+ERR_PKCS11_KEYMANAGER_CANNOT_CREATE_FACTORY_84=An error occurred while \
+ trying to create a key manager factory to access the contents of the PKCS#11 \
+ keystore:  %s
+ERR_FILE_TRUSTMANAGER_NO_SUCH_FILE_87=The trust store file %s \
+ specified in attribute ds-cfg-trust-store-file of configuration entry %s does \
+ not exist
+ERR_FILE_TRUSTMANAGER_CANNOT_DETERMINE_FILE_88=An unexpected error \
+ occurred while trying to determine the value of configuration attribute \
+ ds-cfg-trust-store-file in configuration entry %s:  %s
+ERR_FILE_TRUSTMANAGER_PIN_PROPERTY_NOT_SET_92=Java property %s which \
+ is specified in attribute ds-cfg-trust-store-pin-property of configuration \
+ entry %s should contain the PIN needed to access the file-based trust \
+ manager, but this property is not set
+ERR_FILE_TRUSTMANAGER_PIN_ENVAR_NOT_SET_95=Environment variable %s \
+ which is specified in attribute ds-cfg-trust-store-pin-environment-variable \
+ of configuration entry %s should contain the PIN needed to access the \
+ file-based trust manager, but this property is not set
+ERR_FILE_TRUSTMANAGER_PIN_NO_SUCH_FILE_98=File %s specified in \
+ attribute ds-cfg-trust-store-pin-file of configuration entry %s should \
+ contain the PIN needed to access the file-based trust manager, but this file \
+ does not exist
+ERR_FILE_TRUSTMANAGER_PIN_FILE_CANNOT_READ_99=An error occurred while \
+ trying to read the trust store PIN from file %s specified in configuration \
+ attribute ds-cfg-trust-store-pin-file of configuration entry %s:  %s
+ERR_FILE_TRUSTMANAGER_PIN_FILE_EMPTY_100=File %s specified in \
+ attribute ds-cfg-trust-store-pin-file of configuration entry %s should \
+ contain the PIN needed to access the file-based trust manager, but this file \
+ is empty
+ERR_FILE_TRUSTMANAGER_CANNOT_LOAD_104=An error occurred while trying \
+ to load the trust store contents from file %s:  %s
+ERR_FILE_TRUSTMANAGER_CANNOT_CREATE_FACTORY_105=An error occurred \
+ while trying to create a trust manager factory to access the contents of \
+ trust store file %s:  %s
+ERR_FILE_TRUSTMANAGER_INVALID_TYPE_106=The trust store type %s \
+ specified in attribute ds-cfg-trust-store-type of configuration entry %s is \
+ not valid:  %s
+ERR_SEDCM_NO_PEER_CERTIFICATE_118=Could not map the provided certificate \
+ chain to a user entry because no peer certificate was available
+ERR_SEDCM_PEER_CERT_NOT_X509_119=Could not map the provided certificate \
+ chain to a user because the peer certificate was not an X.509 certificate \
+ (peer certificate format was %s)
+ERR_SEDCM_CANNOT_DECODE_SUBJECT_AS_DN_120=Could not map the provided \
+ certificate chain to a user because the peer certificate subject "%s" could \
+ not be decoded as an LDAP DN:  %s
+ERR_SEDCM_CANNOT_GET_ENTRY_121=Could not map the provided certificate \
+ chain to a user because an error occurred while attempting to retrieve the \
+ user entry with DN "%s":  %s
+ERR_SEDCM_NO_USER_FOR_DN_122=Could not map the provided certificate \
+ chain to a user because no user entry exists with a DN of %s
+ERR_SASLEXTERNAL_NO_CLIENT_CONNECTION_123=The SASL EXTERNAL bind request \
+ could not be processed because the associated bind request does not have a \
+ reference to the client connection
+ERR_SASLEXTERNAL_NOT_LDAP_CLIENT_INSTANCE_124=The SASL EXTERNAL bind \
+request could not be processed because the associated client connection \
+instance is not an instance of LDAPClientConnection
+ERR_SASLEXTERNAL_NO_CLIENT_CERT_126=The SASL EXTERNAL bind request could \
+ not be processed because the client did not present a certificate chain \
+ during SSL/TLS negotiation
+ERR_SASLEXTERNAL_NO_MAPPING_127=The SASL EXTERNAL bind request failed \
+ because the certificate chain presented by the client during SSL/TLS \
+ negotiation could not be mapped to a user entry in the Directory Server
+ERR_STARTTLS_NO_CLIENT_CONNECTION_128=StartTLS cannot be used on this \
+ connection because the underlying client connection is not available
+ERR_STARTTLS_NOT_TLS_CAPABLE_129=StartTLS cannot be used on this client \
+ connection because this connection type is not capable of using StartTLS to \
+ protect its communication
+ERR_SASLEXTERNAL_NO_CERT_IN_ENTRY_137=Unable to authenticate via SASL \
+ EXTERNAL because the mapped user entry %s does not have any certificates with \
+ which to verify the presented peer certificate
+ERR_SASLEXTERNAL_PEER_CERT_NOT_FOUND_138=Unable to authenticate via SASL \
+ EXTERNAL because the mapped user entry %s did not contain the peer \
+ certificate presented by the client
+ERR_SASLEXTERNAL_CANNOT_VALIDATE_CERT_139=An error occurred while \
+ attempting to validate the peer certificate presented by the client with a \
+ certificate from the user's entry %s:  %s
+ERR_SASLPLAIN_NO_SASL_CREDENTIALS_147=SASL PLAIN authentication requires \
+ that SASL credentials be provided but none were included in the bind request
+ERR_SASLPLAIN_NO_NULLS_IN_CREDENTIALS_148=The SASL PLAIN bind request \
+ did not include any NULL characters.  NULL characters are required as \
+ delimiters between the authorization ID and authentication ID, and also \
+ between the authentication ID and the password
+ERR_SASLPLAIN_NO_SECOND_NULL_149=The SASL PLAIN bind request did not \
+ include a second NULL character in the credentials, which is required as a \
+ delimiter between the authentication ID and the password
+ERR_SASLPLAIN_ZERO_LENGTH_AUTHCID_150=The authentication ID contained in \
+ the SASL PLAIN bind request had a length of zero characters, which is not \
+ allowed.  SASL PLAIN authentication does not allow an empty string for use as \
+ the authentication ID
+ERR_SASLPLAIN_ZERO_LENGTH_PASSWORD_151=The password contained in the \
+ SASL PLAIN bind request had a length of zero characters, which is not \
+ allowed.  SASL PLAIN authentication does not allow an empty string for use as \
+ the password
+ERR_SASLPLAIN_CANNOT_DECODE_AUTHCID_AS_DN_152=An error occurred while \
+ attempting to decode the SASL PLAIN authentication ID "%s" because it \
+ appeared to contain a DN but DN decoding failed:  %s
+ERR_SASLPLAIN_AUTHCID_IS_NULL_DN_153=The authentication ID in the SASL \
+ PLAIN bind request appears to be an empty DN.  This is not allowed
+ERR_SASLPLAIN_CANNOT_GET_ENTRY_BY_DN_154=An error occurred while \
+ attempting to retrieve user entry %s as specified in the DN-based \
+ authentication ID of a SASL PLAIN bind request:  %s
+ERR_SASLPLAIN_NO_MATCHING_ENTRIES_157=The server was not able to find \
+ any user entries for the provided authentication ID of %s
+ERR_SASLPLAIN_INVALID_PASSWORD_160=The provided password is invalid
+INFO_SASLPLAIN_CANNOT_LOCK_ENTRY_163=The Directory Server was unable to \
+ obtain a read lock on user entry %s in order to retrieve that entry
+ERR_SEDCM_CANNOT_LOCK_ENTRY_164=The Directory Server was unable to \
+ obtain a read lock on user entry %s in order to retrieve that entry
+INFO_SASLANONYMOUS_TRACE_165=SASL ANONYMOUS bind operation (conn=%d, op=%d) \
+ provided trace information:  %s
+ERR_SASLCRAMMD5_CANNOT_GET_MESSAGE_DIGEST_166=An unexpected error \
+ occurred while attempting to obtain an MD5 digest engine for use by the \
+ CRAM-MD5 SASL handler:  %s
+ERR_SASLCRAMMD5_NO_STORED_CHALLENGE_172=The SASL CRAM-MD5 bind request \
+ contained SASL credentials but there is no stored challenge for this client \
+ connection.  The first CRAM-MD5 bind request in the two-stage process must \
+ not contain client SASL credentials
+ERR_SASLCRAMMD5_INVALID_STORED_CHALLENGE_173=The SASL CRAM-MD5 bind \
+ request contained SASL credentials, but the stored SASL state information for \
+ this client connection is not in an appropriate form for the challenge
+ERR_SASLCRAMMD5_NO_SPACE_IN_CREDENTIALS_174=The SASL CRAM-MD5 bind \
+ request from the client included SASL credentials but there was no space to \
+ separate the username from the authentication digest
+ERR_SASLCRAMMD5_INVALID_DIGEST_LENGTH_175=The SASL CRAM-MD5 bind request \
+ included SASL credentials, but the decoded digest string had an invalid \
+ length of %d bytes rather than the %d bytes expected for a hex representation \
+ of an MD5 digest
+ERR_SASLCRAMMD5_INVALID_DIGEST_CONTENT_176=The SASL CRAM-MD5 bind \
+ request included SASL credentials, but the decoded digest was not comprised \
+ of only hexadecimal digits:  %s
+ERR_SASLCRAMMD5_CANNOT_DECODE_USERNAME_AS_DN_177=An error occurred while \
+ attempting to decode the SASL CRAM-MD5 username "%s" because it appeared to \
+ contain a DN but DN decoding failed:  %s
+ERR_SASLCRAMMD5_USERNAME_IS_NULL_DN_178=The username in the SASL \
+ CRAM-MD5 bind request appears to be an empty DN.  This is not allowed
+INFO_SASLCRAMMD5_CANNOT_LOCK_ENTRY_179=The Directory Server was unable to \
+ obtain a read lock on user entry %s in order to retrieve that entry
+ERR_SASLCRAMMD5_CANNOT_GET_ENTRY_BY_DN_180=An error occurred while \
+ attempting to retrieve user entry %s as specified in the DN-based username of \
+ a SASL CRAM-MD5 bind request:  %s
+ERR_SASLCRAMMD5_NO_MATCHING_ENTRIES_184=The server was not able to find \
+ any user entries for the provided username of %s
+ERR_SASLCRAMMD5_INVALID_PASSWORD_188=The provided password is invalid
+ERR_SASLCRAMMD5_NO_REVERSIBLE_PASSWORDS_189=SASL CRAM-MD5 authentication \
+ is not possible for user %s because none of the passwords in the user entry \
+ are stored in a reversible form
+INFO_SASL_UNSUPPORTED_CALLBACK_192=An unsupported or unexpected callback was \
+ provided to the SASL server for use during %s authentication:  %s
+ERR_SASL_NO_CREDENTIALS_193=The client connection included \
+ %s state information, indicating that the client was in the process \
+ of performing a %s bind, but the bind request did not include any \
+ credentials
+ERR_SASL_CANNOT_GET_SERVER_FQDN_194=An unexpected error occurred \
+ while attempting to determine the value of the ds-cfg-server-fqdn attribute \
+ in configuration entry %s:  %s
+ ERR_SASL_CONTEXT_CREATE_ERROR_195=An unexpected error occurred while \
+ trying to create an %s context: %s
+ERR_SASL_CANNOT_DECODE_USERNAME_AS_DN_196=An error occurred \
+ while attempting to decode the SASL %s username "%s" because it \
+ appeared to contain a DN but DN decoding failed:  %s
+ERR_SASL_USERNAME_IS_NULL_DN_197=The username in the SASL \
+ %s bind request appears to be an empty DN.  This is not allowed
+INFO_SASL_CANNOT_LOCK_ENTRY_198=The Directory Server was unable to \
+ obtain a read lock on user entry %s in order to retrieve that entry
+ERR_SASL_CANNOT_GET_ENTRY_BY_DN_199=An error occurred while \
+ attempting to retrieve user entry %s as specified in the DN-based username of \
+ a SASL %s bind request:  %s
+ERR_SASL_ZERO_LENGTH_USERNAME_200=The username contained in the \
+ SASL %s bind request had a length of zero characters, which is not \
+ allowed.  %s authentication does not allow an empty string for use as \
+ the username
+ERR_SASL_NO_MATCHING_ENTRIES_201=The server was not able to \
+ find any user entries for the provided username of %s
+ERR_SASL_AUTHZID_INVALID_DN_202=The provided authorization ID \
+ %s contained an invalid DN:  %s
+ ERR_SASL_AUTHZID_NO_SUCH_ENTRY_203=The entry %s specified as \
+ the authorization identity does not exist
+ERR_SASL_AUTHZID_CANNOT_GET_ENTRY_204=The entry %s specified as \
+ the authorization identity could not be retrieved:  %s
+ERR_SASL_AUTHZID_NO_MAPPED_ENTRY_205=The server was unable to \
+ find any entry corresponding to authorization ID %s
+ERR_SASL_CANNOT_GET_REVERSIBLE_PASSWORDS_207=An error occurred \
+ while attempting to retrieve the clear-text password(s) for user %s in order \
+ to perform SASL %s authentication:  %s
+ERR_SASL_NO_REVERSIBLE_PASSWORDS_208=SASL %s \
+ authentication is not possible for user %s because none of the passwords in \
+ the user entry are stored in a reversible form
+ERR_SASL_PROTOCOL_ERROR_209=SASL %s protocol error: %s
+ERR_SASL_AUTHZID_INSUFFICIENT_PRIVILEGES_210=The authenticating \
+ user %s does not have sufficient privileges to assume a different \
+ authorization identity
+ERR_SASL_AUTHZID_INSUFFICIENT_ACCESS_211=The authenticating \
+ user %s does not have sufficient access to assume a different \
+ authorization identity
+ERR_SASL_AUTHENTRY_NO_MAPPED_ENTRY_212=The server was unable to \
+ find any entry corresponding to authentication ID %s
+ERR_SASLGSSAPI_KDC_REALM_NOT_DEFINED_213=The server was unable to \
+ because both the ds-cfg-kdc-address and ds-cfg-realm attributes must be \
+ defined or neither defined
+ERR_SASL_CANNOT_MAP_AUTHENTRY_214=An error occurred while \
+ attempting to map authorization ID %s to a user entry:  %s
+ERR_SASLGSSAPI_CANNOT_CREATE_JAAS_CONFIG_215=An error occurred while \
+ attempting to write a temporary JAAS configuration file for use during GSSAPI \
+ processing:  %s
+ERR_SASLGSSAPI_CANNOT_CREATE_LOGIN_CONTEXT_216=An error occurred while \
+ attempting to create the JAAS login context for GSSAPI authentication:  %s
+ERR_SASLGSSAPI_NO_CLIENT_CONNECTION_217=No client connection was \
+ available for use in processing the GSSAPI bind request
+INFO_GSSAPI_PRINCIPAL_NAME_218=GSSAPI mechanism using a principal name of: %s
+INFO_GSSAPI_SERVER_FQDN_219=GSSAPI SASL mechanism using a server fully \
+ qualified domain name of: %s
+INFO_DIGEST_MD5_REALM_220=DIGEST-MD5 SASL mechanism using a realm of: %s
+NOTE_DIGEST_MD5_SERVER_FQDN_221=DIGEST-MD5 SASL mechanism using a server \
+ fully qualified domain name of: %s
+ERR_EXTOP_WHOAMI_PROXYAUTH_INSUFFICIENT_PRIVILEGES_277=You do not have \
+ sufficient privileges to use the proxied authorization control
+ERR_EXACTMAP_MULTIPLE_MATCHING_ENTRIES_306=ID string %s mapped to \
+ multiple users
+ERR_EXACTMAP_INEFFICIENT_SEARCH_307=The internal search based on ID \
+ string %s could not be processed efficiently:  %s.  Check the server \
+ configuration to ensure that all associated backends are properly configured \
+ for these types of searches
+ERR_EXACTMAP_SEARCH_FAILED_308=An internal failure occurred while \
+ attempting to resolve ID string %s to a user entry:  %s
+ERR_SASLCRAMMD5_CANNOT_MAP_USERNAME_313=An error occurred while \
+ attempting to map username %s to a Directory Server entry:  %s
+ERR_SASLDIGESTMD5_CANNOT_MAP_USERNAME_319=An error occurred while \
+ attempting to map username %s to a Directory Server entry:  %s
+ERR_SASLPLAIN_CANNOT_MAP_USERNAME_325=An error occurred while attempting \
+ to map username %s to a Directory Server entry:  %s
+ERR_EXTOP_CANCEL_NO_REQUEST_VALUE_327=Unable to process the cancel \
+ request because the extended operation did not include a request value
+ERR_EXTOP_CANCEL_CANNOT_DECODE_REQUEST_VALUE_328=An error occurred while \
+ attempting to decode the value of the cancel extended request:  %s
+INFO_EXTOP_CANCEL_REASON_329=Processing on this operation was terminated as a \
+ result of receiving a cancel request (message ID %d)
+ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD_330=Password storage scheme \
+ %s does not support use with the authentication password attribute syntax
+ERR_PWLENGTHVALIDATOR_MIN_GREATER_THAN_MAX_335=The configured minimum \
+ password length of %d characters is greater than the configured maximum \
+ password length of %d
+ERR_PWLENGTHVALIDATOR_TOO_SHORT_336=The provided password is shorter \
+ than the minimum required length of %d characters
+ERR_PWLENGTHVALIDATOR_TOO_LONG_337=The provided password is longer than \
+ the maximum allowed length of %d characters
+ERR_RANDOMPWGEN_NO_CHARSETS_341=Configuration entry "%s" does not \
+ contain attribute ds-cfg-password-character-set which specifies the sets of \
+ characters that should be used when generating the password.  This is a \
+ required attribute
+ERR_RANDOMPWGEN_CHARSET_NAME_CONFLICT_342=Configuration entry "%s" \
+ contains multiple definitions for the %s character set
+ERR_RANDOMPWGEN_CANNOT_DETERMINE_CHARSETS_343=An error occurred while \
+ attempting to decode the value(s) of the configuration attribute \
+ ds-cfg-password-character-set, which is used to hold the character set(s) for \
+ use in generating the password:  %s
+ERR_RANDOMPWGEN_UNKNOWN_CHARSET_346=The password format string "%s" \
+ references an undefined character set "%s"
+ERR_RANDOMPWGEN_INVALID_PWFORMAT_347=The password format string "%s" \
+ contains an invalid syntax.  This value should be a comma-delimited sequence \
+ of elements, where each element is the name of a character set followed by a \
+ colon and the number of characters to choose at random from that character \
+ set
+ERR_RANDOMPWGEN_CANNOT_DETERMINE_PWFORMAT_348=An error occurred while \
+ attempting to decode the value for configuration attribute \
+ ds-cfg-password-format, which is used to specify the format for the generated \
+ passwords:  %s
+ERR_EXTOP_PASSMOD_CANNOT_GET_PW_POLICY_354=An error occurred while \
+ attempting to get the password policy for user %s:  %s
+ERR_EXTOP_PASSMOD_REQUIRE_CURRENT_PW_355=The current password must be \
+ provided for self password changes
+ERR_EXTOP_PASSMOD_SECURE_AUTH_REQUIRED_356=Password modify operations \
+ that supply the user's current password must be performed over a secure \
+ communication channel
+ERR_EXTOP_PASSMOD_USER_PW_CHANGES_NOT_ALLOWED_357=End users are not \
+ allowed to change their passwords
+ERR_EXTOP_PASSMOD_SECURE_CHANGES_REQUIRED_358=Password changes must be \
+ performed over a secure communication channel
+ERR_EXTOP_PASSMOD_IN_MIN_AGE_359=The password cannot be changed because \
+ the previous password change was too recent
+ERR_EXTOP_PASSMOD_PASSWORD_IS_EXPIRED_360=The password cannot be changed \
+ because it is expired
+ERR_EXTOP_PASSMOD_NO_PW_GENERATOR_361=No new password was provided, and \
+ no password generator has been defined that may be used to automatically \
+ create a new password
+ERR_EXTOP_PASSMOD_CANNOT_GENERATE_PW_362=An error occurred while \
+ attempting to create a new password using the password generator:  %s
+ERR_EXTOP_PASSMOD_PRE_ENCODED_NOT_ALLOWED_363=The password policy does \
+ not allow users to supply pre-encoded passwords
+ERR_EXTOP_PASSMOD_UNACCEPTABLE_PW_364=The provided new password failed \
+ the validation checks defined in the server:  %s
+ERR_EXTOP_PASSMOD_CANNOT_ENCODE_PASSWORD_365=Unable to encode the \
+ provided password using the default scheme(s):  %s
+ERR_EXTOP_PASSMOD_NO_SUCH_ID_MAPPER_368=The identity mapper with \
+ configuration entry DN %s as specified for use with the password modify \
+ extended operation defined in entry %s either does not exist or is not \
+ enabled.  The identity mapper is a required component, and the password \
+ modify extended operation will not be enabled
+ERR_EXTOP_PASSMOD_CANNOT_DETERMINE_ID_MAPPER_369=An error occurred while \
+ attempting to determine the identity mapper to use in conjunction with the \
+ password modify extended operation defined in configuration entry %s:  %s. \
+ The password modify extended operation will not be enabled for use in the \
+ server
+ERR_EXTOP_PASSMOD_CANNOT_MAP_USER_370=The provided authorization ID \
+ string "%s" could not be mapped to any user in the directory
+ERR_EXTOP_PASSMOD_ERROR_MAPPING_USER_371=An error occurred while \
+ attempting to map authorization ID string "%s" to a user entry:  %s
+NOTE_ERRORLOG_ACCTNOTHANDLER_NOTIFICATION_375=Account-Status-Notification \
+ type='%s' userdn='%s' id=%d msg='%s'
+
+ERR_SASLCRAMMD5_CANNOT_GET_REVERSIBLE_PASSWORDS_377=An error occurred \
+ while attempting to retrieve the clear-text password(s) for user %s in order \
+ to perform SASL CRAM-MD5 authentication:  %s
+ERR_SASLPLAIN_CANNOT_CHECK_PASSWORD_VALIDITY_378=An error occurred while \
+ attempting to verify the password for user %s during SASL PLAIN \
+ authentication:  %s
+WARN_EXTOP_PASSMOD_NOOP_380=The password modify operation was not \
+ actually performed in the Directory Server because the LDAP no-op control was \
+ present in the request
+ERR_EXTOP_PASSMOD_ACCOUNT_DISABLED_381=The user account has been \
+ administratively disabled
+ERR_EXTOP_PASSMOD_ACCOUNT_LOCKED_382=The user account is locked
+ERR_STATICMEMBERS_NO_SUCH_ENTRY_383=Unable to examine entry %s as a \
+ potential member of static group %s because that entry does not exist in the \
+ Directory Server
+ERR_STATICMEMBERS_CANNOT_GET_ENTRY_384=An error occurred while \
+ attempting to retrieve entry %s as a potential member of static group %s:  %s
+ERR_STATICGROUP_INVALID_OC_COMBINATION_385=Entry %s cannot be parsed as \
+ a valid static group because static groups are not allowed to have both the \
+ %s and %s object classes
+ERR_STATICGROUP_NO_VALID_OC_386=Entry %s cannot be parsed as a valid \
+ static group because it does not contain exactly one of the %s or the %s \
+ object classes
+ERR_STATICGROUP_CANNOT_DECODE_MEMBER_VALUE_AS_DN_387=Value %s for \
+ attribute %s in entry %s cannot be parsed as a valid DN:  %s.  It will be \
+ excluded from the set of group members
+ERR_STATICGROUP_ADD_MEMBER_ALREADY_EXISTS_388=Cannot add user %s as a \
+ new member of static group %s because that user is already in the member list \
+ for the group
+ERR_STATICGROUP_REMOVE_MEMBER_NO_SUCH_MEMBER_389=Cannot remove user %s \
+ as a member of static group %s because that user is not included in the \
+ member list for the group
+ERR_STATICGROUP_ADD_MEMBER_UPDATE_FAILED_390=Cannot add user %s as a new \
+ member of static group %s because an error occurred while attempting to \
+ perform an internal modification to update the group:  %s
+ERR_STATICGROUP_REMOVE_MEMBER_UPDATE_FAILED_391=Cannot remove user %s as \
+ a member of static group %s because an error occurred while attempting to \
+ perform an internal modification to update the group:  %s
+ERR_EXTOP_PASSMOD_INSUFFICIENT_PRIVILEGES_392=You do not have sufficient \
+ privileges to perform password reset operations
+ERR_SASLDIGESTMD5_EMPTY_AUTHZID_393=The provided authorization ID was \
+ empty, which is not allowed for DIGEST-MD5 authentication
+ERR_SASLPLAIN_AUTHZID_INVALID_DN_400=The provided authorization ID %s \
+ contained an invalid DN:  %s
+ERR_SASLPLAIN_AUTHZID_INSUFFICIENT_PRIVILEGES_401=The authenticating \
+ user %s does not have sufficient privileges to specify an alternate \
+ authorization ID
+ERR_SASLPLAIN_AUTHZID_NO_SUCH_ENTRY_402=The entry corresponding to \
+ authorization DN %s does not exist in the Directory Server
+ERR_SASLPLAIN_AUTHZID_CANNOT_GET_ENTRY_403=An error occurred while \
+ attempting to retrieve entry %s specified as the authorization ID:  %s
+ERR_SASLPLAIN_AUTHZID_NO_MAPPED_ENTRY_404=No entry corresponding to \
+ authorization ID %s was found in the server
+ERR_SASLPLAIN_AUTHZID_CANNOT_MAP_AUTHZID_405=An error occurred while \
+ attempting to map authorization ID %s to a user entry:  %s
+ERR_SDTUACM_NO_PEER_CERTIFICATE_417=Could not map the provided \
+ certificate chain to a user entry because no peer certificate was available
+ERR_SDTUACM_PEER_CERT_NOT_X509_418=Could not map the provided \
+ certificate chain to a user because the peer certificate was not an X.509 \
+ certificate (peer certificate format was %s)
+ERR_SDTUACM_MULTIPLE_MATCHING_ENTRIES_419=The certificate with subject \
+ %s could not be mapped to exactly one user.  It maps to both %s and %s
+ERR_SATUACM_INVALID_MAP_FORMAT_422=Configuration entry %s has value \
+ '%s' which violates the format required for attribute mappings.  The expected \
+ format is 'certattr:userattr'
+ERR_SATUACM_DUPLICATE_CERT_ATTR_423=Configuration entry %s contains \
+ multiple mappings for certificate attribute %s
+ERR_SATUACM_NO_SUCH_ATTR_424=Mapping %s in configuration entry %s \
+ references attribute %s which is not defined in the server schema
+ERR_SATUACM_DUPLICATE_USER_ATTR_425=Configuration entry %s contains \
+ multiple mappings for user attribute %s
+ERR_SATUACM_NO_PEER_CERTIFICATE_429=Could not map the provided \
+ certificate chain to a user entry because no peer certificate was available
+ERR_SATUACM_PEER_CERT_NOT_X509_430=Could not map the provided \
+ certificate chain to a user because the peer certificate was not an X.509 \
+ certificate (peer certificate format was %s)
+ERR_SATUACM_CANNOT_DECODE_SUBJECT_AS_DN_431=Unable to decode peer \
+ certificate subject %s as a DN:  %s
+ERR_SATUACM_NO_MAPPABLE_ATTRIBUTES_432=Peer certificate subject %s \
+ does not contain any attributes for which a mapping has been established
+ERR_SATUACM_MULTIPLE_MATCHING_ENTRIES_433=The certificate with subject \
+ %s could not be mapped to exactly one user.  It maps to both %s and %s
+ERR_FCM_NO_PEER_CERTIFICATE_443=Could not map the provided certificate \
+ chain to a user entry because no peer certificate was available
+ERR_FCM_PEER_CERT_NOT_X509_444=Could not map the provided certificate \
+ chain to a user because the peer certificate was not an X.509 certificate \
+ (peer certificate format was %s)
+ERR_FCM_CANNOT_CALCULATE_FINGERPRINT_445=An error occurred while \
+ attempting to calculate the fingerprint for the peer certificate with subject \
+ %s:  %s
+ERR_FCM_MULTIPLE_MATCHING_ENTRIES_446=The certificate with fingerprint \
+ %s could not be mapped to exactly one user.  It maps to both %s and %s
+ERR_DYNAMICGROUP_CANNOT_DECODE_MEMBERURL_447=Unable to decode value "%s" \
+ in entry "%s" as an LDAP URL:  %s
+ERR_DYNAMICGROUP_NESTING_NOT_SUPPORTED_448=Dynamic groups do not support \
+ nested groups
+ERR_DYNAMICGROUP_ALTERING_MEMBERS_NOT_SUPPORTED_449=Dynamic groups do \
+ not support explicitly altering their membership
+WARN_DYNAMICGROUP_NONEXISTENT_BASE_DN_450=Base DN %s specified in \
+ dynamic group %s does not exist in the server
+ERR_DYNAMICGROUP_INTERNAL_SEARCH_FAILED_451=An error occurred while \
+ attempting perform an internal search with base DN %s and filter %s to \
+ resolve the member list for dynamic group %s:  result code %s, error message \
+ %s
+ERR_DYNAMICGROUP_CANNOT_RETURN_ENTRY_452=The server encountered a \
+ timeout while attempting to add user %s to the member list for dynamic group \
+ %s
+ERR_PWDIFFERENCEVALIDATOR_TOO_SMALL_456=The provided password differs \
+ less than the minimum required difference of %d characters
+ERR_REPEATEDCHARS_VALIDATOR_TOO_MANY_CONSECUTIVE_457=The provided \
+ password contained too many instances of the same character appearing \
+ consecutively.  The maximum number of times the same character may appear \
+ consecutively in a password is %d
+ERR_UNIQUECHARS_VALIDATOR_NOT_ENOUGH_UNIQUE_CHARS_458=The provided \
+ password does not contain enough unique characters.  The minimum number of \
+ unique characters that may appear in a user password is %d
+ERR_VATTR_NOT_SEARCHABLE_459=The %s attribute is not \
+ searchable and should not be included in otherwise unindexed search filters
+ERR_DICTIONARY_VALIDATOR_PASSWORD_IN_DICTIONARY_460=The provided \
+ password contained a word from the server's dictionary
+ERR_DICTIONARY_VALIDATOR_NO_SUCH_FILE_461=The specified dictionary file \
+ %s does not exist
+ERR_DICTIONARY_VALIDATOR_CANNOT_READ_FILE_462=An error occurred while \
+ attempting to load the dictionary from file %s:  %s
+ERR_ATTRVALUE_VALIDATOR_PASSWORD_IN_ENTRY_463=The provided password was \
+ found in another attribute in the user entry
+ERR_CHARSET_VALIDATOR_ILLEGAL_CHARACTER_464=The provided password \
+ contained character '%s' which is not allowed for use in passwords
+ERR_CHARSET_VALIDATOR_TOO_FEW_CHARS_FROM_SET_465=The provided password \
+ did not contain enough characters from the character set '%s'.  The minimum \
+ number of characters from that set that must be present in user passwords is \
+ %d
+ERR_CHARSET_VALIDATOR_NO_SET_COLON_466=The provided character set \
+ definition '%s' is invalid because it does not contain a colon to separate \
+ the minimum count from the character set
+ERR_CHARSET_VALIDATOR_NO_SET_CHARS_467=The provided character set definition \
+ '%s' is invalid because the provided character set is empty
+ERR_CHARSET_VALIDATOR_INVALID_SET_COUNT_468=The provided character set \
+ definition '%s' is invalid because the value before the colon must be an \
+ integer greater or equal to zero
+ERR_CHARSET_VALIDATOR_DUPLICATE_CHAR_469=The provided character set \
+ definition '%s' is invalid because it contains character '%s' which has \
+ already been used
+ERR_VIRTUAL_STATIC_GROUP_MULTIPLE_TARGETS_470=The virtual static group \
+ defined in entry %s contains multiple target group DNs, but only one is \
+ allowed
+ERR_VIRTUAL_STATIC_GROUP_CANNOT_DECODE_TARGET_471=Unable to decode "%s" \
+ as the target DN for group %s:  %s
+ERR_VIRTUAL_STATIC_GROUP_NO_TARGET_472=The virtual static group defined \
+ in entry %s does not contain a target group definition
+ERR_VIRTUAL_STATIC_GROUP_NESTING_NOT_SUPPORTED_473=Virtual static groups \
+ do not support nesting
+ERR_VIRTUAL_STATIC_GROUP_NO_TARGET_GROUP_474=Target group %s referenced \
+ by virtual static group %s does not exist
+ERR_VIRTUAL_STATIC_GROUP_ALTERING_MEMBERS_NOT_SUPPORTED_475=Altering \
+ membership for virtual static group %s is not allowed
+ERR_VIRTUAL_STATIC_GROUP_TARGET_CANNOT_BE_VIRTUAL_476=Virtual static \
+ group %s references target group %s which is itself a virtual static group. \
+ One virtual static group is not allowed to reference another as its target \
+ group
+NOTE_FSCACHE_RESTORE_484=Staring persistent entry cache state restoration, \
+ this may take awhile
+NOTE_FSCACHE_SAVE_485=Making the entry cache state persistent, this may \
+ take awhile
+ERR_FSCACHE_CANNOT_INITIALIZE_486=A fatal error occurred while trying \
+ to initialize file system entry cache:  %s
+ERR_FSCACHE_CANNOT_LOAD_PERSISTENT_DATA_487=An error occurred while \
+ trying to load persistent cache. Persistent cache will be flushed now
+ERR_FSCACHE_CANNOT_STORE_PERSISTENT_DATA_488=An error occurred while \
+ trying to store persistent cache. Persistent cache will be flushed now
+ERR_FSCACHE_CANNOT_STORE_ENTRY_489=Unable to store new cache entry in \
+ the file system entry cache
+ERR_FSCACHE_CANNOT_RETRIEVE_ENTRY_490=Unable to retrieve an existing \
+ cache entry from the file system entry cache
+ERR_FSCACHE_CANNOT_SET_JE_MEMORY_PCT_491=Internal error occurred while \
+ trying to set the entry cache backend internal cache size as percentage. The \
+ previous or default value will be used instead
+ERR_FSCACHE_CANNOT_SET_JE_MEMORY_SIZE_492=Internal error occurred \
+ while trying to set the entry cache backend internal cache size in bytes. The \
+ previous or default value will be used instead
+ERR_FSCACHE_CANNOT_SET_JE_PROPERTIES_493=Internal error occurred \
+ while trying to set the entry cache backend Berkeley DB JE properties:  %s
+ERR_FSCACHE_HOMELESS_494=A fatal error occurred while trying to setup \
+ file system entry cache home. No suitable path can be found to host the cache \
+ home
+WARN_FSCACHE_SET_PERMISSIONS_FAILED_495=Unable to set file permissions \
+ for the file system entry cache backend database directory %s
+WARN_FSCACHE_OFFLINE_STATE_FAIL_496=%s backend current offline state \
+ does not match persistent cache last recorded offline state. All cached data \
+ for this backend is now discarded
+NOTE_FSCACHE_RESTORE_REPORT_497=Restored %d persistent cache entries into \
+ the entry cache
+NOTE_FSCACHE_SAVE_REPORT_498=Made persistent %d cache entries
+NOTE_FSCACHE_INDEX_NOT_FOUND_499=No previous persistent cache state can be \
+ found. Starting with an empty cache
+ERR_FSCACHE_INDEX_IMPAIRED_500=The persistent cache index is \
+ inconsistent or damaged. Persistent cache will be flushed now
+ERR_ENTRYUUID_VATTR_NOT_SEARCHABLE_501=The %s attribute is not \
+ searchable and should not be included in otherwise unindexed search filters
+ERR_PWPSTATE_EXTOP_NO_PRIVILEGE_502=You do not have sufficient \
+ privileges to use the password policy state extended operation
+ERR_PWPSTATE_EXTOP_NO_REQUEST_VALUE_503=The provided password policy \
+ state extended request did not include a request value
+ERR_PWPSTATE_EXTOP_DECODE_FAILURE_504=An unexpected error occurred \
+ while attempting to decode password policy state extended request value:  %s
+ERR_PWPSTATE_EXTOP_MULTIPLE_ENTRIES_505=Multiple entries were found \
+ with DN %s
+ERR_PWPSTATE_EXTOP_INVALID_OP_ENCODING_506=An unexpected error \
+ occurred while attempting to decode an operation from the password policy \
+ state extended request:  %s
+ERR_PWPSTATE_EXTOP_NO_DISABLED_VALUE_507=No value was provided for the \
+ password policy state operation intended to set the disabled state for the \
+ user.  Exactly one value (either 'true' or 'false') must be given
+ERR_PWPSTATE_EXTOP_BAD_DISABLED_VALUE_COUNT_508=Multiple values were \
+ provided for the password policy state operation intended to set the disabled \
+ state for the user.  Exactly one value (either 'true' or 'false') must be \
+ given
+ERR_PWPSTATE_EXTOP_BAD_DISABLED_VALUE_509=The value provided for the \
+ password policy state operation  intended to set the disabled state for the \
+ user was invalid.  The value must be either 'true' or 'false'
+ERR_PWPSTATE_EXTOP_BAD_ACCT_EXP_VALUE_COUNT_510=Multiple values were \
+ provided for the password policy state operation intended to set the account \
+ expiration time for the user.  Exactly one value must be given
+ERR_PWPSTATE_EXTOP_BAD_ACCT_EXP_VALUE_511=The value %s provided for \
+ the password policy state operation used to set the account expiration time \
+ was invalid:  %s.  The value should be specified using the generalized time \
+ format
+ERR_PWPSTATE_EXTOP_BAD_PWCHANGETIME_VALUE_COUNT_512=Multiple values \
+ were provided for the password policy state operation intended to set the \
+ password changed time for the user.  Exactly one value must be given
+ERR_PWPSTATE_EXTOP_BAD_PWCHANGETIME_VALUE_513=The value %s provided \
+ for the password policy state operation used to set the password changed time \
+ was invalid:  %s.  The value should be specified using the generalized time \
+ format
+ERR_PWPSTATE_EXTOP_BAD_PWWARNEDTIME_VALUE_COUNT_514=Multiple values \
+ were provided for the password policy state operation intended to set the \
+ password warned time for the user.  Exactly one value must be given
+ERR_PWPSTATE_EXTOP_BAD_PWWARNEDTIME_VALUE_515=The value %s provided \
+ for the password policy state operation used to set the password warned time \
+ was invalid:  %s.  The value should be specified using the generalized time \
+ format
+ERR_PWPSTATE_EXTOP_BAD_ADD_FAILURE_TIME_COUNT_516=Multiple values were \
+ provided for the password policy state operation intended to add an \
+ authentication failure time for the user.  Exactly one value must be given
+ERR_PWPSTATE_EXTOP_BAD_AUTH_FAILURE_TIME_517=The value %s provided for \
+ the password policy state operation used to update the authentication failure \
+ times was invalid:  %s.  The value should be specified using the generalized \
+ time format
+ERR_PWPSTATE_EXTOP_BAD_LAST_LOGIN_TIME_COUNT_518=Multiple values were \
+ provided for the password policy state operation intended to set the last \
+ login time for the user.  Exactly one value must be given
+ERR_PWPSTATE_EXTOP_BAD_LAST_LOGIN_TIME_519=The value %s provided for \
+ the password policy state operation used to set the last login time was \
+ invalid:  %s.  The value should be specified using the generalized time format
+ERR_PWPSTATE_EXTOP_NO_RESET_STATE_VALUE_520=No value was provided for \
+ the password policy state operation intended to set the reset state for the \
+ user.  Exactly one value (either 'true' or 'false') must be given
+ERR_PWPSTATE_EXTOP_BAD_RESET_STATE_VALUE_COUNT_521=Multiple values \
+ were provided for the password policy state operation intended to set the \
+ reset state for the user.  Exactly one value (either 'true' or 'false') must \
+ be given
+ERR_PWPSTATE_EXTOP_BAD_RESET_STATE_VALUE_522=The value provided for \
+ the password policy state operation  intended to set the reset state for the \
+ user was invalid.  The value must be either 'true' or 'false'
+ERR_PWPSTATE_EXTOP_BAD_ADD_GRACE_LOGIN_TIME_COUNT_523=Multiple values \
+ were provided for the password policy state operation intended to add a grace \
+ login use time for the user.  Exactly one value must be given
+ERR_PWPSTATE_EXTOP_BAD_GRACE_LOGIN_TIME_524=The value %s provided for \
+ the password policy state operation used to update the grace login use times \
+ was invalid:  %s.  The value should be specified using the generalized time \
+ format
+ERR_PWPSTATE_EXTOP_BAD_REQUIRED_CHANGE_TIME_COUNT_525=Multiple values \
+ were provided for the password policy state operation intended to set the \
+ required change time for the user.  Exactly one value must be given
+ERR_PWPSTATE_EXTOP_BAD_REQUIRED_CHANGE_TIME_526=The value %s provided \
+ for the password policy state operation used to set the required change time \
+ was invalid:  %s.  The value should be specified using the generalized time \
+ format
+ERR_PWPSTATE_EXTOP_UNKNOWN_OP_TYPE_527=The password policy state \
+ extended request included an operation with an invalid or unsupported \
+ operation type of %s
+WARN_EXTOP_PASSMOD_CANNOT_UPDATE_PWP_STATE_528=An error occurred while \
+ attempting to update the password policy state information for user %s as \
+ part of a password modify extended operation (result code='%s', error \
+ message='%s')
+ERR_EXTOP_PASSMOD_PW_IN_HISTORY_530=The provided new password was \
+ already contained in the password history
+ERR_SMTPALERTHANDLER_NO_SMTP_SERVERS_531=The Directory Server is not \
+ configured with any SMTP servers.  The SMTP alert handler cannot be used \
+ unless the Directory Server is configured with information about at least one \
+ SMTP server
+WARN_SMTPALERTHANDLER_ERROR_SENDING_MESSAGE_532=An error occurred when \
+ trying to send an e-mail message for administrative alert with type %s and \
+ message %s:  %s
+ERR_REGEXMAP_INVALID_MATCH_PATTERN_533=The provided match pattern "%s" \
+ could not be parsed as a regular expression:  %s
+ERR_REGEXMAP_MULTIPLE_MATCHING_ENTRIES_535=The processed ID string %s \
+ mapped to multiple users
+ERR_REGEXMAP_INEFFICIENT_SEARCH_536=The internal search based on \
+ processed ID string %s could not be processed efficiently:  %s.  Check the \
+ server configuration to ensure that all associated backends are properly \
+ configured for these types of searches
+ERR_REGEXMAP_SEARCH_FAILED_537=An internal failure occurred while \
+ attempting to resolve processed ID string %s to a user entry:  %s
+ERR_STATICGROUP_ADD_NESTED_GROUP_ALREADY_EXISTS_538=Cannot add group %s \
+ as a new nested group of static group %s because that group is already in the \
+ nested group list for the group
+ERR_STATICGROUP_REMOVE_NESTED_GROUP_NO_SUCH_GROUP_539=Cannot remove \
+ group %s as a nested group of static group %s because that group is not \
+ included in the nested group list for the group
+ERR_STATICGROUP_GROUP_INSTANCE_INVALID_540=Group instance with DN %s has \
+ been deleted and is no longer valid
+ERR_NUMSUBORDINATES_VATTR_NOT_SEARCHABLE_541=The %s attribute is not \
+ searchable and should not be included in otherwise unindexed search filters
+ERR_HASSUBORDINATES_VATTR_NOT_SEARCHABLE_542=The %s attribute is not \
+ searchable and should not be included in otherwise unindexed search filters
+ERR_SMTP_ASNH_NO_MAIL_SERVERS_CONFIGURED_543=The SMTP account status \
+ notification handler defined in configuration entry %s cannot be enabled \
+ unless the Directory Server is with information about one or more SMTP servers
+ERR_SMTP_ASNH_NO_RECIPIENTS_544=SMTP account status notification handler \
+ configuration entry '%s' does not include any email address attribute types \
+ or recipient addresses.  At least one of these must be provided
+ERR_SMTP_ASNH_SUBJECT_NO_COLON_545=Unable to parse message subject value \
+ '%s' from configuration entry '%s' because the value does not contain a \
+ colon to separate the notification type from the subject
+ERR_SMTP_ASNH_SUBJECT_INVALID_NOTIFICATION_TYPE_546=Unable to parse \
+ message subject value '%s' from configuration entry '%s' because '%s' is not \
+ a valid account status notification type
+ERR_SMTP_ASNH_SUBJECT_DUPLICATE_TYPE_547=The message subject definitions \
+ contained in configuration entry '%s' have multiple subjects defined for \
+ notification type %s
+ERR_SMTP_ASNH_TEMPLATE_NO_COLON_548=Unable to parse message template \
+ file path value '%s' from configuration entry '%s' because the value does \
+ not contain a colon to separate the notification type from the template file \
+ path
+ERR_SMTP_ASNH_TEMPLATE_INVALID_NOTIFICATION_TYPE_549=Unable to parse \
+ message template file path value '%s' from configuration entry '%s' because \
+ '%s' is not a valid account status notification type
+ERR_SMTP_ASNH_TEMPLATE_DUPLICATE_TYPE_550=The message template file path \
+ definitions contained in configuration entry '%s' have multiple template \
+ file paths defined for notification type %s
+ERR_SMTP_ASNH_TEMPLATE_NO_SUCH_FILE_551=The message template file '%s' \
+ referenced in configuration entry '%s' does not exist
+ERR_SMTP_ASNH_TEMPLATE_UNCLOSED_TOKEN_552=An unclosed token was found \
+ starting at column %d of line %d
+ERR_SMTP_ASNH_TEMPLATE_UNDEFINED_ATTR_TYPE_553=The \
+ notification-user-attr token starting at column %d of line %d references \
+ undefined attribute type %s
+ERR_SMTP_ASNH_TEMPLATE_UNDEFINED_PROPERTY_554=The \
+ notification-property token starting at column %d of line %d references \
+ undefined notification property %s
+ERR_SMTP_ASNH_TEMPLATE_UNRECOGNIZED_TOKEN_555=An unrecognized token %s \
+ was found at column %d of line %d
+ERR_SMTP_ASNH_TEMPLATE_CANNOT_PARSE_556=An error occurred while \
+ attempting to parse message template file '%s' referenced in configuration \
+ entry '%s':  %s
+INFO_SMTP_ASNH_DEFAULT_SUBJECT_557=Directory Account Status Notification
+ERR_SMTP_ASNH_CANNOT_SEND_MESSAGE_558=An error occurred while \
+ attempting to send an account status notification message for notification \
+ type %s for user entry %s:  %s
+ERR_PWSCHEME_CANNOT_ENCRYPT_559=An error occurred while trying to \
+ encrypt a value using password storage scheme %s:  %s
+ERR_PWSCHEME_CANNOT_DECRYPT_560=An error occurred while trying to \
+ decrypt a value using password storage scheme %s:  %s
+ERR_GET_SYMMETRIC_KEY_NO_VALUE_561=Cannot decode the provided \
+ symmetric key extended operation because it does not have a value
+ERR_GET_SYMMETRIC_KEY_ASN1_DECODE_EXCEPTION_563=Cannot decode the \
+ provided symmetric key extended request: %s
+ERR_GET_SYMMETRIC_KEY_DECODE_EXCEPTION_564=An unexpected error occurred \
+ while attempting to decode the symmetric key extended request sequence: %s
+ERR_EXACTMAP_ATTR_UNINDEXED_565=The exact match identity mapper \
+ defined in configuration entry %s references attribute type %s which is does \
+ not have an equality index defined in backend %s
+ERR_REGEXMAP_ATTR_UNINDEXED_566=The regular expression identity mapper \
+ defined in configuration entry %s references attribute type %s which is does \
+ not have an equality index defined in backend %s
+WARN_SATUACM_ATTR_UNINDEXED_568=The subject attribute to user attribute \
+ certificate mapper defined in configuration entry %s references attribute \
+ type %s which is does not have an equality index defined in backend %s
+NOTE_LOG_EXTENSION_INFORMATION_571=Loaded extension from file '%s' (build %s, \
+ revision %s)
+ERR_SASL_CREATE_SASL_SERVER_FAILED_572=Failed to create a SASL server \
+ for SASL mechanism %s using a server FQDN of %s
+ERR_SASL_GSSAPI_KEYTAB_INVALID_573=GSSAPI SASL mechanism handler initalization \
+failed because the keytab file %s does not exist
+INFO_GSSAPI_STARTED_574=The GSSAPI SASL mechanism handler initialization \
+was successful
+INFO_GSSAPI_STOPPED_575=The GSSAPI SASL mechanism handler has been stopped
+ERR_COLLECTIVEATTRIBUTESUBENTRIES_VATTR_NOT_SEARCHABLE_576=The %s \
+ attribute is not searchable and should not be included in otherwise \
+ unindexed search filters
+ERR_PASSWORDPOLICYSUBENTRY_VATTR_NOT_SEARCHABLE_577=The %s \
+ attribute is not searchable and should not be included in otherwise \
+ unindexed search filters
+ERR_PWSCHEME_INVALID_BASE64_DECODED_STORED_PASSWORD_578=The password \
+value %s has been base64-decoded but is too short to be valid
+ERR_CHARSET_VALIDATOR_MIN_CHAR_SETS_TOO_SMALL_579=The provided minimum \
+ required number of character sets '%d' is invalid because it must include \
+ all mandatory character sets and at least one optional character set
+ERR_CHARSET_VALIDATOR_MIN_CHAR_SETS_TOO_BIG_580=The provided minimum \
+ required number of character sets '%d' is invalid because it is greater than \
+ the total number of defined character sets
+ERR_CHARSET_VALIDATOR_TOO_FEW_OPTIONAL_CHAR_SETS_581=The provided \
+ password did not contain characters from at least %d of the following \
+ character sets or ranges: %s
+ERR_STATICMEMBERS_CANNOT_DECODE_DN_582=An error occurred while \
+ attempting to decode member's DN %s of static group %s:  %s
+ERR_SASL_ACCOUNT_NOT_LOCAL_583=SASL %s authentication \
+ is not supported for user %s because the account is not managed locally
+ERR_EXTOP_PASSMOD_ACCOUNT_NOT_LOCAL_584=Password modification is not \
+ supported for user %s because the account is not managed locally
+ERR_EXTOP_PWPSTATE_ACCOUNT_NOT_LOCAL_585=The password policy state \
+ extended operation is not supported for user %s because the account is not \
+ managed locally
+ERR_LDAP_PTA_MAPPING_ATTRIBUTE_NOT_FOUND_586=The user "%s" could not be \
+ authenticated using LDAP PTA policy "%s" because the following \
+ mapping attributes were not found in the user's entry: %s
+ERR_LDAP_PTA_MAPPED_SEARCH_TOO_MANY_CANDIDATES_587=The user "%s" could \
+ not be authenticated using LDAP PTA policy "%s" because the search of base \
+ DN "%s" returned more than one entry matching the filter "%s"
+ERR_LDAP_PTA_MAPPED_SEARCH_NO_CANDIDATES_588=The user "%s" could \
+ not be authenticated using LDAP PTA policy "%s" because the search did not \
+ return any entries matching the filter "%s"
+ERR_LDAP_PTA_MAPPED_SEARCH_FAILED_589=The user "%s" could \
+ not be authenticated using LDAP PTA policy "%s" because the search failed \
+ unexpectedly for the following reason: %s
+ERR_LDAP_PTA_MAPPED_BIND_FAILED_590=The user "%s" could \
+ not be authenticated using LDAP PTA policy "%s" because the bind failed \
+ unexpectedly for the following reason: %s
+ERR_LDAP_PTA_CONNECT_UNKNOWN_HOST_591=A connection could not be established \
+ to the remote LDAP server at %s:%d for LDAP PTA policy "%s" because the host name \
+ "%s" could not be resolved to an IP address
+ERR_LDAP_PTA_CONNECT_ERROR_592=A connection could not be established \
+ to the remote LDAP server at %s:%d for LDAP PTA policy "%s" because the connection \
+ was refused. This may indicate that the server is either offline or it is not \
+ listening on port %d
+ERR_LDAP_PTA_CONNECT_TIMEOUT_593=A connection could not be established \
+ to the remote LDAP server at %s:%d for LDAP PTA policy "%s" because the connection \
+ attempt timed out. This may indicate that the server is slow to respond, \
+ the network is slow, or that there is some other network problem
+ERR_LDAP_PTA_CONNECT_SSL_ERROR_594=A connection could not be established \
+ to the remote LDAP server at %s:%d for LDAP PTA policy "%s" because SSL \
+ negotiation failed for the following reason: %s
+ERR_LDAP_PTA_CONNECT_OTHER_ERROR_595=A connection could not be established \
+ to the remote LDAP server at %s:%d for LDAP PTA policy "%s" because an unexpected \
+ error occurred: %s
+ERR_LDAP_PTA_CONNECTION_OTHER_ERROR_596=The connection to the remote LDAP \
+ server at %s:%d for LDAP PTA policy "%s" has failed unexpectedly: %s
+ERR_LDAP_PTA_CONNECTION_CLOSED_597=The connection to the remote LDAP \
+ server at %s:%d for LDAP PTA policy "%s" has been closed unexpectedly
+ERR_LDAP_PTA_CONNECTION_TIMEOUT_598=The connection to the remote LDAP \
+ server at %s:%d for LDAP PTA policy "%s" has timed out and will be closed. This \
+ may indicate that the server is slow to respond, the network is slow, or \
+ that there is some other network problem
+ERR_LDAP_PTA_CONNECTION_DECODE_ERROR_599=The connection to the remote LDAP \
+ server at %s:%d for LDAP PTA policy "%s" has encountered a protocol error while \
+ decoding a response from the server and will be closed. The decoding error was: %s
+ERR_LDAP_PTA_CONNECTION_WRONG_RESPONSE_600=The connection to the remote LDAP \
+ server at %s:%d for LDAP PTA policy "%s" has received an unexpected response \
+ from the server and will be closed. The unexpected response message was: %s
+ERR_LDAP_PTA_CONNECTION_DISCONNECTING_601=The connection to the remote LDAP \
+ server at %s:%d for LDAP PTA policy "%s" has received a disconnect notification \
+ with response code %d (%s) and error message "%s"
+ERR_LDAP_PTA_CONNECTION_BIND_FAILED_602=The remote LDAP server at %s:%d \
+ for LDAP PTA policy "%s" has failed to authenticate user "%s", returning the \
+ response code %d (%s) and error message "%s"
+ERR_LDAP_PTA_CONNECTION_SEARCH_SIZE_LIMIT_603=The remote LDAP server at %s:%d \
+ for LDAP PTA policy "%s" returned multiple matching entries while searching \
+ "%s" using the filter "%s"
+ERR_LDAP_PTA_CONNECTION_SEARCH_NO_MATCHES_604=The remote LDAP server at %s:%d \
+ for LDAP PTA policy "%s" did not return any matching entries while searching \
+ "%s" using the filter "%s"
+ERR_LDAP_PTA_CONNECTION_SEARCH_FAILED_605=The remote LDAP server at %s:%d \
+ for LDAP PTA policy "%s" returned an error while searching "%s" using the \
+ filter "%s": response code %d (%s) and error message "%s"
+ERR_LDAP_PTA_INVALID_PORT_NUMBER_606=The configuration of LDAP PTA policy \
+ "%s" is invalid because the remote LDAP server address "%s" specifies a port \
+ number which is invalid. Port numbers should be greater than 0 and less than 65536
+ERR_LDAP_PTA_PWD_PROPERTY_NOT_SET_607=The configuration of LDAP PTA policy \
+ "%s" is invalid because the Java property %s which should contain the mapped \
+ search bind password is not set
+ERR_LDAP_PTA_PWD_ENVAR_NOT_SET_608=The configuration of LDAP PTA policy \
+ "%s" is invalid because the environment variable %s which should contain the mapped \
+ search bind password is not set
+ERR_LDAP_PTA_PWD_NO_SUCH_FILE_609=The configuration of LDAP PTA policy \
+ "%s" is invalid because the file %s which should contain the mapped search \
+ bind password does not exist
+ERR_LDAP_PTA_PWD_FILE_CANNOT_READ_610=The configuration of LDAP PTA policy \
+ "%s" is invalid because the file %s which should contain the mapped search \
+ bind password cannot be read for the following reason:  %s
+ERR_LDAP_PTA_PWD_FILE_EMPTY_611=The configuration of LDAP PTA policy \
+ "%s" is invalid because the file %s which should contain the mapped search \
+ bind password is empty
+ERR_LDAP_PTA_NO_PWD_613=The configuration of LDAP PTA policy \
+ "%s" is invalid because it does not specify the a means for obtaining the mapped \
+ search bind password
+ERR_ETAG_VATTR_NOT_SEARCHABLE_614=The %s attribute is not \
+ searchable and should not be included in otherwise unindexed search filters
+ERR_PWDEXPTIME_VATTR_NOT_SEARCHABLE_615=The %s attribute is not \
+ searchable and should not be included in otherwise unindexed search filters
+ERR_SATUACM_MULTIPLE_SEARCH_MATCHING_ENTRIES_616=The certificate with \
+ subject %s mapped to multiple users
+ERR_SATUACM_INEFFICIENT_SEARCH_617=The internal search based on \
+ the certificate with subject %s could not be processed efficiently:  %s.  \
+ Check the server configuration to ensure that all associated backends are \
+ properly configured for these types of searches
+ERR_SATUACM_SEARCH_FAILED_618=An internal failure occurred while \
+ attempting to map the certificate with subject %s to a user entry:  %s
+ERR_SDTUACM_MULTIPLE_SEARCH_MATCHING_ENTRIES_619=The certificate with \
+ subject %s mapped to multiple users
+ERR_SDTUACM_INEFFICIENT_SEARCH_620=The internal search based on \
+ the certificate with subject %s could not be processed efficiently:  %s.  \
+ Check the server configuration to ensure that all associated backends are \
+ properly configured for these types of searches
+ERR_SDTUACM_SEARCH_FAILED_621=An internal failure occurred while \
+ attempting to map the certificate with subject %s to a user entry:  %s
+ERR_FCM_MULTIPLE_SEARCH_MATCHING_ENTRIES_622=The certificate with \
+ fingerprint %s mapped to multiple users
+ERR_FCM_INEFFICIENT_SEARCH_623=The internal search based on \
+ the certificate with fingerprint %s could not be processed efficiently:  %s.  \
+ Check the server configuration to ensure that all associated backends are \
+ properly configured for these types of searches
+ERR_FCM_SEARCH_FAILED_624=An internal failure occurred while \
+ attempting to map the certificate with fingerprint %s to a user entry:  %s
+ERR_FIRSTCHANGENUMBER_VATTR_NOT_SEARCHABLE_625=The %s attribute is not \
+ searchable and should not be included in otherwise unindexed search filters
+ERR_LASTCHANGENUMBER_VATTR_NOT_SEARCHABLE_626=The %s attribute is not \
+ searchable and should not be included in otherwise unindexed search filters
+ERR_LASTCOOKIE_VATTR_NOT_SEARCHABLE_627=The %s attribute is not \
+ searchable and should not be included in otherwise unindexed search filters
+ERR_CHANGELOGBASEDN_VATTR_NOT_SEARCHABLE_628=The %s attribute is not \
+ searchable and should not be included in otherwise unindexed search filters
+ERR_CHARSET_VALIDATOR_TOO_FEW_CHARS_FROM_RANGE_629=The provided password \
+ did not contain enough characters from the character range '%s'.  The minimum \
+ number of characters from that range that must be present in user passwords \
+ is %d
+ERR_CHARSET_VALIDATOR_NO_RANGE_COLON_630=The provided character range \
+ definition  '%s' is invalid because it does not contain a colon to separate \
+ the minimum count from the character range
+ERR_CHARSET_VALIDATOR_NO_RANGE_CHARS_631=The provided character range \
+ definition  '%s' is invalid because it does not contain a colon to separate \
+ the minimum count from the character range
+ERR_CHARSET_VALIDATOR_INVALID_RANGE_COUNT_632=The provided character \
+ range definition '%s' is invalid because the value before the colon must be \
+ an integer greater or equal to zero
+ERR_CHARSET_VALIDATOR_UNSORTED_RANGE_633=The provided character range \
+ definition '%s' is invalid because the range '%s' is reversed
+ERR_CHARSET_VALIDATOR_MALFORMED_RANGE_634=The provided character range \
+ definition '%s' is invalid because the range '%s' is missing the minus
+ERR_CHARSET_VALIDATOR_SHORT_RANGE_635=The provided character range \
+ definition '%s' is invalid because the range '%s' is too short
diff --git a/opendj-admin/src/main/resources/stylesheets/admin.xsd b/opendj-admin/src/main/resources/stylesheets/admin.xsd
index 01bb283..a0c813b 100644
--- a/opendj-admin/src/main/resources/stylesheets/admin.xsd
+++ b/opendj-admin/src/main/resources/stylesheets/admin.xsd
@@ -5,6 +5,8 @@
   xmlns:tns="http://www.opends.org/admin">
   <xsd:import namespace="http://www.opends.org/admin-ldap"
     schemaLocation="admin-ldap.xsd" />
+  <xsd:import namespace="http://www.opends.org/admin-cli"
+    schemaLocation="admin-cli.xsd" />
   <xsd:import namespace="http://www.opends.org/admin-preprocessor"
     schemaLocation="admin-preprocessor.xsd" />
   <xsd:annotation>
diff --git a/opendj-admin/src/main/resources/stylesheets/catalog.xml b/opendj-admin/src/main/resources/stylesheets/catalog.xml
new file mode 100644
index 0000000..01f9af0
--- /dev/null
+++ b/opendj-admin/src/main/resources/stylesheets/catalog.xml
@@ -0,0 +1,5 @@
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+  <system systemId="admin-ldap.xsd" uri="admin-ldap.xsd" />
+  <system systemId="admin-cli.xsd" uri="admin-cli.xsd" />
+  <system systemId="admin-preprocessor.xsd" uri="admin-preprocessor.xsd" />
+</catalog>
\ No newline at end of file

--
Gitblit v1.10.0