From 19fb5731ffbe883fe8375ee9b785984c8ccf1880 Mon Sep 17 00:00:00 2001
From: coulbeck <coulbeck@localhost>
Date: Fri, 20 Apr 2007 22:23:11 +0000
Subject: [PATCH] Migrate the BackendConfigManager to the new configuration framework.

---
 opends/src/server/org/opends/server/core/BackendConfigManager.java                               | 1942 +++-----------
 opends/src/admin/defn/org/opends/server/admin/std/RootDSEBackendConfiguration.xml                |   61 
 opends/src/server/org/opends/server/admin/server/ConfigExceptionFactory.java                     |    2 
 opends/resource/admin/admin.xsd                                                                  |    2 
 opends/src/admin/defn/org/opends/server/admin/std/JEBackendConfiguration.xml                     |  865 ++++++
 opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml                          |   17 
 opends/src/server/org/opends/server/messages/CoreMessages.java                                   |    6 
 opends/tests/unit-tests-testng/resource/config-changes.ldif                                      |  164 
 opends/src/admin/defn/org/opends/server/admin/std/SchemaBackendConfiguration.xml                 |   87 
 opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestEntryContainer.java |   61 
 opends/src/admin/defn/org/opends/server/admin/std/BackupBackendConfiguration.xml                 |   47 
 opends/src/server/org/opends/server/backends/RootDSEBackend.java                                 |  413 --
 opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java      |    3 
 opends/src/server/org/opends/server/backends/SchemaBackend.java                                  |  401 --
 opends/resource/schema/02-config.ldif                                                            |   13 
 opends/src/server/org/opends/server/admin/server/ServerManagedObject.java                        |    3 
 opends/src/server/org/opends/server/backends/BackupBackend.java                                  |  221 -
 opends/src/server/org/opends/server/backends/jeb/ConfigurableEnvironment.java                    |  551 +---
 opends/src/server/org/opends/server/messages/UtilityMessages.java                                |    2 
 opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java  |    2 
 opends/resource/config/config.ldif                                                               |   35 
 opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java                   |    3 
 opends/src/server/org/opends/server/core/DirectoryServer.java                                    |   19 
 opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java              |    3 
 opends/src/admin/defn/org/opends/server/admin/std/TaskBackendConfiguration.xml                   |   75 
 opends/src/server/org/opends/server/backends/jeb/RootContainer.java                              |  203 
 opends/src/server/org/opends/server/backends/MonitorBackend.java                                 |  187 -
 opends/resource/admin/abbreviations.xsl                                                          |   10 
 opends/src/server/org/opends/server/backends/jeb/Config.java                                     |  535 +--
 opends/src/server/org/opends/server/messages/JebMessages.java                                    |  458 ---
 opends/src/server/org/opends/server/backends/jeb/BackendImpl.java                                |  317 --
 opends/src/admin/defn/org/opends/server/admin/std/BackendConfiguration.xml                       |  173 +
 opends/src/server/org/opends/server/messages/AdminMessages.java                                  |    2 
 opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java    |  113 
 opends/src/server/org/opends/server/backends/task/TaskBackend.java                               |  424 --
 35 files changed, 2,913 insertions(+), 4,507 deletions(-)

diff --git a/opends/resource/admin/abbreviations.xsl b/opends/resource/admin/abbreviations.xsl
index 90d72f0..88c5fe4 100644
--- a/opends/resource/admin/abbreviations.xsl
+++ b/opends/resource/admin/abbreviations.xsl
@@ -33,20 +33,20 @@
   <!--
     Determines whether or not the provided word is a known abbreviation or
     acronym.
-    
+
     @param value The word.
-    
+
     @return Returns the string "true" if the word is an abbreviation.
   -->
   <xsl:template name="is-abbreviation">
     <xsl:param name="value" select="/.." />
     <xsl:value-of
-      select="$value = 'aci' or $value = 'ip' or $value = 'ssl' 
+      select="$value = 'aci' or $value = 'ip' or $value = 'ssl'
               or $value = 'dn' or $value = 'rdn' or $value = 'jmx'
-              or $value = 'smtp' or $value = 'http'  or $value = 'https'  
+              or $value = 'smtp' or $value = 'http'  or $value = 'https'
               or $value = 'ldap' or $value = 'ldaps' or $value = 'ldif'
               or $value = 'jdbc' or $value = 'tcp' or $value = 'tls'
               or $value = 'pkcs11' or $value = 'sasl' or $value = 'gssapi'
-              or $value = 'md5' " />
+              or $value = 'md5' or $value = 'je' or $value = 'dse' " />
   </xsl:template>
 </xsl:stylesheet>
diff --git a/opends/resource/admin/admin.xsd b/opends/resource/admin/admin.xsd
index f9cef3d..a2c9104 100644
--- a/opends/resource/admin/admin.xsd
+++ b/opends/resource/admin/admin.xsd
@@ -965,7 +965,7 @@
             Sizes can be specified using both decimal and binary units.
             For example, "1kb" represents 1000 bytes, and "1kib"
             represents 1024 bytes. Values must always specify the unit
-            and can included a fractionaly part (e.g. 1.5mb). Both short
+            and can include a fractional part (e.g. 1.5mb). Both short
             and long unit names are supported (e.g. "kb" and
             "kilobytes").
           </xsd:documentation>
diff --git a/opends/resource/config/config.ldif b/opends/resource/config/config.ldif
index 9b6458b..64a8ea3 100644
--- a/opends/resource/config/config.ldif
+++ b/opends/resource/config/config.ldif
@@ -120,6 +120,21 @@
 ds-cfg-backend-import-thread-count: 8
 ds-cfg-backend-entries-compressed: false
 ds-cfg-backend-deadlock-retry-limit: 10
+ds-cfg-database-cache-percent: 10
+ds-cfg-database-cache-size: 0 megabytes
+ds-cfg-database-txn-no-sync: false
+ds-cfg-database-txn-write-no-sync: true
+ds-cfg-database-run-cleaner: true
+ds-cfg-database-cleaner-num-threads: 1
+ds-cfg-database-cleaner-min-utilization: 75
+ds-cfg-database-evictor-lru-only: true
+ds-cfg-database-evictor-nodes-per-scan: 10
+ds-cfg-database-log-file-max: 50 megabytes
+ds-cfg-database-logging-file-handler-on: true
+ds-cfg-database-logging-level: CONFIG
+ds-cfg-database-checkpointer-bytes-interval: 20 megabytes
+ds-cfg-database-checkpointer-wakeup-interval: 30 seconds
+ds-cfg-database-lock-num-lock-tables: 19
 
 dn: cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config
 objectClass: top
@@ -202,26 +217,6 @@
 ds-cfg-index-attribute: entryuuid
 ds-cfg-index-type: equality
 
-dn: cn=JE Database,ds-cfg-backend-id=userRoot,cn=Backends,cn=config
-objectClass: top
-objectClass: ds-cfg-je-database
-cn: JE Database
-ds-cfg-database-cache-percent: 10
-ds-cfg-database-cache-size: 0 megabytes
-ds-cfg-database-txn-no-sync: false
-ds-cfg-database-txn-write-no-sync: true
-ds-cfg-database-run-cleaner: true
-ds-cfg-database-cleaner-num-threads: 1
-ds-cfg-database-cleaner-min-utilization: 75
-ds-cfg-database-evictor-lru-only: true
-ds-cfg-database-evictor-nodes-per-scan: 10
-ds-cfg-database-log-file-max: 50 megabytes
-ds-cfg-database-logging-file-handler-on: true
-ds-cfg-database-logging-level: CONFIG
-ds-cfg-database-checkpointer-bytes-interval: 20 megabytes
-ds-cfg-database-checkpointer-wakeup-interval: 30 seconds
-ds-cfg-database-lock-num-lock-tables: 19
-
 dn: ds-cfg-backend-id=backup,cn=Backends,cn=config
 objectClass: top
 objectClass: ds-cfg-backend
diff --git a/opends/resource/schema/02-config.ldif b/opends/resource/schema/02-config.ldif
index 517ccbb..c5b4b8b 100644
--- a/opends/resource/schema/02-config.ldif
+++ b/opends/resource/schema/02-config.ldif
@@ -1210,7 +1210,16 @@
   ds-cfg-backend-import-temp-directory $ ds-cfg-backend-import-buffer-size $
   ds-cfg-backend-import-queue-size $ ds-cfg-backend-import-thread-count $
   ds-cfg-backend-entries-compressed $ ds-cfg-backend-deadlock-retry-limit $
-  ds-cfg-backend-import-pass-size $ ds-cfg-backend-mode )
+  ds-cfg-backend-import-pass-size $ ds-cfg-backend-mode $
+  ds-cfg-database-cache-percent $
+  ds-cfg-database-cache-size $ ds-cfg-database-txn-no-sync $
+  ds-cfg-database-txn-write-no-sync $ ds-cfg-database-run-cleaner $
+  ds-cfg-database-cleaner-min-utilization $ ds-cfg-database-evictor-lru-only $
+  ds-cfg-database-evictor-nodes-per-scan $ ds-cfg-database-log-file-max $
+  ds-cfg-database-logging-file-handler-on $ ds-cfg-database-logging-level $
+  ds-cfg-database-checkpointer-bytes-interval $
+  ds-cfg-database-checkpointer-wakeup-interval $
+  ds-cfg-database-lock-num-lock-tables $ ds-cfg-database-cleaner-num-threads )
   X-ORIGIN 'OpenDS Directory Server' )
 objectClasses: ( 1.3.6.1.4.1.26027.1.2.7 NAME 'ds-cfg-je-database'
   SUP top STRUCTURAL MAY ( cn $ ds-cfg-database-cache-percent $
@@ -1624,7 +1633,7 @@
   NAME 'ds-task-initialize-remote-replica' SUP ds-task
   MUST ( ds-task-initialize-domain-dn $ ds-task-initialize-replica-server-id )
   MAY ( ds-task-processed-entry-count $ ds-task-unprocessed-entry-count )
-  X-ORIGIN 'OpenDS Directory Server' )  
+  X-ORIGIN 'OpenDS Directory Server' )
 objectClasses: ( 1.3.6.1.4.1.26027.1.2.95
   NAME 'ds-cfg-dictionary-password-validator' SUP ds-cfg-password-validator
   STRUCTURAL MUST ( ds-cfg-dictionary-file $ ds-cfg-case-sensitive-validation $
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/BackendConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/BackendConfiguration.xml
new file mode 100644
index 0000000..92124f9
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/BackendConfiguration.xml
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<adm:managed-object
+     name="backend"
+     plural-name="backends"
+     package="org.opends.server.admin.std"
+     xmlns:adm="http://www.opends.org/admin"
+     xmlns:ldap="http://www.opends.org/admin-ldap">
+  <adm:synopsis>
+    <adm:user-friendly-plural-name/> are responsible for providing access
+    to the underlying data presented by the server. The data may be stored
+    locally (e.g., in an embedded database), remotely (e.g., in an
+    external system), or generated on the fly (e.g., calculated from other
+    information that is available).
+  </adm:synopsis>
+  <adm:profile name="ldap">
+    <ldap:object-class>
+      <ldap:oid>1.3.6.1.4.1.26027.1.2.5</ldap:oid>
+      <ldap:name>ds-cfg-backend</ldap:name>
+      <ldap:superior>top</ldap:superior>
+    </ldap:object-class>
+  </adm:profile>
+  <adm:property name="backend-enabled"
+    mandatory="true"
+    multi-valued="false">
+    <adm:synopsis>
+      Indicates whether the backend is enabled for use in the server.
+    </adm:synopsis>
+    <adm:description>
+      If a backend is not enabled, then its contents will not be accessible
+      when processing operations.
+    </adm:description>
+    <adm:syntax>
+      <adm:boolean />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.13</ldap:oid>
+        <ldap:name>ds-cfg-backend-enabled</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-class"
+    mandatory="true"
+    multi-valued="false">
+    <adm:synopsis>
+      The fully-qualified name of the Java class that provides the
+      backend implementation.
+    </adm:synopsis>
+    <adm:description>
+      The specified class must be a subclass of the
+      org.opends.server.api.Backend superclass.  The backend must be disabled
+      and re-enabled for changes to the handler class to take effect.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:component-restart/>
+    </adm:requires-admin-action>
+    <adm:syntax>
+      <adm:java-class>
+        <adm:instance-of>org.opends.server.api.Backend</adm:instance-of>
+      </adm:java-class>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.11</ldap:oid>
+        <ldap:name>ds-cfg-backend-class</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-id"
+    mandatory="true"
+    multi-valued="false">
+    <adm:synopsis>
+      Provides a name that will be used to identify the associated backend.
+    </adm:synopsis>
+    <adm:description>
+      The name must be unique among all backends in the server.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:other>
+        <adm:synopsis>
+          The backend ID may not be altered after the backend is created in
+          the server.
+        </adm:synopsis>
+      </adm:other>
+    </adm:requires-admin-action>
+    <adm:syntax>
+      <adm:string />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.14</ldap:oid>
+        <ldap:name>ds-cfg-backend-id</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-writability-mode"
+    mandatory="true"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the behavior that the backend should use when processing write
+      operations.
+    </adm:synopsis>
+    <adm:description>
+      A value of "enabled" will allow write operations to be
+      performed in that backend (if the requested operation is valid, the user
+      has permission to perform the operation, the backend supports that type
+      of write operation, and the global writability mode property is also
+      enabled).  A value of "disabled" will cause all write attempts to
+      fail, and a value of "internal-only" will cause external write attempts
+      to fail but will allow writes by replication and internal operations.
+    </adm:description>
+    <adm:syntax>
+      <adm:enumeration>
+        <adm:value name="enabled">
+          <adm:synopsis>
+            Allows write operations to be performed in that backend.
+          </adm:synopsis>
+        </adm:value>
+        <adm:value name="disabled">
+          <adm:synopsis>
+            Causes all write attempts to fail.
+          </adm:synopsis>
+        </adm:value>
+        <adm:value name="internal-only">
+          <adm:synopsis>
+            Causes external write attempts to fail but allows writes by
+            replication and internal operations.
+          </adm:synopsis>
+        </adm:value>
+      </adm:enumeration>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.162</ldap:oid>
+        <ldap:name>ds-cfg-backend-writability-mode</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-base-dn"
+    mandatory="true"
+    multi-valued="true">
+    <adm:synopsis>
+      Specifies the base DN(s) for the data that the backend will handle.
+    </adm:synopsis>
+    <adm:description>
+      A single backend may be responsible for one or more base DNs.  Note
+      that no two backends may have the same base DN, although one backend
+      may have a base DN that is below a base DN provided by another
+      backend (similar to the use of sub-suffixes in the Sun Java System
+      Directory Server).  Note that if any of the base DNs is subordinate
+      to a base DN for another backend, then all base DNs for that backend
+      must be subordinate to that same base DN.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:other>
+        <adm:synopsis>
+          No administrative action is required by default, although some action
+          may be required on a per-backend basis before the new base DN may
+          be used.
+        </adm:synopsis>
+      </adm:other>
+    </adm:requires-admin-action>
+    <adm:syntax>
+      <adm:dn />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.10</ldap:oid>
+        <ldap:name>ds-cfg-backend-base-dn</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/BackupBackendConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/BackupBackendConfiguration.xml
new file mode 100644
index 0000000..04fe55b
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/BackupBackendConfiguration.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<adm:managed-object name="backup-backend" plural-name="backup-backends"
+  package="org.opends.server.admin.std"
+  extends="backend"
+  xmlns:adm="http://www.opends.org/admin"
+  xmlns:ldap="http://www.opends.org/admin-ldap">
+  <adm:synopsis>
+    The backup backend provides read-only access to the set of backups that
+    are available for the OpenDS Directory Server.
+  </adm:synopsis>
+  <adm:description>
+    The backup backend is provided as a convenience feature that makes it
+    easier to determine what backups are available to be restored if necessary.
+    The org.opends.server.backends.BackupBackend class provides the
+    implementation for this backend.
+  </adm:description>
+  <adm:profile name="ldap">
+    <ldap:object-class>
+      <ldap:oid>1.3.6.1.4.1.26027.1.2.68</ldap:oid>
+      <ldap:name>ds-cfg-backup-backend</ldap:name>
+      <ldap:superior>ds-cfg-backend</ldap:superior>
+    </ldap:object-class>
+  </adm:profile>
+  <adm:property name="backup-directory"
+    mandatory="true"
+    multi-valued="true">
+    <adm:synopsis>
+      Specifies the path to a backup directory containing one or more backups
+      for a particular backend. It may be either an absolute path or one that
+      is relative to the base of the OpenDS Directory Server installation.
+    </adm:synopsis>
+    <adm:description>
+      This is a multivalued attribute, and each value may specify a different
+      backup directory if desired (e.g., one for each backend for which backups
+      are taken).
+    </adm:description>
+    <adm:syntax>
+      <adm:string />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.228</ldap:oid>
+        <ldap:name>ds-cfg-backup-directory</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/JEBackendConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/JEBackendConfiguration.xml
new file mode 100644
index 0000000..b0215c4
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/JEBackendConfiguration.xml
@@ -0,0 +1,865 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<adm:managed-object name="je-backend" plural-name="je-backends"
+  package="org.opends.server.admin.std"
+  extends="backend"
+  xmlns:adm="http://www.opends.org/admin"
+  xmlns:ldap="http://www.opends.org/admin-ldap">
+  <adm:synopsis>
+    The primary backend provided by the OpenDS Directory Server uses the
+    Berkeley DB Java Edition to store user-provided data in a local repository.
+    It is the traditional "directory server" backend and is similar to the
+    backends provided by the Sun Java System Directory Server.
+  </adm:synopsis>
+  <adm:description>
+    The <adm:user-friendly-name/> stores the entries in an encoded form and
+    also provides indexes that can be used to quickly locate target entries
+    based on different kinds of criteria.
+    The org.opends.server.backends.jeb.BackendImpl class provides the
+    implementation for this backend, and therefore should be used as the
+    value of the ds-cfg-backend-class-name property.
+  </adm:description>
+  <adm:profile name="ldap">
+    <ldap:object-class>
+      <ldap:oid>1.3.6.1.4.1.26027.1.2.6</ldap:oid>
+      <ldap:name>ds-cfg-je-backend</ldap:name>
+      <ldap:superior>ds-cfg-backend</ldap:superior>
+    </ldap:object-class>
+  </adm:profile>
+  <adm:property name="backend-deadlock-retry-limit"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the number of times that the server should retry an attempted
+      operation in the backend if a deadlock results from two concurrent
+      requests that interfere with each other in a conflicting manner.
+    </adm:synopsis>
+    <adm:description>
+      A value of "0" indicates no limit.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>10</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:integer  lower-limit="0" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.267</ldap:oid>
+        <ldap:name>ds-cfg-backend-deadlock-retry-limit</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-directory"
+    mandatory="true"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the path to the filesystem directory that will be used to hold
+      the Berkeley DB Java Edition database files containing the data for this
+      backend.
+    </adm:synopsis>
+    <adm:description>
+      The path may be either an absolute path or a path relative to the
+      directory containing the base of the OpenDS Directory Server installation.
+      The path may be any valid directory path in which the server has
+      appropriate permissions to read and write files and has sufficient space
+      to hold the database contents.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:component-restart/>
+    </adm:requires-admin-action>
+    <adm:syntax>
+      <adm:string />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.12</ldap:oid>
+        <ldap:name>ds-cfg-backend-directory</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-entries-compressed"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Indicates whether the backend should attempt to compress entries before
+      storing them in the database.
+    </adm:synopsis>
+    <adm:description>
+      Note that this property applies only to the entries themselves
+      and does not impact the index data.  Further, the effectiveness of the
+      compression will be based on the type of data contained in the entry.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:other>
+        <adm:synopsis>
+          Changes to this setting will only take effect for writes that occur
+          after the change is made.  It will not be retroactively applied to
+          existing data.
+        </adm:synopsis>
+      </adm:other>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>false</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:boolean />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.266</ldap:oid>
+        <ldap:name>ds-cfg-backend-entries-compressed</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-import-buffer-size"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the amount of memory that should be used as an internal
+      buffer for index information when processing an LDIF import.
+    </adm:synopsis>
+    <adm:requires-admin-action>
+      <adm:other>
+        <adm:synopsis>
+          No admin action required, although changes will not take effect for
+          any import that may already be in progress.
+        </adm:synopsis>
+      </adm:other>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>256mb</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:size lower-limit="10mb"/>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.263</ldap:oid>
+        <ldap:name>ds-cfg-backend-import-buffer-size</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-import-pass-size"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the maximum number of entries that should be imported in each
+      import pass.
+    </adm:synopsis>
+    <adm:description>
+      An import pass consists of the processing required to import a set of
+      entries as well as the index post-processing required to index those
+      entries.  A value of zero for this property indicates that all entries
+      should be processed in a single pass, which is the recommended
+      configuration for most deployments, although a non-zero value may be
+      required when importing a very large number of entries if the amount
+      of memory required for index post-processing exceeds the total amount
+      available to the server.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:other>
+        <adm:synopsis>
+          No admin action required, although changes will not take effect for
+          any import that may already be in progress.
+        </adm:synopsis>
+      </adm:other>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>0</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:integer  lower-limit="0"  upper-limit="2147483647" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.277</ldap:oid>
+        <ldap:name>ds-cfg-backend-import-pass-size</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-import-queue-size"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the size (in number of entries) of the queue that will be used
+      to hold the entries read during an LDIF import.
+    </adm:synopsis>
+    <adm:requires-admin-action>
+      <adm:other>
+        <adm:synopsis>
+          No admin action required, although changes will not take effect for
+          any import that may already be in progress.
+        </adm:synopsis>
+      </adm:other>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>100</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:integer  lower-limit="1" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.264</ldap:oid>
+        <ldap:name>ds-cfg-backend-import-queue-size</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-import-temp-directory"
+    mandatory="true"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the location of the directory that will be used for the
+      files used to hold temporary information that will be used during the
+      index post-processing phase of an LDIF import.
+    </adm:synopsis>
+    <adm:description>
+      The specified directory will only be used while an import is in progress
+      and the files created in this directory will be deleted as they are
+      processed. It may be an absolute path or one that is relative to the
+      instance root directory.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:other>
+        <adm:synopsis>
+          No admin action required, although changes will not take effect for
+          any import that may already be in progress.
+        </adm:synopsis>
+      </adm:other>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:undefined/>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:string />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.262</ldap:oid>
+        <ldap:name>ds-cfg-backend-import-temp-directory</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-import-thread-count"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the number of threads that will be used for concurrent
+      processing during an LDIF import.
+    </adm:synopsis>
+    <adm:description>
+      This should generally be a small multiple (e.g., 2x) of the number of CPUs
+      in the system for a traditional system, or equal to the number of CPU
+      strands for a CMT system.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:other>
+        <adm:synopsis>
+          No admin action required, although changes will not take effect for
+          any import that may already be in progress.
+        </adm:synopsis>
+      </adm:other>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>8</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:integer  lower-limit="1" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.265</ldap:oid>
+        <ldap:name>ds-cfg-backend-import-thread-count</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-index-entry-limit"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the maximum number of entries that will be allowed to
+      match a given index key before that particular index key is no longer
+      maintained (i.e., it is analogous to the ALL IDs threshold in the Sun
+      Java System Directory Server). Note that this is the default limit for
+      the backend, and it may be overridden on a per-attribute basis.
+    </adm:synopsis>
+    <adm:description>
+      Note that this is the default limit for the backend, and it may be
+      overridden on a per-attribute basis. A value of 0 means there is no limit.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:other>
+        <adm:synopsis>
+          No admin action is required, although if any index keys have already
+          reached this limit, indexes will need to be rebuilt before they will
+          be allowed to use the new limit.
+        </adm:synopsis>
+      </adm:other>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>4000</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:integer  lower-limit="0" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.15</ldap:oid>
+        <ldap:name>ds-cfg-backend-index-entry-limit</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-mode"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the permissions that should be applied to the directory
+      containing the server database files.  They should be expressed as
+      three-digit octal values, which is the traditional representation for
+      UNIX file permissions.
+    </adm:synopsis>
+    <adm:description>
+      The three digits represent the permissions that will be available for the
+      directory's owner, group members, and other users (in that order), and
+      each digit is the octal representation of the read, write, and execute
+      bits.
+      Note that this only impacts permissions on the database directory and
+      not on the files written into that directory. On UNIX systems, the
+      user's umask will control permissions given to the database files.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:server-restart/>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>700</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:string>
+        <adm:pattern>
+          <adm:regex>7[0-7][0-7]</adm:regex>
+          <adm:synopsis>
+            Any octal value between 700 and 777 (the owner must always have
+            read, write, and execute permissions on the directory).
+          </adm:synopsis>
+        </adm:pattern>
+      </adm:string>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.287</ldap:oid>
+        <ldap:name>ds-cfg-backend-mode</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-preload-time-limit"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the length of time that the backend will be allowed to
+      spend "pre-loading" data when it is initialized.
+    </adm:synopsis>
+    <adm:description>
+      The pre-load process may be used to pre-populate the database cache so
+      that it can be more quickly available when the server is processing
+      requests.  A duration of zero means there will be no pre-load.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>0s</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:duration base-unit="ms" lower-limit="0"/>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.261</ldap:oid>
+        <ldap:name>ds-cfg-backend-preload-time-limit</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="backend-subtree-delete-size-limit"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the maximum number of entries that may be deleted from the
+      backend when using the subtree delete control.
+    </adm:synopsis>
+    <adm:description>
+      If a subtree delete operation targets a subtree with more than this
+      number of entries, then multiple passes may be required to remove all
+      entries in that subtree.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>100000</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:integer  lower-limit="0" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.16</ldap:oid>
+        <ldap:name>ds-cfg-backend-subtree-delete-size-limit</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-cache-percent"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      The percentage of JVM memory to allocate to the database cache.
+    </adm:synopsis>
+    <adm:description>
+      Specifies the percentage of memory available to the JVM that should
+      be used for caching database contents. Note that this will only be used
+      if the value of the database-cache-size property is set to "0 MB".
+      Otherwise, the value of that property will be used instead to control
+      the cache size configuration.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>10</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:integer  lower-limit="1"  upper-limit="90" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.25</ldap:oid>
+        <ldap:name>ds-cfg-database-cache-percent</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-cache-size"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      The amount of JVM memory to allocate to the database cache.
+    </adm:synopsis>
+    <adm:description>
+      Specifies the amount of memory that should be used for caching database
+      contents. A value of "0 MB" indicates that the database-cache-percent
+      property should be used instead to specify the cache size.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>0 MB</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:size lower-limit="0 MB" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.27</ldap:oid>
+        <ldap:name>ds-cfg-database-cache-size</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-cleaner-min-utilization"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the minimum percentage of "live" data that the database cleaner
+      will attempt to keep in database log files.
+    </adm:synopsis>
+    <adm:description>
+      If the amount of live data in any database log file drops below this
+      percentage, then the cleaner will move the remaining live data in that
+      file to the end of the database and will delete the original file in
+      order to keep the database relatively compact.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>75</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:integer  lower-limit="0"  upper-limit="90" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.26</ldap:oid>
+        <ldap:name>ds-cfg-database-cleaner-min-utilization</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-run-cleaner"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      This indicates whether the database cleaner threads should be enabled.
+    </adm:synopsis>
+    <adm:description>
+      The cleaner threads will be used to periodically compact the database by
+      identifying database files with a low (i.e., less than the amount
+      specified by the database-cleaner-min-utilization property)
+      percentage of live data, moving the remaining live data to the end of the
+      log and deleting that file.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>true</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:boolean />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.28</ldap:oid>
+        <ldap:name>ds-cfg-database-run-cleaner</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-evictor-lru-only"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Indicates whether the database should evict existing data from the cache
+      based on an LRU policy (where the least recently used information will be
+      evicted first).
+    </adm:synopsis>
+    <adm:description>
+      If the value of this configuration property is set to "false", then
+      eviction will prefer to keep internal nodes of the underlying Btree in
+      the cache over leaf notes, even if the leaf nodes have been accessed
+      more recently, which may be a better configuration for databases in
+      which only a very small portion of the data is cached.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:component-restart/>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>true</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:boolean />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.268</ldap:oid>
+        <ldap:name>ds-cfg-database-evictor-lru-only</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-evictor-nodes-per-scan"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the number of Btree nodes that should be evicted from the
+      cache in a single pass if it is determined that it is necessary to
+      free existing data in order to make room for new information.
+    </adm:synopsis>
+    <adm:description>
+      Changes to this property do not take effect until the backend is
+      restarted.  It is recommended that you also change this property when you
+      set database-evictor-lru-only to false. This setting controls the number
+      of Btree nodes that are considered, or sampled, each time a node is
+      evicted. A setting of 100 often produces good results, but this may vary
+      from application to application. The larger the nodesPerScan, the more
+      accurate the algorithm. However, setting it too high is detrimental;
+      the need to consider larger numbers of nodes for each eviction may
+      delay the completion of a given database operation, which will impact
+      the response time of the application thread.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:component-restart/>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>10</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:integer  lower-limit="1"  upper-limit="1000" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.269</ldap:oid>
+        <ldap:name>ds-cfg-database-evictor-nodes-per-scan</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-log-file-max"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the maximum size that may be used for a database log file.
+    </adm:synopsis>
+    <adm:requires-admin-action>
+      <adm:component-restart/>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>50mb</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:size lower-limit="1mb" upper-limit="4gib"/>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.270</ldap:oid>
+        <ldap:name>ds-cfg-database-log-file-max</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-logging-file-handler-on"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Indicates whether the database should maintain a je.info file in the same
+      directory as the database log directory. This file will contain
+      information about the internal processing performed by the underlying
+      database.
+    </adm:synopsis>
+    <adm:requires-admin-action>
+      <adm:component-restart/>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>true</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:boolean />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.271</ldap:oid>
+        <ldap:name>ds-cfg-database-logging-file-handler-on</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-logging-level"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      This specifies the log level that should be used by the database when
+      it is writing information into the je.info file.
+    </adm:synopsis>
+    <adm:description>
+      The database trace logging level is (in increasing order of verbosity)
+      chosen from: OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:component-restart/>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>CONFIG</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:string />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.272</ldap:oid>
+        <ldap:name>ds-cfg-database-logging-level</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-checkpointer-bytes-interval"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the maximum number of bytes that may be written to the database
+      before it will be forced to perform a checkpoint.
+    </adm:synopsis>
+    <adm:description>
+      This can be used to bound the recovery time that may be required if the
+      database environment is opened without having been properly closed.
+      If this propertyis set to a non-zero value, the checkpointer wakeup
+      interval is not used.  To use time based checkpointing, set this
+      property to zero.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:server-restart/>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>20mb</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:size lower-limit="0b" upper-limit="9223372036854775807b"/>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.273</ldap:oid>
+        <ldap:name>ds-cfg-database-checkpointer-bytes-interval</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-checkpointer-wakeup-interval"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the maximum length of time that may pass between checkpoints.
+    </adm:synopsis>
+    <adm:description>
+      Note that this will only be used if the value of the checkpointer bytes
+      interval is zero.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:component-restart/>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>30s</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:duration base-unit="s" lower-limit="1" upper-limit="4294"/>
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.274</ldap:oid>
+        <ldap:name>ds-cfg-database-checkpointer-wakeup-interval</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-lock-num-lock-tables"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      This specifies the number of lock tables that should be used by the
+      underlying database.
+    </adm:synopsis>
+    <adm:description>
+      This can be particularly important to help improve scalability by
+      avoiding contention on systems with large numbers of CPUs. The value of
+      this configuration property should be set to a prime number that is less
+      than or equal to the number of worker threads configured for use in the
+      server.
+    </adm:description>
+    <adm:requires-admin-action>
+      <adm:component-restart/>
+    </adm:requires-admin-action>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>19</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:integer  lower-limit="1"  upper-limit="32767" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.275</ldap:oid>
+        <ldap:name>ds-cfg-database-lock-num-lock-tables</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-cleaner-num-threads"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Specifies the number of threads that the backend should maintain to
+      keep the database log files at or near the desired utilization.
+    </adm:synopsis>
+    <adm:description>
+      In environments with high write throughput, multiple cleaner threads may
+      be required to maintain the desired utilization.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>1</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:integer  lower-limit="1" />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.284</ldap:oid>
+        <ldap:name>ds-cfg-database-cleaner-num-threads</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-txn-no-sync"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Indicates whether database writes should be primarily written to an
+      internal buffer but not immediately written to disk.
+    </adm:synopsis>
+    <adm:description>
+      Setting the value of this configuration attribute to "true" may improve
+      write performance but could cause some number of the most recent changes
+      to be lost if the OpenDS Directory Server or the underlying JVM exits
+      abnormally, or if an OS or hardware failure occurs (a behavior similar
+      to running with transaction durability disabled in the Sun Java System
+      Directory Server).
+    </adm:description>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>false</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:boolean />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.29</ldap:oid>
+        <ldap:name>ds-cfg-database-txn-no-sync</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="database-txn-write-no-sync"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      Indicates whether the database should synchronously flush data as it is
+      written to disk.
+    </adm:synopsis>
+    <adm:description>
+      If this value is set to "false", then all data written to disk will be
+      synchronously flushed to persistent storage and thereby providing full
+      durability. If it is set to "true", then data may be cached for a period
+      of time by the underlying operating system before actually being written
+      to disk. This may improve performance, but could cause some number of
+      the most recent changes to be lost in the event of an underlying OS or
+      hardware failure (but not in the case that the OpenDS Directory Server
+      or the JVM exits abnormally).
+    </adm:description>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>true</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:boolean />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.30</ldap:oid>
+        <ldap:name>ds-cfg-database-txn-write-no-sync</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
index 7601a77..01da02b 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
@@ -93,5 +93,22 @@
       </ldap:rdn-sequence>
     </adm:profile>
   </adm:relation>
+  <adm:relation name="backend">
+    <adm:one-to-many />
+    <adm:profile name="ldap">
+      <ldap:rdn-sequence>
+        cn=Backends,cn=config
+      </ldap:rdn-sequence>
+      <ldap:naming-attribute>ds-cfg-backend-id</ldap:naming-attribute>
+    </adm:profile>
+  </adm:relation>
+  <adm:relation name="root-dse-backend">
+    <adm:one-to-one />
+    <adm:profile name="ldap">
+      <ldap:rdn-sequence>
+        cn=config
+      </ldap:rdn-sequence>
+    </adm:profile>
+  </adm:relation>
   <adm:product-name>OpenDS Directory Server</adm:product-name>
 </adm:root-managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/RootDSEBackendConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/RootDSEBackendConfiguration.xml
new file mode 100644
index 0000000..388e3a5
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/RootDSEBackendConfiguration.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<adm:managed-object name="root-dse-backend" plural-name="root-dse-backends"
+  package="org.opends.server.admin.std"
+  xmlns:adm="http://www.opends.org/admin"
+  xmlns:ldap="http://www.opends.org/admin-ldap">
+  <adm:synopsis>
+    This class defines a backend to hold the Directory Server root DSE.
+  </adm:synopsis>
+  <adm:description>
+    This is a special meta-backend that will dynamically generate the root DSE
+    entry for base-level searches, and will simply redirect to other backends
+    for operations in other scopes.
+  </adm:description>
+  <adm:profile name="ldap">
+    <ldap:object-class>
+      <ldap:oid>1.3.6.1.4.1.26027.1.2.42</ldap:oid>
+      <ldap:name>ds-cfg-root-dse</ldap:name>
+      <ldap:superior>top</ldap:superior>
+    </ldap:object-class>
+  </adm:profile>
+  <adm:property name="subordinate-base-dn"
+    mandatory="false"
+    multi-valued="true">
+    <adm:synopsis>
+      Specifies the set of base DNs that will be used for singleLevel,
+      wholeSubtree, and subordinateSubtree searches based at the root DSE.  If
+      this is not provided, then the set of all user-defined suffixes will be
+      used.
+    </adm:synopsis>
+    <adm:default-behavior>
+      <adm:undefined/>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:dn />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.122</ldap:oid>
+        <ldap:name>ds-cfg-subordinate-base-dn</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="show-all-attributes"
+    mandatory="true"
+    multi-valued="false">
+    <adm:synopsis>
+      Indicates whether all attributes in the root DSE should be treated like
+      user attributes (and therefore returned to clients by default)
+      regardless of the Directory Server schema configuration.
+    </adm:synopsis>
+    <adm:syntax>
+      <adm:boolean />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.141</ldap:oid>
+        <ldap:name>ds-cfg-show-all-attributes</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/SchemaBackendConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/SchemaBackendConfiguration.xml
new file mode 100644
index 0000000..5da6f04
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/SchemaBackendConfiguration.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<adm:managed-object name="schema-backend" plural-name="schema-backends"
+  package="org.opends.server.admin.std"
+  extends="backend"
+  xmlns:adm="http://www.opends.org/admin"
+  xmlns:ldap="http://www.opends.org/admin-ldap">
+  <adm:synopsis>
+    The schema backend provides access to the OpenDS Directory Server schema
+    information, including the attribute types, object classes, attribute
+    syntaxes, matching rules, matching rule uses, DIT content rules, and
+    DIT structure rules that it contains.
+  </adm:synopsis>
+  <adm:description>
+    The server will allow modify operations in this backend to alter the server
+    schema definitions. The org.opends.server.backends.SchemaBackend class
+    provides the implementation for this backend.
+    The configuration entry for this backend is based on the
+    ds-cfg-schema-backend structural object class. Note that any attribute
+    types included in this entry that are not included in this object class
+    (or the parent ds-cfg-backend class) will appear directly in the schema
+    entry.
+  </adm:description>
+  <adm:profile name="ldap">
+    <ldap:object-class>
+      <ldap:oid>1.3.6.1.4.1.26027.1.2.9</ldap:oid>
+      <ldap:name>ds-cfg-schema-backend</ldap:name>
+      <ldap:superior>ds-cfg-backend</ldap:superior>
+    </ldap:object-class>
+  </adm:profile>
+  <adm:property name="schema-entry-dn"
+    mandatory="false"
+    multi-valued="true">
+    <adm:synopsis>
+      This defines the base DN(s) at which the schema information will be
+      published, in addition to the value included in the ds-cfg-backend-base-dn
+      configuration attribute.
+    </adm:synopsis>
+    <adm:description>
+      The value provided in the ds-cfg-backend-base-dn configuration attribute
+      is the only one that will appear in the subschemaSubentry operational
+      attribute of the server's root DSE (which is necessary because that is a
+      single-valued attribute) and as a virtual attribute in other entries,
+      but the ds-cfg-schema-entry-dn attribute may be used to make the schema
+      information available in other locations as well in case certain client
+      applications have been hard-coded to expect the schema to reside in a
+      specific location.
+    </adm:description>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>cn=schema</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:dn />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.113</ldap:oid>
+        <ldap:name>ds-cfg-schema-entry-dn</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="show-all-attributes"
+    mandatory="true"
+    multi-valued="false">
+    <adm:synopsis>
+      Indicates whether to treat all attributes in the schema entry as if they
+      were user attributes regardless of their configuration.
+    </adm:synopsis>
+    <adm:description>
+      This may provide compatibility with some applications that expect schema
+      attributes like attributeType and objectClasses to be included by default
+      even if they are not requested.  Note that the ldapSyntaxes attribute
+      will always be treated as operational in order to avoid problems with
+      attempts to modify the schema over protocol.
+    </adm:description>
+    <adm:syntax>
+      <adm:boolean />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.141</ldap:oid>
+        <ldap:name>ds-cfg-show-all-attributes</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/TaskBackendConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/TaskBackendConfiguration.xml
new file mode 100644
index 0000000..fd12d38
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/TaskBackendConfiguration.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<adm:managed-object name="task-backend" plural-name="task-backends"
+  package="org.opends.server.admin.std"
+  extends="backend"
+  xmlns:adm="http://www.opends.org/admin"
+  xmlns:ldap="http://www.opends.org/admin-ldap">
+  <adm:synopsis>
+    The task backend provides a mechanism for processing tasks in the
+    OpenDS Directory Server. Tasks are intended to provide access to certain
+    types of administrative functions in the server that may not otherwise be
+    convenient to perform remotely.
+  </adm:synopsis>
+  <adm:description>
+    Tasks that are currently available for use provide the ability to backup
+    and restore backends, to import and export LDIF files, and to stop and
+    restart the server. The details of the task to perform are held in an
+    entry that is added below the root of the task backend, and then the
+    task backend is responsible for decoding that task entry and ensuring
+    that it is processed as requested. Tasks may be invoked immediately,
+    but they may also be scheduled for execution at some future time.
+    It is also expected that task backend will be given the ability process
+    recurring tasks, which can be used to help ensure that maintenance
+    operations (e.g., backups) are performed automatically on a regular basis.
+    The org.opends.server.backends.task.TaskBackend class provides the entry
+    point for the task backend implementation.
+  </adm:description>
+  <adm:profile name="ldap">
+    <ldap:object-class>
+      <ldap:oid>1.3.6.1.4.1.26027.1.2.10</ldap:oid>
+      <ldap:name>ds-cfg-task-backend</ldap:name>
+      <ldap:superior>ds-cfg-backend</ldap:superior>
+    </ldap:object-class>
+  </adm:profile>
+  <adm:property name="task-backing-file"
+    mandatory="true"
+    multi-valued="false">
+    <adm:synopsis>
+      This specifies the path to the backing file for storing information about
+      the tasks configured in the server. It may be either an absolute path or
+      a path that is relative to the base of the OpenDS Directory Server
+      instance.
+    </adm:synopsis>
+    <adm:syntax>
+      <adm:string />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.97</ldap:oid>
+        <ldap:name>ds-cfg-task-backing-file</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+  <adm:property name="task-retention-time"
+    mandatory="false"
+    multi-valued="false">
+    <adm:synopsis>
+      This specifies the length of time that task entries should be retained
+      after processing on the associated task has been completed.
+    </adm:synopsis>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>24 hours</adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:syntax>
+      <adm:duration />
+    </adm:syntax>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:oid>1.3.6.1.4.1.26027.1.1.106</ldap:oid>
+        <ldap:name>ds-cfg-task-retention-time</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
+</adm:managed-object>
diff --git a/opends/src/server/org/opends/server/admin/server/ConfigExceptionFactory.java b/opends/src/server/org/opends/server/admin/server/ConfigExceptionFactory.java
index c8ab7ed..d9a0e7c 100644
--- a/opends/src/server/org/opends/server/admin/server/ConfigExceptionFactory.java
+++ b/opends/src/server/org/opends/server/admin/server/ConfigExceptionFactory.java
@@ -41,7 +41,7 @@
 /**
  * A utility class for converting admin exceptions to config exceptions.
  */
-final class ConfigExceptionFactory {
+public final class ConfigExceptionFactory {
 
   // The singleton instance.
   private static final ConfigExceptionFactory INSTANCE =
diff --git a/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java b/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
index 99ebc42..2347042 100644
--- a/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
+++ b/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
@@ -178,7 +178,8 @@
    *           If one or more of the managed object's properties could
    *           not be decoded.
    */
-  static <S extends Configuration> ServerManagedObject<? extends S> decode(
+  public static <S extends Configuration>
+  ServerManagedObject<? extends S> decode(
       ManagedObjectPath path,
       AbstractManagedObjectDefinition<?, S> definition,
       final ConfigEntry configEntry)
diff --git a/opends/src/server/org/opends/server/backends/BackupBackend.java b/opends/src/server/org/opends/server/backends/BackupBackend.java
index b0d888a..9ef282f 100644
--- a/opends/src/server/org/opends/server/backends/BackupBackend.java
+++ b/opends/src/server/org/opends/server/backends/BackupBackend.java
@@ -29,28 +29,18 @@
 
 
 import java.io.File;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 import org.opends.server.api.Backend;
-import org.opends.server.api.ConfigurableComponent;
-import org.opends.server.config.ConfigAttribute;
-import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.ConfigException;
-import org.opends.server.config.StringConfigAttribute;
+import org.opends.server.config.ConfigEntry;
 import org.opends.server.core.AddOperation;
 import org.opends.server.core.DeleteOperation;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.ModifyOperation;
 import org.opends.server.core.ModifyDNOperation;
 import org.opends.server.core.SearchOperation;
+import org.opends.server.core.BackendConfigManager;
 import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.schema.BooleanSyntax;
 import org.opends.server.schema.GeneralizedTimeSyntax;
@@ -82,7 +72,9 @@
 import static org.opends.server.messages.MessageHandler.*;
 import static org.opends.server.util.ServerConstants.*;
 import static org.opends.server.util.StaticUtils.*;
-
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.std.server.BackupBackendCfg;
+import org.opends.server.admin.std.meta.BackupBackendCfgDefn;
 
 
 /**
@@ -95,10 +87,10 @@
  */
 public class BackupBackend
        extends Backend
-       implements ConfigurableComponent
+       implements ConfigurationChangeListener<BackupBackendCfg>
 {
-  // The DN of the configuration entry for this backend.
-  private DN configEntryDN;
+  // The current configuration state.
+  private BackupBackendCfg currentConfig;
 
   // The DN for the base backup entry.
   private DN backupBaseDN;
@@ -135,20 +127,7 @@
 
 
   /**
-   * Initializes this backend based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this backend.
-   * @param  baseDNs      The set of base DNs that have been configured for this
-   *                      backend.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
-   *
-   * @throws  InitializationException  If a problem occurs during initialization
-   *                                   that is not related to the server
-   *                                   configuration.
+   * {@inheritDoc}
    */
   public void initializeBackend(ConfigEntry configEntry, DN[] baseDNs)
          throws ConfigException, InitializationException
@@ -162,7 +141,7 @@
       throw new ConfigException(msgID, message);
     }
 
-    configEntryDN = configEntry.getDN();
+    BackupBackendCfg cfg = getBackupBackendCfg(configEntry);
 
 
     // Create the set of base DNs that we will handle.  In this case, it's just
@@ -188,39 +167,11 @@
 
 
     // Determine the set of backup directories that we will use by default.
-    int msgID = MSGID_BACKUP_DESCRIPTION_BACKUP_DIR_LIST;
-    StringConfigAttribute backupDirStub =
-         new StringConfigAttribute(ATTR_BACKUP_DIR_LIST, getMessage(msgID),
-                                   true, true, false);
-    try
+    Set<String> values = cfg.getBackupDirectory();
+    backupDirectories = new LinkedHashSet<File>(values.size());
+    for (String s : values)
     {
-      StringConfigAttribute backupDirAttr =
-           (StringConfigAttribute)
-           configEntry.getConfigAttribute(backupDirStub);
-      if (backupDirAttr == null)
-      {
-        backupDirectories = new LinkedHashSet<File>();
-      }
-      else
-      {
-        List<String> values = backupDirAttr.activeValues();
-        backupDirectories = new LinkedHashSet<File>(values.size());
-        for (String s : values)
-        {
-          backupDirectories.add(getFileForPath(s));
-        }
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_BACKUP_CANNOT_DETERMINE_BACKUP_DIR_LIST;
-      String message = getMessage(msgID, stackTraceToSingleLineString(e));
-      throw new InitializationException(msgID, message, e);
+      backupDirectories.add(getFileForPath(s));
     }
 
 
@@ -263,8 +214,9 @@
     supportedFeatures = new HashSet<String>(0);
 
 
-    // Register with the Directory Server as a configurable component.
-    DirectoryServer.registerConfigurableComponent(this);
+    // Register this as a change listener.
+    currentConfig = cfg;
+    cfg.addBackupChangeListener(this);
 
 
     // Register the backup base as a private suffix.
@@ -279,7 +231,7 @@
         debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      msgID = MSGID_BACKEND_CANNOT_REGISTER_BASEDN;
+      int msgID = MSGID_BACKEND_CANNOT_REGISTER_BASEDN;
       String message = getMessage(msgID, backupBaseDN.toString(),
                                   stackTraceToSingleLineString(e));
       throw new InitializationException(msgID, message, e);
@@ -301,7 +253,7 @@
    */
   public void finalizeBackend()
   {
-    DirectoryServer.deregisterConfigurableComponent(this);
+    currentConfig.removeBackupChangeListener(this);
 
     try
     {
@@ -1310,63 +1262,11 @@
 
 
   /**
-   * Retrieves the DN of the configuration entry with which this component is
-   * associated.
-   *
-   * @return  The DN of the configuration entry with which this component is
-   *          associated.
+   * {@inheritDoc}
    */
-  public DN getConfigurableComponentEntryDN()
-  {
-    return configEntryDN;
-  }
-
-
-
-  /**
-   * Retrieves the set of configuration attributes that are associated with this
-   * configurable component.
-   *
-   * @return  The set of configuration attributes that are associated with this
-   *          configurable component.
-   */
-  public List<ConfigAttribute> getConfigurationAttributes()
-  {
-    LinkedList<ConfigAttribute> attrs = new LinkedList<ConfigAttribute>();
-
-
-    ArrayList<String> backupDirs =
-         new ArrayList<String>(backupDirectories.size());
-    for (File f : backupDirectories)
-    {
-      backupDirs.add(f.getAbsolutePath());
-    }
-
-    int msgID = MSGID_BACKUP_DESCRIPTION_BACKUP_DIR_LIST;
-    attrs.add(new StringConfigAttribute(ATTR_BACKUP_DIR_LIST, getMessage(msgID),
-                                        true, true, false, backupDirs));
-
-    return attrs;
-  }
-
-
-
-  /**
-   * Indicates whether the provided configuration entry has an acceptable
-   * configuration for this component.  If it does not, then detailed
-   * information about the problem(s) should be added to the provided list.
-   *
-   * @param  configEntry          The configuration entry for which to make the
-   *                              determination.
-   * @param  unacceptableReasons  A list that can be used to hold messages about
-   *                              why the provided entry does not have an
-   *                              acceptable configuration.
-   *
-   * @return  <CODE>true</CODE> if the provided entry has an acceptable
-   *          configuration for this component, or <CODE>false</CODE> if not.
-   */
-  public boolean hasAcceptableConfiguration(ConfigEntry configEntry,
-                                            List<String> unacceptableReasons)
+  public boolean isConfigurationChangeAcceptable(
+       BackupBackendCfg configEntry,
+       List<String> unacceptableReasons)
   {
     // We'll accept anything here.  The only configurable attribute is the
     // default set of backup directories, but that doesn't require any
@@ -1375,67 +1275,25 @@
   }
 
 
-
   /**
-   * Makes a best-effort attempt to apply the configuration contained in the
-   * provided entry.  Information about the result of this processing should be
-   * added to the provided message list.  Information should always be added to
-   * this list if a configuration change could not be applied.  If detailed
-   * results are requested, then information about the changes applied
-   * successfully (and optionally about parameters that were not changed) should
-   * also be included.
-   *
-   * @param  configEntry      The entry containing the new configuration to
-   *                          apply for this component.
-   * @param  detailedResults  Indicates whether detailed information about the
-   *                          processing should be added to the list.
-   *
-   * @return  Information about the result of the configuration update.
+   * {@inheritDoc}
    */
-  public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry,
-                                                  boolean detailedResults)
+  public ConfigChangeResult applyConfigurationChange(
+       BackupBackendCfg configEntry)
   {
     ResultCode        resultCode          = ResultCode.SUCCESS;
     boolean           adminActionRequired = false;
     ArrayList<String> messages            = new ArrayList<String>();
 
 
-    int msgID = MSGID_BACKUP_DESCRIPTION_BACKUP_DIR_LIST;
-    StringConfigAttribute backupDirStub =
-         new StringConfigAttribute(ATTR_BACKUP_DIR_LIST, getMessage(msgID),
-                                   true, true, false);
-    try
+    Set<String> values = configEntry.getBackupDirectory();
+    backupDirectories = new LinkedHashSet<File>(values.size());
+    for (String s : values)
     {
-      StringConfigAttribute backupDirAttr =
-           (StringConfigAttribute)
-           configEntry.getConfigAttribute(backupDirStub);
-      if (backupDirAttr == null)
-      {
-        backupDirectories = new LinkedHashSet<File>();
-      }
-      else
-      {
-        List<String> values = backupDirAttr.activeValues();
-        backupDirectories = new LinkedHashSet<File>(values.size());
-        for (String s : values)
-        {
-          backupDirectories.add(getFileForPath(s));
-        }
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_BACKUP_CANNOT_DETERMINE_BACKUP_DIR_LIST;
-      messages.add(getMessage(msgID, stackTraceToSingleLineString(e)));
-      resultCode = DirectoryServer.getServerErrorResultCode();
+      backupDirectories.add(getFileForPath(s));
     }
 
-
+    currentConfig = configEntry;
     return new ConfigChangeResult(resultCode, adminActionRequired, messages);
   }
 
@@ -1454,5 +1312,20 @@
          new AttributeValue(rdnAttrType, rdnStringValue);
     return parentDN.concat(RDN.create(rdnAttrType, attrValue));
   }
+
+
+  /**
+   * Gets the backup backend configuration corresponding to a backup
+   * backend config entry.
+   *
+   * @param configEntry A backup backend config entry.
+   * @return Returns the backup backend configuration.
+   * @throws ConfigException If the config entry could not be decoded.
+   */
+  static BackupBackendCfg getBackupBackendCfg(ConfigEntry configEntry)
+      throws ConfigException {
+    return BackendConfigManager.getConfiguration(
+         BackupBackendCfgDefn.getInstance(), configEntry);
+  }
 }
 
diff --git a/opends/src/server/org/opends/server/backends/MonitorBackend.java b/opends/src/server/org/opends/server/backends/MonitorBackend.java
index ef39963..d7c50bf 100644
--- a/opends/src/server/org/opends/server/backends/MonitorBackend.java
+++ b/opends/src/server/org/opends/server/backends/MonitorBackend.java
@@ -33,13 +33,10 @@
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
-import java.util.LinkedList;
 import java.util.List;
 
 import org.opends.server.api.Backend;
-import org.opends.server.api.ConfigurableComponent;
 import org.opends.server.api.MonitorProvider;
-import org.opends.server.config.ConfigAttribute;
 import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.AddOperation;
@@ -48,6 +45,7 @@
 import org.opends.server.core.ModifyOperation;
 import org.opends.server.core.ModifyDNOperation;
 import org.opends.server.core.SearchOperation;
+import org.opends.server.core.BackendConfigManager;
 import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.types.Attribute;
 import org.opends.server.types.AttributeType;
@@ -77,9 +75,11 @@
 import org.opends.server.types.DebugLogLevel;
 import static org.opends.server.messages.BackendMessages.*;
 import static org.opends.server.messages.MessageHandler.*;
+import static org.opends.server.messages.ConfigMessages.*;
 import static org.opends.server.util.ServerConstants.*;
 import static org.opends.server.util.StaticUtils.*;
-
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.std.server.BackendCfg;
 
 
 /**
@@ -90,7 +90,7 @@
  */
 public class MonitorBackend
        extends Backend
-       implements ConfigurableComponent
+       implements ConfigurationChangeListener<BackendCfg>
 {
   // The set of user-defined attributes that will be included in the base
   // monitor entry.
@@ -102,6 +102,9 @@
   // The DN of the configuration entry for this backend.
   private DN configEntryDN;
 
+  // The current configuration state.
+  private BackendCfg currentConfig;
+
   // The DN for the base monitor entry.
   private DN baseMonitorDN;
 
@@ -131,20 +134,7 @@
 
 
   /**
-   * Initializes this backend based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this backend.
-   * @param  baseDNs      The set of base DNs that have been configured for this
-   *                      backend.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
-   *
-   * @throws  InitializationException  If a problem occurs during initialization
-   *                                   that is not related to the server
-   *                                   configuration.
+   * {@inheritDoc}
    */
   public void initializeBackend(ConfigEntry configEntry, DN[] baseDNs)
          throws ConfigException, InitializationException
@@ -158,6 +148,7 @@
       throw new ConfigException(msgID, message);
     }
 
+    BackendCfg cfg = BackendConfigManager.getBackendCfg(configEntry);
     configEntryDN = configEntry.getDN();
 
 
@@ -227,7 +218,8 @@
 
 
     // Register with the Directory Server as a configurable component.
-    DirectoryServer.registerConfigurableComponent(this);
+    currentConfig = cfg;
+    cfg.addChangeListener(this);
 
 
     // Register the monitor base as a private suffix.
@@ -264,7 +256,7 @@
    */
   public void finalizeBackend()
   {
-    DirectoryServer.deregisterConfigurableComponent(this);
+    currentConfig.removeChangeListener(this);
 
     try
     {
@@ -955,17 +947,7 @@
 
 
   /**
-   * Exports the contents of this backend to LDIF.  This method should only be
-   * called if <CODE>supportsLDIFExport</CODE> returns <CODE>true</CODE>.  Note
-   * that the server will not explicitly initialize this backend before calling
-   * this method.
-   *
-   * @param  configEntry   The configuration entry for this backend.
-   * @param  baseDNs       The set of base DNs configured for this backend.
-   * @param  exportConfig  The configuration to use when performing the export.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the LDIF
-   *                              export.
+   * {@inheritDoc}
    */
   public void exportLDIF(ConfigEntry configEntry, DN[] baseDNs,
                          LDIFExportConfig exportConfig)
@@ -1091,17 +1073,7 @@
 
 
   /**
-   * Imports information from an LDIF file into this backend.  This method
-   * should only be called if <CODE>supportsLDIFImport</CODE> returns
-   * <CODE>true</CODE>.  Note that the server will not explicitly initialize
-   * this backend before calling this method.
-   *
-   * @param  configEntry   The configuration entry for this backend.
-   * @param  baseDNs       The set of base DNs configured for this backend.
-   * @param  importConfig  The configuration to use when performing the import.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the LDIF
-   *                              import.
+   * {@inheritDoc}
    */
   public void importLDIF(ConfigEntry configEntry, DN[] baseDNs,
                          LDIFImportConfig importConfig)
@@ -1160,17 +1132,7 @@
 
 
   /**
-   * Creates a backup of the contents of this backend in a form that may be
-   * restored at a later date if necessary.  This method should only be called
-   * if <CODE>supportsBackup</CODE> returns <CODE>true</CODE>.  Note that the
-   * server will not explicitly initialize this backend before calling this
-   * method.
-   *
-   * @param  configEntry   The configuration entry for this backend.
-   * @param  backupConfig  The configuration to use when performing the backup.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the
-   *                              backup.
+   * {@inheritDoc}
    */
   public void createBackup(ConfigEntry configEntry, BackupConfig backupConfig)
          throws DirectoryException
@@ -1224,17 +1186,7 @@
 
 
   /**
-   * Restores a backup of the contents of this backend.  This method should only
-   * be called if <CODE>supportsRestore</CODE> returns <CODE>true</CODE>.  Note
-   * that the server will not explicitly initialize this backend before calling
-   * this method.
-   *
-   * @param  configEntry    The configuration entry for this backend.
-   * @param  restoreConfig  The configuration to use when performing the
-   *                        restore.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the
-   *                              restore.
+   * {@inheritDoc}
    */
   public void restoreBackup(ConfigEntry configEntry,
                             RestoreConfig restoreConfig)
@@ -1250,40 +1202,11 @@
 
 
   /**
-   * Retrieves the DN of the configuration entry with which this component is
-   * associated.
-   *
-   * @return  The DN of the configuration entry with which this component is
-   *          associated.
-   */
-  public DN getConfigurableComponentEntryDN()
-  {
-    return configEntryDN;
-  }
-
-
-
-  /**
-   * Retrieves the set of configuration attributes that are associated with this
-   * configurable component.
-   *
-   * @return  The set of configuration attributes that are associated with this
-   *          configurable component.
-   */
-  public List<ConfigAttribute> getConfigurationAttributes()
-  {
-    // There are no configurable attributes that will be explicitly advertised.
-    return new LinkedList<ConfigAttribute>();
-  }
-
-
-
-  /**
    * Indicates whether the provided configuration entry has an acceptable
    * configuration for this component.  If it does not, then detailed
    * information about the problem(s) should be added to the provided list.
    *
-   * @param  configEntry          The configuration entry for which to make the
+   * @param  backendCfg          The configuration entry for which to make the
    *                              determination.
    * @param  unacceptableReasons  A list that can be used to hold messages about
    *                              why the provided entry does not have an
@@ -1292,8 +1215,9 @@
    * @return  <CODE>true</CODE> if the provided entry has an acceptable
    *          configuration for this component, or <CODE>false</CODE> if not.
    */
-  public boolean hasAcceptableConfiguration(ConfigEntry configEntry,
-                                            List<String> unacceptableReasons)
+  public boolean isConfigurationChangeAcceptable(
+       BackendCfg backendCfg,
+       List<String> unacceptableReasons)
   {
     // We'll pretty much accept anything here as long as it isn't one of our
     // private attributes.
@@ -1303,23 +1227,9 @@
 
 
   /**
-   * Makes a best-effort attempt to apply the configuration contained in the
-   * provided entry.  Information about the result of this processing should be
-   * added to the provided message list.  Information should always be added to
-   * this list if a configuration change could not be applied.  If detailed
-   * results are requested, then information about the changes applied
-   * successfully (and optionally about parameters that were not changed) should
-   * also be included.
-   *
-   * @param  configEntry      The entry containing the new configuration to
-   *                          apply for this component.
-   * @param  detailedResults  Indicates whether detailed information about the
-   *                          processing should be added to the list.
-   *
-   * @return  Information about the result of the configuration update.
+   * {@inheritDoc}
    */
-  public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry,
-                                                  boolean detailedResults)
+  public ConfigChangeResult applyConfigurationChange(BackendCfg backendCfg)
   {
     ResultCode        resultCode          = ResultCode.SUCCESS;
     boolean           adminActionRequired = false;
@@ -1328,39 +1238,54 @@
 
     // Check to see if there is a new set of user-defined attributes.
     ArrayList<Attribute> userAttrs = new ArrayList<Attribute>();
-    for (List<Attribute> attrs :
-         configEntry.getEntry().getUserAttributes().values())
+    try
     {
-      for (Attribute a : attrs)
+      ConfigEntry configEntry = DirectoryServer.getConfigEntry(configEntryDN);
+      for (List<Attribute> attrs :
+           configEntry.getEntry().getUserAttributes().values())
       {
-        if (! isMonitorConfigAttribute(a))
+        for (Attribute a : attrs)
         {
-          userAttrs.add(a);
+          if (! isMonitorConfigAttribute(a))
+          {
+            userAttrs.add(a);
+          }
+        }
+      }
+      for (List<Attribute> attrs :
+           configEntry.getEntry().getOperationalAttributes().values())
+      {
+        for (Attribute a : attrs)
+        {
+          if (! isMonitorConfigAttribute(a))
+          {
+            userAttrs.add(a);
+          }
         }
       }
     }
-    for (List<Attribute> attrs :
-         configEntry.getEntry().getOperationalAttributes().values())
+    catch (Exception e)
     {
-      for (Attribute a : attrs)
+      if (debugEnabled())
       {
-        if (! isMonitorConfigAttribute(a))
-        {
-          userAttrs.add(a);
-        }
+        debugCaught(DebugLogLevel.ERROR, e);
       }
+
+      int msgID = MSGID_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY;
+      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
+                              stackTraceToSingleLineString(e)));
+      resultCode = DirectoryServer.getServerErrorResultCode();
     }
 
 
     userDefinedAttributes = userAttrs;
-    if (detailedResults)
-    {
-      int    msgID   = MSGID_MONITOR_USING_NEW_USER_ATTRS;
-      String message = getMessage(msgID);
-      messages.add(message);
-    }
+
+    int    msgID   = MSGID_MONITOR_USING_NEW_USER_ATTRS;
+    String message = getMessage(msgID);
+    messages.add(message);
 
 
+    currentConfig = backendCfg;
     return new ConfigChangeResult(resultCode, adminActionRequired, messages);
   }
 }
diff --git a/opends/src/server/org/opends/server/backends/RootDSEBackend.java b/opends/src/server/org/opends/server/backends/RootDSEBackend.java
index 142f6e9..df0defc 100644
--- a/opends/src/server/org/opends/server/backends/RootDSEBackend.java
+++ b/opends/src/server/org/opends/server/backends/RootDSEBackend.java
@@ -32,27 +32,22 @@
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.LinkedHashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.opends.server.api.Backend;
-import org.opends.server.api.ConfigurableComponent;
-import org.opends.server.config.BooleanConfigAttribute;
-import org.opends.server.config.ConfigAttribute;
 import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.ConfigException;
-import org.opends.server.config.DNConfigAttribute;
 import org.opends.server.core.AddOperation;
 import org.opends.server.core.DeleteOperation;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.ModifyOperation;
 import org.opends.server.core.ModifyDNOperation;
 import org.opends.server.core.SearchOperation;
+import org.opends.server.core.BackendConfigManager;
 import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.types.Attribute;
 import org.opends.server.types.AttributeType;
@@ -84,9 +79,13 @@
 import static org.opends.server.loggers.Error.*;
 import static org.opends.server.messages.BackendMessages.*;
 import static org.opends.server.messages.MessageHandler.*;
+import static org.opends.server.messages.ConfigMessages.
+     MSGID_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY;
 import static org.opends.server.util.ServerConstants.*;
 import static org.opends.server.util.StaticUtils.*;
-
+import org.opends.server.admin.std.server.RootDSEBackendCfg;
+import org.opends.server.admin.std.meta.RootDSEBackendCfgDefn;
+import org.opends.server.admin.server.ConfigurationChangeListener;
 
 
 /**
@@ -103,7 +102,7 @@
  */
 public class RootDSEBackend
        extends Backend
-       implements ConfigurableComponent
+       implements ConfigurationChangeListener<RootDSEBackendCfg>
 {
   // The set of standard "static" attributes that we will always include in the
   // root DSE entry and won't change while the server is running.
@@ -124,6 +123,9 @@
   // The set of objectclasses that will be used in the root DSE entry.
   private HashMap<ObjectClass,String> dseObjectClasses;
 
+  // The current configuration state.
+  private RootDSEBackendCfg currentConfig;
+
   // The DN of the configuration entry for this backend.
   private DN configEntryDN;
 
@@ -156,20 +158,7 @@
 
 
   /**
-   * Initializes this backend based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this backend.
-   * @param  baseDNs      The set of base DNs that have been configured for this
-   *                      backend.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
-   *
-   * @throws  InitializationException  If a problem occurs during initialization
-   *                                   that is not related to the server
-   *                                   configuration.
+   * {@inheritDoc}
    */
   public void initializeBackend(ConfigEntry configEntry, DN[] baseDNs)
          throws ConfigException, InitializationException
@@ -184,6 +173,7 @@
     }
 
     configEntryDN = configEntry.getDN();
+    RootDSEBackendCfg cfg = getRootDSEBackendCfg(configEntry);
 
 
     // Get the set of user-defined attributes for the configuration entry.  Any
@@ -223,15 +213,10 @@
     // Create the set of subordinate base DNs.  If this is specified in the
     // configuration, then use that set.  Otherwise, use the set of non-private
     // backends defined in the server.
-    String description = getMessage(MSGID_ROOTDSE_SUBORDINATE_BASE_DESCRIPTION);
-    DNConfigAttribute subDNsStub =
-         new DNConfigAttribute(ATTR_ROOT_DSE_SUBORDINATE_BASE_DN, description,
-                               false, true, false);
     try
     {
-      DNConfigAttribute subDNsAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(subDNsStub);
-      if (subDNsAttr == null)
+      Set<DN> subDNs = cfg.getSubordinateBaseDN();
+      if (subDNs.isEmpty())
       {
         // This is fine -- we'll just use the set of user-defined suffixes.
         subordinateBaseDNs = null;
@@ -239,7 +224,7 @@
       else
       {
         subordinateBaseDNs = new ConcurrentHashMap<DN,Backend>();
-        for (DN baseDN : subDNsAttr.activeValues())
+        for (DN baseDN : subDNs)
         {
           Backend backend = DirectoryServer.getBackend(baseDN);
           if (backend == null)
@@ -271,34 +256,7 @@
 
     // Determine whether all root DSE attributes should be treated as user
     // attributes.
-    showAllAttributes = DEFAULT_ROOTDSE_SHOW_ALL_ATTRIBUTES;
-    int msgID = MSGID_ROOTDSE_DESCRIPTION_SHOW_ALL_ATTRIBUTES;
-    BooleanConfigAttribute showAllStub =
-         new BooleanConfigAttribute(ATTR_ROOTDSE_SHOW_ALL_ATTRIBUTES,
-                                    getMessage(msgID), false);
-    try
-    {
-      BooleanConfigAttribute showAllAttr =
-           (BooleanConfigAttribute)
-           configEntry.getConfigAttribute(showAllStub);
-      if (showAllAttr != null)
-      {
-        showAllAttributes = showAllAttr.activeValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_ROOTDSE_CANNOT_DETERMINE_ALL_USER_ATTRIBUTES;
-      String message = getMessage(msgID, ATTR_ROOTDSE_SHOW_ALL_ATTRIBUTES,
-                                  stackTraceToSingleLineString(e));
-      logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_ERROR, message,
-               msgID);
-    }
+    showAllAttributes = cfg.isShowAllAttributes();
 
 
     // Construct the set of "static" attributes that will always be present in
@@ -344,8 +302,9 @@
     setBackendID("rootdse");
 
 
-    // Register with the Directory Server as a configurable component.
-    DirectoryServer.registerConfigurableComponent(this);
+    // Register as a change listener.
+    currentConfig = cfg;
+    cfg.addChangeListener(this);
   }
 
 
@@ -363,7 +322,7 @@
    */
   public void finalizeBackend()
   {
-    DirectoryServer.deregisterConfigurableComponent(this);
+    currentConfig.removeChangeListener(this);
   }
 
 
@@ -1158,17 +1117,7 @@
 
 
   /**
-   * Exports the contents of this backend to LDIF.  This method should only be
-   * called if <CODE>supportsLDIFExport</CODE> returns <CODE>true</CODE>.  Note
-   * that the server will not explicitly initialize this backend before calling
-   * this method.
-   *
-   * @param  configEntry   The configuration entry for this backend.
-   * @param  baseDNs       The set of base DNs configured for this backend.
-   * @param  exportConfig  The configuration to use when performing the export.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the LDIF
-   *                              export.
+   * {@inheritDoc}
    */
   public void exportLDIF(ConfigEntry configEntry, DN[] baseDNs,
                          LDIFExportConfig exportConfig)
@@ -1246,17 +1195,7 @@
 
 
   /**
-   * Imports information from an LDIF file into this backend.  This method
-   * should only be called if <CODE>supportsLDIFImport</CODE> returns
-   * <CODE>true</CODE>.  Note that the server will not explicitly initialize
-   * this backend before calling this method.
-   *
-   * @param  configEntry   The configuration entry for this backend.
-   * @param  baseDNs       The set of base DNs configured for this backend.
-   * @param  importConfig  The configuration to use when performing the import.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the LDIF
-   *                              import.
+   * {@inheritDoc}
    */
   public void importLDIF(ConfigEntry configEntry, DN[] baseDNs,
                          LDIFImportConfig importConfig)
@@ -1315,17 +1254,7 @@
 
 
   /**
-   * Creates a backup of the contents of this backend in a form that may be
-   * restored at a later date if necessary.  This method should only be called
-   * if <CODE>supportsBackup</CODE> returns <CODE>true</CODE>.  Note that the
-   * server will not explicitly initialize this backend before calling this
-   * method.
-   *
-   * @param  configEntry   The configuration entry for this backend.
-   * @param  backupConfig  The configuration to use when performing the backup.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the
-   *                              backup.
+   * {@inheritDoc}
    */
   public void createBackup(ConfigEntry configEntry, BackupConfig backupConfig)
          throws DirectoryException
@@ -1379,17 +1308,7 @@
 
 
   /**
-   * Restores a backup of the contents of this backend.  This method should only
-   * be called if <CODE>supportsRestore</CODE> returns <CODE>true</CODE>.  Note
-   * that the server will not explicitly initialize this backend before calling
-   * this method.
-   *
-   * @param  configEntry    The configuration entry for this backend.
-   * @param  restoreConfig  The configuration to use when performing the
-   *                        restore.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the
-   *                              restore.
+   * {@inheritDoc}
    */
   public void restoreBackup(ConfigEntry configEntry,
                             RestoreConfig restoreConfig)
@@ -1405,88 +1324,25 @@
 
 
   /**
-   * Retrieves the DN of the configuration entry with which this component is
-   * associated.
-   *
-   * @return  The DN of the configuration entry with which this component is
-   *          associated.
+   * {@inheritDoc}
    */
-  public DN getConfigurableComponentEntryDN()
-  {
-    return configEntryDN;
-  }
-
-
-
-  /**
-   * Retrieves the set of configuration attributes that are associated with this
-   * configurable component.
-   *
-   * @return  The set of configuration attributes that are associated with this
-   *          configurable component.
-   */
-  public List<ConfigAttribute> getConfigurationAttributes()
-  {
-    LinkedList<ConfigAttribute> attrList = new LinkedList<ConfigAttribute>();
-
-    String description = getMessage(MSGID_ROOTDSE_SUBORDINATE_BASE_DESCRIPTION);
-
-    ArrayList<DN> values = new ArrayList<DN>();
-    if (subordinateBaseDNs != null)
-    {
-      values.addAll(subordinateBaseDNs.keySet());
-    }
-
-    attrList.add(new DNConfigAttribute(ATTR_ROOT_DSE_SUBORDINATE_BASE_DN,
-                                       description, false, true, false,
-                                       values));
-
-
-    description = getMessage(MSGID_ROOTDSE_DESCRIPTION_SHOW_ALL_ATTRIBUTES);
-    attrList.add(new BooleanConfigAttribute(ATTR_ROOTDSE_SHOW_ALL_ATTRIBUTES,
-                                            description, showAllAttributes));
-
-
-    return attrList;
-  }
-
-
-
-  /**
-   * Indicates whether the provided configuration entry has an acceptable
-   * configuration for this component.  If it does not, then detailed
-   * information about the problem(s) should be added to the provided list.
-   *
-   * @param  configEntry          The configuration entry for which to make the
-   *                              determination.
-   * @param  unacceptableReasons  A list that can be used to hold messages about
-   *                              why the provided entry does not have an
-   *                              acceptable configuration.
-   *
-   * @return  <CODE>true</CODE> if the provided entry has an acceptable
-   *          configuration for this component, or <CODE>false</CODE> if not.
-   */
-  public boolean hasAcceptableConfiguration(ConfigEntry configEntry,
-                                            List<String> unacceptableReasons)
+  public boolean isConfigurationChangeAcceptable(
+       RootDSEBackendCfg cfg,
+       List<String> unacceptableReasons)
   {
     boolean configIsAcceptable = true;
 
 
-    String description = getMessage(MSGID_ROOTDSE_SUBORDINATE_BASE_DESCRIPTION);
-    DNConfigAttribute subDNsStub =
-         new DNConfigAttribute(ATTR_ROOT_DSE_SUBORDINATE_BASE_DN, description,
-                               false, true, false);
     try
     {
-      DNConfigAttribute subDNsAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(subDNsStub);
-      if (subDNsAttr == null)
+      Set<DN> subDNs = cfg.getSubordinateBaseDN();
+      if (subDNs.isEmpty())
       {
         // This is fine -- we'll just use the set of user-defined suffixes.
       }
       else
       {
-        for (DN baseDN : subDNsAttr.activeValues())
+        for (DN baseDN : subDNs)
         {
           Backend backend = DirectoryServer.getBackend(baseDN);
           if (backend == null)
@@ -1513,54 +1369,15 @@
     }
 
 
-    description = getMessage(MSGID_ROOTDSE_DESCRIPTION_SHOW_ALL_ATTRIBUTES);
-    BooleanConfigAttribute showAllStub =
-         new BooleanConfigAttribute(ATTR_ROOTDSE_SHOW_ALL_ATTRIBUTES,
-                                    description, false);
-    try
-    {
-      BooleanConfigAttribute showAllAttr =
-           (BooleanConfigAttribute) configEntry.getConfigAttribute(showAllStub);
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      int    msgID   = MSGID_ROOTDSE_CANNOT_DETERMINE_ALL_USER_ATTRIBUTES;
-      String message = getMessage(msgID, ATTR_ROOTDSE_SHOW_ALL_ATTRIBUTES,
-                                  stackTraceToSingleLineString(e));
-      unacceptableReasons.add(message);
-
-      configIsAcceptable = false;
-    }
-
-
     return configIsAcceptable;
   }
 
 
 
   /**
-   * Makes a best-effort attempt to apply the configuration contained in the
-   * provided entry.  Information about the result of this processing should be
-   * added to the provided message list.  Information should always be added to
-   * this list if a configuration change could not be applied.  If detailed
-   * results are requested, then information about the changes applied
-   * successfully (and optionally about parameters that were not changed) should
-   * also be included.
-   *
-   * @param  configEntry      The entry containing the new configuration to
-   *                          apply for this component.
-   * @param  detailedResults  Indicates whether detailed information about the
-   *                          processing should be added to the list.
-   *
-   * @return  Information about the result of the configuration update.
+   * {@inheritDoc}
    */
-  public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry,
-                                                  boolean detailedResults)
+  public ConfigChangeResult applyConfigurationChange(RootDSEBackendCfg cfg)
   {
     ResultCode        resultCode          = ResultCode.SUCCESS;
     boolean           adminActionRequired = false;
@@ -1569,15 +1386,10 @@
 
     // Check to see if we should apply a new set of base DNs.
     ConcurrentHashMap<DN,Backend> subBases;
-    String description = getMessage(MSGID_ROOTDSE_SUBORDINATE_BASE_DESCRIPTION);
-    DNConfigAttribute subDNsStub =
-         new DNConfigAttribute(ATTR_ROOT_DSE_SUBORDINATE_BASE_DN, description,
-                               false, true, false);
     try
     {
-      DNConfigAttribute subDNsAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(subDNsStub);
-      if (subDNsAttr == null)
+      Set<DN> subDNs = cfg.getSubordinateBaseDN();
+      if (subDNs.isEmpty())
       {
         // This is fine -- we'll just use the set of user-defined suffixes.
         subBases = null;
@@ -1585,7 +1397,7 @@
       else
       {
         subBases = new ConcurrentHashMap<DN,Backend>();
-        for (DN baseDN : subDNsAttr.activeValues())
+        for (DN baseDN : subDNs)
         {
           Backend backend = DirectoryServer.getBackend(baseDN);
           if (backend == null)
@@ -1627,62 +1439,49 @@
     }
 
 
-    boolean newShowAll = DEFAULT_ROOTDSE_SHOW_ALL_ATTRIBUTES;
-    description = getMessage(MSGID_ROOTDSE_DESCRIPTION_SHOW_ALL_ATTRIBUTES);
-    BooleanConfigAttribute showAllStub =
-         new BooleanConfigAttribute(ATTR_ROOTDSE_SHOW_ALL_ATTRIBUTES,
-                                    description, false);
+    boolean newShowAll = cfg.isShowAllAttributes();
+
+
+    // Check to see if there is a new set of user-defined attributes.
+    ArrayList<Attribute> userAttrs = new ArrayList<Attribute>();
     try
     {
-      BooleanConfigAttribute showAllAttr =
-           (BooleanConfigAttribute) configEntry.getConfigAttribute(showAllStub);
-      if (showAllAttr != null)
+      ConfigEntry configEntry = DirectoryServer.getConfigEntry(configEntryDN);
+
+      for (List<Attribute> attrs :
+           configEntry.getEntry().getUserAttributes().values())
       {
-        newShowAll = showAllAttr.pendingValue();
+        for (Attribute a : attrs)
+        {
+          if (! isDSEConfigAttribute(a))
+          {
+            userAttrs.add(a);
+          }
+        }
+      }
+      for (List<Attribute> attrs :
+           configEntry.getEntry().getOperationalAttributes().values())
+      {
+        for (Attribute a : attrs)
+        {
+          if (! isDSEConfigAttribute(a))
+          {
+            userAttrs.add(a);
+          }
+        }
       }
     }
-    catch (Exception e)
+    catch (ConfigException e)
     {
       if (debugEnabled())
       {
         debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      int msgID = MSGID_ROOTDSE_CANNOT_DETERMINE_ALL_USER_ATTRIBUTES;
-      String message = getMessage(msgID, ATTR_ROOTDSE_SHOW_ALL_ATTRIBUTES,
-                                  stackTraceToSingleLineString(e));
-      messages.add(message);
-
-      if (resultCode == ResultCode.SUCCESS)
-      {
-        resultCode = DirectoryServer.getServerErrorResultCode();
-      }
-    }
-
-
-    // Check to see if there is a new set of user-defined attributes.
-    ArrayList<Attribute> userAttrs = new ArrayList<Attribute>();
-    for (List<Attribute> attrs :
-         configEntry.getEntry().getUserAttributes().values())
-    {
-      for (Attribute a : attrs)
-      {
-        if (! isDSEConfigAttribute(a))
-        {
-          userAttrs.add(a);
-        }
-      }
-    }
-    for (List<Attribute> attrs :
-         configEntry.getEntry().getOperationalAttributes().values())
-    {
-      for (Attribute a : attrs)
-      {
-        if (! isDSEConfigAttribute(a))
-        {
-          userAttrs.add(a);
-        }
-      }
+      int msgID = MSGID_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY;
+      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
+                              stackTraceToSingleLineString(e)));
+      resultCode = DirectoryServer.getServerErrorResultCode();
     }
 
 
@@ -1690,65 +1489,63 @@
     {
       subordinateBaseDNs = subBases;
 
-      if (detailedResults)
+      if (subordinateBaseDNs == null)
       {
-        if (subordinateBaseDNs == null)
+        int msgID = MSGID_ROOTDSE_USING_SUFFIXES_AS_BASE_DNS;
+        String message = getMessage(msgID);
+        messages.add(message);
+      }
+      else
+      {
+        StringBuilder basesStr = new StringBuilder();
+        for (DN dn : subordinateBaseDNs.keySet())
         {
-          int msgID = MSGID_ROOTDSE_USING_SUFFIXES_AS_BASE_DNS;
-          String message = getMessage(msgID);
-          messages.add(message);
-        }
-        else
-        {
-          StringBuilder basesStr = new StringBuilder();
-          Iterator<DN> iterator = subordinateBaseDNs.keySet().iterator();
-          while (iterator.hasNext())
+          if (basesStr.length() > 0)
           {
-            if (basesStr.length() > 0)
-            {
-              basesStr.append(", ");
-            }
-            else
-            {
-              basesStr.append("{ ");
-            }
-
-            basesStr.append(iterator.next());
+            basesStr.append(", ");
+          }
+          else
+          {
+            basesStr.append("{ ");
           }
 
-          basesStr.append(" }");
-
-          int msgID = MSGID_ROOTDSE_USING_NEW_SUBORDINATE_BASE_DNS;
-          String message = getMessage(msgID, basesStr.toString());
-          messages.add(message);
+          basesStr.append(dn);
         }
+
+        basesStr.append(" }");
+
+        int msgID = MSGID_ROOTDSE_USING_NEW_SUBORDINATE_BASE_DNS;
+        String message = getMessage(msgID, basesStr.toString());
+        messages.add(message);
       }
 
 
       if (showAllAttributes != newShowAll)
       {
         showAllAttributes = newShowAll;
-        if (detailedResults)
-        {
-          int    msgID   = MSGID_ROOTDSE_UPDATED_SHOW_ALL_ATTRS;
-          String message = getMessage(msgID, ATTR_ROOTDSE_SHOW_ALL_ATTRIBUTES,
-                                      showAllAttributes);
-          messages.add(message);
-        }
+        int    msgID   = MSGID_ROOTDSE_UPDATED_SHOW_ALL_ATTRS;
+        String message = getMessage(msgID, ATTR_ROOTDSE_SHOW_ALL_ATTRIBUTES,
+                                    showAllAttributes);
+        messages.add(message);
       }
 
 
       userDefinedAttributes = userAttrs;
-      if (detailedResults)
-      {
-        int    msgID   = MSGID_ROOTDSE_USING_NEW_USER_ATTRS;
-        String message = getMessage(msgID);
-        messages.add(message);
-      }
+      int    msgID   = MSGID_ROOTDSE_USING_NEW_USER_ATTRS;
+      String message = getMessage(msgID);
+      messages.add(message);
     }
 
 
     return new ConfigChangeResult(resultCode, adminActionRequired, messages);
   }
+
+
+
+  private static RootDSEBackendCfg getRootDSEBackendCfg(ConfigEntry configEntry)
+      throws ConfigException {
+    return BackendConfigManager.getConfiguration(
+         RootDSEBackendCfgDefn.getInstance(), configEntry);
+  }
 }
 
diff --git a/opends/src/server/org/opends/server/backends/SchemaBackend.java b/opends/src/server/org/opends/server/backends/SchemaBackend.java
index 042bafe..ac7bbc4 100644
--- a/opends/src/server/org/opends/server/backends/SchemaBackend.java
+++ b/opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -59,13 +59,9 @@
 import org.opends.server.api.AlertGenerator;
 import org.opends.server.api.Backend;
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.ConfigurableComponent;
 import org.opends.server.api.MatchingRule;
-import org.opends.server.config.BooleanConfigAttribute;
-import org.opends.server.config.ConfigAttribute;
 import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.ConfigException;
-import org.opends.server.config.DNConfigAttribute;
 import org.opends.server.core.AddOperation;
 import org.opends.server.core.DeleteOperation;
 import org.opends.server.core.DirectoryServer;
@@ -73,6 +69,7 @@
 import org.opends.server.core.ModifyDNOperation;
 import org.opends.server.core.SchemaConfigManager;
 import org.opends.server.core.SearchOperation;
+import org.opends.server.core.BackendConfigManager;
 import org.opends.server.schema.AttributeTypeSyntax;
 import org.opends.server.schema.DITContentRuleSyntax;
 import org.opends.server.schema.DITStructureRuleSyntax;
@@ -125,7 +122,10 @@
 import static org.opends.server.messages.MessageHandler.*;
 import static org.opends.server.util.ServerConstants.*;
 import static org.opends.server.util.StaticUtils.*;
-
+import org.opends.server.admin.std.server.SchemaBackendCfg;
+import org.opends.server.admin.std.meta.SchemaBackendCfgDefn;
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import static org.opends.server.messages.ConfigMessages.*;
 
 
 /**
@@ -134,8 +134,8 @@
  * rather dynamically generates the schema entry whenever it is requested.
  */
 public class SchemaBackend
-       extends Backend
-       implements ConfigurableComponent, AlertGenerator
+     extends Backend
+     implements ConfigurationChangeListener<SchemaBackendCfg>, AlertGenerator
 {
   /**
    * The fully-qualified name of this class.
@@ -213,6 +213,9 @@
   // The DN of the configuration entry for this backend.
   private DN configEntryDN;
 
+  // The current configuration state.
+  private SchemaBackendCfg currentConfig;
+
   // The set of base DNs for this backend.
   private DN[] baseDNs;
 
@@ -245,20 +248,7 @@
 
 
   /**
-   * Initializes this backend based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this backend.
-   * @param  baseDNs      The set of base DNs that have been configured for this
-   *                      backend.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
-   *
-   * @throws  InitializationException  If a problem occurs during initialization
-   *                                   that is not related to the server
-   *                                   configuration.
+   * {@inheritDoc}
    */
   public void initializeBackend(ConfigEntry configEntry, DN[] baseDNs)
          throws ConfigException, InitializationException
@@ -273,7 +263,7 @@
     }
 
     configEntryDN = configEntry.getDN();
-
+    SchemaBackendCfg cfg = getSchemaBackendCfg(configEntry);
 
     // Get all of the attribute types that we will use for schema elements.
     attributeTypesType =
@@ -347,32 +337,7 @@
 
 
     // Determine whether to show all attributes.
-    showAllAttributes = DEFAULT_SCHEMA_SHOW_ALL_ATTRIBUTES;
-    int msgID = MSGID_SCHEMA_DESCRIPTION_SHOW_ALL_ATTRIBUTES;
-    BooleanConfigAttribute showAllStub =
-         new BooleanConfigAttribute(ATTR_SCHEMA_SHOW_ALL_ATTRIBUTES,
-                                    getMessage(msgID), false);
-    try
-    {
-      BooleanConfigAttribute showAllAttr =
-           (BooleanConfigAttribute) configEntry.getConfigAttribute(showAllStub);
-      if (showAllAttr != null)
-      {
-        showAllAttributes = showAllAttr.activeValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SCHEMA_CANNOT_DETERMINE_SHOW_ALL;
-      String message = getMessage(msgID, String.valueOf(configEntryDN),
-                                  stackTraceToSingleLineString(e));
-      throw new ConfigException(msgID, message, e);
-    }
+    showAllAttributes = cfg.isShowAllAttributes();
 
 
     // Register each of the suffixes with the Directory Server.  Also, register
@@ -392,7 +357,7 @@
           debugCaught(DebugLogLevel.ERROR, e);
         }
 
-        msgID = MSGID_BACKEND_CANNOT_REGISTER_BASEDN;
+        int msgID = MSGID_BACKEND_CANNOT_REGISTER_BASEDN;
         String message = getMessage(msgID, baseDNs[i].toString(),
                                     stackTraceToSingleLineString(e));
         throw new InitializationException(msgID, message, e);
@@ -469,7 +434,7 @@
           }
           else
           {
-            msgID = MSGID_SCHEMA_CANNOT_FIND_CONCAT_FILE;
+            int msgID = MSGID_SCHEMA_CANNOT_FIND_CONCAT_FILE;
             String message = getMessage(msgID,
                                         upgradeDirectory.getAbsolutePath(),
                                         SCHEMA_CONCAT_FILE_NAME,
@@ -521,7 +486,7 @@
         debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      msgID = MSGID_SCHEMA_ERROR_DETERMINING_SCHEMA_CHANGES;
+      int msgID = MSGID_SCHEMA_ERROR_DETERMINING_SCHEMA_CHANGES;
       String message = getMessage(msgID, stackTraceToSingleLineString(e));
       logError(ErrorLogCategory.SCHEMA, ErrorLogSeverity.SEVERE_ERROR, message,
                msgID);
@@ -529,7 +494,8 @@
 
 
     // Register with the Directory Server as a configurable component.
-    DirectoryServer.registerConfigurableComponent(this);
+    currentConfig = cfg;
+    cfg.addSchemaChangeListener(this);
   }
 
 
@@ -547,7 +513,7 @@
    */
   public void finalizeBackend()
   {
-    DirectoryServer.deregisterConfigurableComponent(this);
+    currentConfig.removeSchemaChangeListener(this);
 
     for (DN baseDN : baseDNs)
     {
@@ -4169,17 +4135,7 @@
 
 
   /**
-   * Exports the contents of this backend to LDIF.  This method should only be
-   * called if <CODE>supportsLDIFExport</CODE> returns <CODE>true</CODE>.  Note
-   * that the server will not explicitly initialize this backend before calling
-   * this method.
-   *
-   * @param  configEntry   The configuration entry for this backend.
-   * @param  baseDNs       The set of base DNs configured for this backend.
-   * @param  exportConfig  The configuration to use when performing the export.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the LDIF
-   *                              export.
+   * {@inheritDoc}
    */
   public void exportLDIF(ConfigEntry configEntry, DN[] baseDNs,
                          LDIFExportConfig exportConfig)
@@ -4258,17 +4214,7 @@
 
 
   /**
-   * Imports information from an LDIF file into this backend.  This method
-   * should only be called if <CODE>supportsLDIFImport</CODE> returns
-   * <CODE>true</CODE>.  Note that the server will not explicitly initialize
-   * this backend before calling this method.
-   *
-   * @param  configEntry   The configuration entry for this backend.
-   * @param  baseDNs       The set of base DNs configured for this backend.
-   * @param  importConfig  The configuration to use when performing the import.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the LDIF
-   *                              import.
+   * {@inheritDoc}
    */
   public void importLDIF(ConfigEntry configEntry, DN[] baseDNs,
                          LDIFImportConfig importConfig)
@@ -4330,17 +4276,7 @@
 
 
   /**
-   * Creates a backup of the contents of this backend in a form that may be
-   * restored at a later date if necessary.  This method should only be called
-   * if <CODE>supportsBackup</CODE> returns <CODE>true</CODE>.  Note that the
-   * server will not explicitly initialize this backend before calling this
-   * method.
-   *
-   * @param  configEntry   The configuration entry for this backend.
-   * @param  backupConfig  The configuration to use when performing the backup.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the
-   *                              backup.
+   * {@inheritDoc}
    */
   public void createBackup(ConfigEntry configEntry, BackupConfig backupConfig)
          throws DirectoryException
@@ -4737,17 +4673,7 @@
 
 
   /**
-   * Restores a backup of the contents of this backend.  This method should only
-   * be called if <CODE>supportsRestore</CODE> returns <CODE>true</CODE>.  Note
-   * that the server will not explicitly initialize this backend before calling
-   * this method.
-   *
-   * @param  configEntry    The configuration entry for this backend.
-   * @param  restoreConfig  The configuration to use when performing the
-   *                        restore.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the
-   *                              restore.
+   * {@inheritDoc}
    */
   public void restoreBackup(ConfigEntry configEntry,
                             RestoreConfig restoreConfig)
@@ -5253,82 +5179,37 @@
 
 
   /**
-   * Retrieves the DN of the configuration entry with which this component is
-   * associated.
-   *
-   * @return  The DN of the configuration entry with which this component is
-   *          associated.
+   * {@inheritDoc}
    */
-  public DN getConfigurableComponentEntryDN()
+  public boolean isConfigurationChangeAcceptable(
+       SchemaBackendCfg configEntry,
+       List<String> unacceptableReasons)
   {
-    return configEntryDN;
+    return true;
   }
 
 
 
   /**
-   * Retrieves the set of configuration attributes that are associated with this
-   * configurable component.
-   *
-   * @return  The set of configuration attributes that are associated with this
-   *          configurable component.
+   * {@inheritDoc}
    */
-  public List<ConfigAttribute> getConfigurationAttributes()
+  public ConfigChangeResult applyConfigurationChange(
+       SchemaBackendCfg backendCfg)
   {
-    LinkedList<ConfigAttribute> attrList = new LinkedList<ConfigAttribute>();
-
-    String description = getMessage(MSGID_SCHEMA_DESCRIPTION_ENTRY_DN);
-
-    ArrayList<DN> values = new ArrayList<DN>(baseDNs.length);
-    for (DN baseDN : baseDNs)
-    {
-      values.add(baseDN);
-    }
-
-    attrList.add(new DNConfigAttribute(ATTR_SCHEMA_ENTRY_DN, description,
-                                       false, true, false, values));
+    ResultCode        resultCode          = ResultCode.SUCCESS;
+    boolean           adminActionRequired = false;
+    ArrayList<String> messages            = new ArrayList<String>();
 
 
-    description = getMessage(MSGID_SCHEMA_DESCRIPTION_SHOW_ALL_ATTRIBUTES);
-    attrList.add(new BooleanConfigAttribute(ATTR_SCHEMA_SHOW_ALL_ATTRIBUTES,
-                                            description, false,
-                                            showAllAttributes));
-
-
-    return attrList;
-  }
-
-
-
-  /**
-   * Indicates whether the provided configuration entry has an acceptable
-   * configuration for this component.  If it does not, then detailed
-   * information about the problem(s) should be added to the provided list.
-   *
-   * @param  configEntry          The configuration entry for which to make the
-   *                              determination.
-   * @param  unacceptableReasons  A list that can be used to hold messages about
-   *                              why the provided entry does not have an
-   *                              acceptable configuration.
-   *
-   * @return  <CODE>true</CODE> if the provided entry has an acceptable
-   *          configuration for this component, or <CODE>false</CODE> if not.
-   */
-  public boolean hasAcceptableConfiguration(ConfigEntry configEntry,
-                                            List<String> unacceptableReasons)
-  {
-    boolean configIsAcceptable = true;
-
-
-    String description = getMessage(MSGID_SCHEMA_DESCRIPTION_ENTRY_DN);
-    DNConfigAttribute baseDNStub =
-         new DNConfigAttribute(ATTR_SCHEMA_ENTRY_DN, description, false, true,
-                               false);
+    // Check to see if we should apply a new set of base DNs.
+    Set<DN> newBaseDNs;
     try
     {
-      // We don't care what the DNs are as long as we can parse them.
-      DNConfigAttribute baseDNAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(baseDNStub);
+      newBaseDNs = backendCfg.getSchemaEntryDN();
+      if (newBaseDNs.isEmpty())
+      {
+        newBaseDNs.add(DN.decode(DN_DEFAULT_SCHEMA_ROOT));
+      }
     }
     catch (Exception e)
     {
@@ -5338,104 +5219,6 @@
       }
 
       int msgID = MSGID_SCHEMA_CANNOT_DETERMINE_BASE_DN;
-      String message = getMessage(msgID, String.valueOf(configEntryDN),
-                                  stackTraceToSingleLineString(e));
-      unacceptableReasons.add(message);
-      configIsAcceptable = false;
-    }
-
-
-    description = getMessage(MSGID_SCHEMA_DESCRIPTION_SHOW_ALL_ATTRIBUTES);
-    BooleanConfigAttribute showAllStub =
-         new BooleanConfigAttribute(ATTR_SCHEMA_SHOW_ALL_ATTRIBUTES,
-                                    description, false);
-    try
-    {
-      // We don't care what the value is as long as we can parse it.
-      BooleanConfigAttribute showAllAttr =
-           (BooleanConfigAttribute) configEntry.getConfigAttribute(showAllStub);
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      int msgID = MSGID_SCHEMA_CANNOT_DETERMINE_SHOW_ALL;
-      String message = getMessage(msgID, String.valueOf(configEntryDN),
-                                  stackTraceToSingleLineString(e));
-      unacceptableReasons.add(message);
-      configIsAcceptable = false;
-    }
-
-
-    return configIsAcceptable;
-  }
-
-
-
-  /**
-   * Makes a best-effort attempt to apply the configuration contained in the
-   * provided entry.  Information about the result of this processing should be
-   * added to the provided message list.  Information should always be added to
-   * this list if a configuration change could not be applied.  If detailed
-   * results are requested, then information about the changes applied
-   * successfully (and optionally about parameters that were not changed) should
-   * also be included.
-   *
-   * @param  configEntry      The entry containing the new configuration to
-   *                          apply for this component.
-   * @param  detailedResults  Indicates whether detailed information about the
-   *                          processing should be added to the list.
-   *
-   * @return  Information about the result of the configuration update.
-   */
-  public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry,
-                                                  boolean detailedResults)
-  {
-    ResultCode        resultCode          = ResultCode.SUCCESS;
-    boolean           adminActionRequired = false;
-    ArrayList<String> messages            = new ArrayList<String>();
-
-
-    // Check to see if we should apply a new set of base DNs.
-    HashSet<DN> newBaseDNs;
-    int msgID = MSGID_SCHEMA_DESCRIPTION_ENTRY_DN;
-    DNConfigAttribute baseDNStub =
-         new DNConfigAttribute(ATTR_SCHEMA_ENTRY_DN, getMessage(msgID), false,
-                               true, false);
-    try
-    {
-      DNConfigAttribute baseDNAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(baseDNStub);
-      if (baseDNAttr == null)
-      {
-        newBaseDNs = new HashSet<DN>(1);
-        newBaseDNs.add(DN.decode(DN_DEFAULT_SCHEMA_ROOT));
-      }
-      else
-      {
-        List<DN> newDNList = baseDNAttr.activeValues();
-        if ((newDNList == null) || newDNList.isEmpty())
-        {
-          newBaseDNs = new HashSet<DN>(1);
-          newBaseDNs.add(DN.decode(DN_DEFAULT_SCHEMA_ROOT));
-        }
-        else
-        {
-          newBaseDNs = new HashSet<DN>(newDNList);
-        }
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SCHEMA_CANNOT_DETERMINE_BASE_DN;
       messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                               stackTraceToSingleLineString(e)));
       resultCode = DirectoryServer.getServerErrorResultCode();
@@ -5445,58 +5228,48 @@
 
     // Check to see if we should change the behavior regarding whether to show
     // all schema attributes.
-    boolean newShowAllAttributes = DEFAULT_SCHEMA_SHOW_ALL_ATTRIBUTES;
-    msgID = MSGID_SCHEMA_DESCRIPTION_SHOW_ALL_ATTRIBUTES;
-    BooleanConfigAttribute showAllStub =
-         new BooleanConfigAttribute(ATTR_SCHEMA_SHOW_ALL_ATTRIBUTES,
-                                    getMessage(msgID), false);
+    boolean newShowAllAttributes = backendCfg.isShowAllAttributes();
+
+
+    // Check to see if there is a new set of user-defined attributes.
+    ArrayList<Attribute> newUserAttrs = new ArrayList<Attribute>();
     try
     {
-      BooleanConfigAttribute showAllAttr =
-           (BooleanConfigAttribute) configEntry.getConfigAttribute(showAllStub);
-      if (showAllAttr != null)
+      ConfigEntry configEntry = DirectoryServer.getConfigEntry(configEntryDN);
+      for (List<Attribute> attrs :
+           configEntry.getEntry().getUserAttributes().values())
       {
-        newShowAllAttributes = showAllAttr.activeValue();
+        for (Attribute a : attrs)
+        {
+          if (! isSchemaConfigAttribute(a))
+          {
+            newUserAttrs.add(a);
+          }
+        }
+      }
+      for (List<Attribute> attrs :
+           configEntry.getEntry().getOperationalAttributes().values())
+      {
+        for (Attribute a : attrs)
+        {
+          if (! isSchemaConfigAttribute(a))
+          {
+            newUserAttrs.add(a);
+          }
+        }
       }
     }
-    catch (Exception e)
+    catch (ConfigException e)
     {
       if (debugEnabled())
       {
         debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      msgID = MSGID_SCHEMA_CANNOT_DETERMINE_SHOW_ALL;
+      int msgID = MSGID_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY;
       messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                               stackTraceToSingleLineString(e)));
       resultCode = DirectoryServer.getServerErrorResultCode();
-      newBaseDNs = null;
-    }
-
-
-    // Check to see if there is a new set of user-defined attributes.
-    ArrayList<Attribute> newUserAttrs = new ArrayList<Attribute>();
-    for (List<Attribute> attrs :
-         configEntry.getEntry().getUserAttributes().values())
-    {
-      for (Attribute a : attrs)
-      {
-        if (! isSchemaConfigAttribute(a))
-        {
-          newUserAttrs.add(a);
-        }
-      }
-    }
-    for (List<Attribute> attrs :
-         configEntry.getEntry().getOperationalAttributes().values())
-    {
-      for (Attribute a : attrs)
-      {
-        if (! isSchemaConfigAttribute(a))
-        {
-          newUserAttrs.add(a);
-        }
-      }
     }
 
 
@@ -5525,11 +5298,8 @@
         try
         {
           DirectoryServer.deregisterBaseDN(dn, false);
-          if (detailedResults)
-          {
-            msgID = MSGID_SCHEMA_DEREGISTERED_BASE_DN;
-            messages.add(getMessage(msgID, String.valueOf(dn)));
-          }
+          int msgID = MSGID_SCHEMA_DEREGISTERED_BASE_DN;
+          messages.add(getMessage(msgID, String.valueOf(dn)));
         }
         catch (Exception e)
         {
@@ -5538,7 +5308,7 @@
             debugCaught(DebugLogLevel.ERROR, e);
           }
 
-          msgID = MSGID_SCHEMA_CANNOT_DEREGISTER_BASE_DN;
+          int msgID = MSGID_SCHEMA_CANNOT_DEREGISTER_BASE_DN;
           messages.add(getMessage(msgID, String.valueOf(dn),
                                   stackTraceToSingleLineString(e)));
           resultCode = DirectoryServer.getServerErrorResultCode();
@@ -5551,11 +5321,8 @@
         try
         {
           DirectoryServer.registerBaseDN(dn, this, true, false);
-          if (detailedResults)
-          {
-            msgID = MSGID_SCHEMA_REGISTERED_BASE_DN;
-            messages.add(getMessage(msgID, String.valueOf(dn)));
-          }
+          int msgID = MSGID_SCHEMA_REGISTERED_BASE_DN;
+          messages.add(getMessage(msgID, String.valueOf(dn)));
         }
         catch (Exception e)
         {
@@ -5564,7 +5331,7 @@
             debugCaught(DebugLogLevel.ERROR, e);
           }
 
-          msgID = MSGID_SCHEMA_CANNOT_REGISTER_BASE_DN;
+          int msgID = MSGID_SCHEMA_CANNOT_REGISTER_BASE_DN;
           messages.add(getMessage(msgID, String.valueOf(dn),
                                   stackTraceToSingleLineString(e)));
           resultCode = DirectoryServer.getServerErrorResultCode();
@@ -5576,15 +5343,13 @@
 
 
       userDefinedAttributes = newUserAttrs;
-      if (detailedResults)
-      {
-        msgID = MSGID_SCHEMA_USING_NEW_USER_ATTRS;
-        String message = getMessage(msgID);
-        messages.add(message);
-      }
+      int msgID = MSGID_SCHEMA_USING_NEW_USER_ATTRS;
+      String message = getMessage(msgID);
+      messages.add(message);
     }
 
 
+    currentConfig = backendCfg;
     return new ConfigChangeResult(resultCode, adminActionRequired, messages);
   }
 
@@ -5668,5 +5433,13 @@
 
     return alerts;
   }
+
+
+
+  private static SchemaBackendCfg getSchemaBackendCfg(ConfigEntry configEntry)
+      throws ConfigException {
+    return BackendConfigManager.getConfiguration(
+         SchemaBackendCfgDefn.getInstance(), configEntry);
+  }
 }
 
diff --git a/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java b/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
index 93f8fc2..5534235 100644
--- a/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
+++ b/opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
@@ -35,63 +35,47 @@
 import com.sleepycat.je.DatabaseException;
 
 import org.opends.server.api.Backend;
-import org.opends.server.api.ConfigurableComponent;
 import org.opends.server.api.MonitorProvider;
-import org.opends.server.config.ConfigAttribute;
-import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.ConfigException;
-import org.opends.server.config.DNConfigAttribute;
+import org.opends.server.config.ConfigEntry;
 import org.opends.server.core.AddOperation;
 import org.opends.server.core.DeleteOperation;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.ModifyOperation;
 import org.opends.server.core.ModifyDNOperation;
 import org.opends.server.core.SearchOperation;
-import org.opends.server.types.BackupConfig;
-import org.opends.server.types.BackupDirectory;
-import org.opends.server.types.CancelledOperationException;
-import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.DN;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.Entry;
-import org.opends.server.types.ErrorLogCategory;
-import org.opends.server.types.ErrorLogSeverity;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.LDIFImportConfig;
-import org.opends.server.types.LDIFExportConfig;
-import org.opends.server.types.RestoreConfig;
-import org.opends.server.types.ResultCode;
+import org.opends.server.core.BackendConfigManager;
 import org.opends.server.util.LDIFException;
+import org.opends.server.util.Validator;
 
 import static org.opends.server.messages.BackendMessages.*;
-import static org.opends.server.messages.MessageHandler.*;
+import static org.opends.server.messages.MessageHandler.getMessage;
 import static org.opends.server.messages.JebMessages.*;
 import static org.opends.server.loggers.Error.logError;
-import static org.opends.server.messages.ConfigMessages.*;
-import static org.opends.server.config.ConfigConstants.ATTR_BACKEND_BASE_DN;
 import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
 import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
-import org.opends.server.types.DebugLogLevel;
+import org.opends.server.types.*;
 import static org.opends.server.util.ServerConstants.OID_SUBTREE_DELETE_CONTROL;
 import static org.opends.server.util.ServerConstants.OID_PAGED_RESULTS_CONTROL;
 import static org.opends.server.util.ServerConstants.OID_MANAGE_DSAIT_CONTROL;
+import org.opends.server.admin.std.server.JEBackendCfg;
+import org.opends.server.admin.std.meta.JEBackendCfgDefn;
+import org.opends.server.admin.server.ConfigurationChangeListener;
 
 /**
  * This is an implementation of a Directory Server Backend which stores entries
  * locally in a Sleepycat JE database.
  */
-public class BackendImpl extends Backend implements ConfigurableComponent
+public class BackendImpl
+     extends Backend
+     implements ConfigurationChangeListener<JEBackendCfg>
 {
 
   /**
-   * The DN of the configuration entry for this backend.
-   */
-  private DN configDN;
-
-  /**
    * The configuration of this JE backend.
    */
   private Config config;
+  private JEBackendCfg currentConfig;
 
   /**
    * The root JE container to use for this backend.
@@ -99,12 +83,6 @@
   private RootContainer rootContainer;
 
   /**
-   * A configurable component to handle changes to the configuration of
-   * the database environment.
-   */
-  private ConfigurableEnvironment configurableEnv = null;
-
-  /**
    * A count of the total operation threads currently in the backend.
    */
   private AtomicInteger threadTotalCount = new AtomicInteger(0);
@@ -125,17 +103,6 @@
    */
   private static HashSet<String> supportedControls;
 
-  /**
-   * The set of configuration attributes associated with the backend in its role
-   * as a configurable component.
-   */
-  private static ArrayList<ConfigAttribute> configAttrs;
-
-  /**
-   * The configuration attribute stub for the backendBaseDN attribute.
-   */
-  private static DNConfigAttribute baseDNStub;
-
 
 
   static
@@ -145,17 +112,6 @@
     supportedControls.add(OID_SUBTREE_DELETE_CONTROL);
     supportedControls.add(OID_PAGED_RESULTS_CONTROL);
     supportedControls.add(OID_MANAGE_DSAIT_CONTROL);
-
-    configAttrs = new ArrayList<ConfigAttribute>();
-
-    // ds-cfg-backendBaseDN configuration attribute.
-    int msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS;
-    baseDNStub = new DNConfigAttribute(ATTR_BACKEND_BASE_DN,
-                                       getMessage(msgID),
-                                       true, true, true);
-
-    configAttrs.add(baseDNStub);
-
   }
 
 
@@ -256,29 +212,17 @@
 
 
   /**
-   * Initializes this backend based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this backend.
-   * @param  baseDNs      The set of base DNs that have been configured for this
-   *                      backend.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
-   *
-   * @throws  InitializationException  If a problem occurs during initialization
-   *                                   that is not related to the server
-   *                                   configuration.
+   * {@inheritDoc}
    */
   public void initializeBackend(ConfigEntry configEntry, DN[] baseDNs)
        throws ConfigException, InitializationException
   {
-    configDN = configEntry.getDN();
+    Validator.ensureNotNull(configEntry);
+    JEBackendCfg backendCfg = getJEBackendCfg(configEntry);
 
     // Initialize a config object
     config = new Config();
-    config.initializeConfig(configEntry, baseDNs);
+    config.initializeConfig(backendCfg, baseDNs);
 
     for (DN dn : baseDNs)
     {
@@ -370,16 +314,11 @@
                                         message, databaseException);
     }
 
-    // Register this backend as a configurable component.
-    DirectoryServer.registerConfigurableComponent(this);
-
-    // Register the database environment as a configurable component.
-    ConfigurableEnvironment configurableEnv =
-        rootContainer.getConfigurableEnvironment();
-    if (configurableEnv != null)
-    {
-      DirectoryServer.registerConfigurableComponent(configurableEnv);
-    }
+    // Register this backend as a change listener.
+    currentConfig = backendCfg;
+    backendCfg.addJEChangeListener(this);
+    backendCfg.addJEChangeListener(config);
+    backendCfg.addJEChangeListener(rootContainer);
   }
 
   /**
@@ -393,17 +332,12 @@
    */
   public void finalizeBackend()
   {
-    // Deregister our configurable components.
-    // TODO: configurableEnv is always null and will not be deregistered.
-    if (configurableEnv != null)
-    {
-      DirectoryServer.deregisterConfigurableComponent(configurableEnv);
-      configurableEnv = null;
-    }
-    DirectoryServer.deregisterConfigurableComponent(this);
+    // Deregister as a change listener.
+    currentConfig.removeJEChangeListener(rootContainer);
+    currentConfig.removeJEChangeListener(config);
+    currentConfig.removeJEChangeListener(this);
 
-    // Deregister our suffixes.
-    // FIXME: Currently assuming every base DN is also a suffix.
+    // Deregister our base DNs.
     for (DN dn : rootContainer.getBaseDNs())
     {
       try
@@ -943,16 +877,7 @@
 
 
   /**
-   * Exports the contents of this backend to LDIF.  This method should only be
-   * called if <CODE>supportsLDIFExport</CODE> returns <CODE>true</CODE>.  Note
-   * that the server will not explicitly initialize this backend before calling
-   * this method.
-   *
-   * @param configEntry  The configuration entry for this backend.
-   * @param baseDNs      The set of base DNs configured for this backend.
-   * @param exportConfig The configuration to use when performing the export.
-   * @throws org.opends.server.types.DirectoryException
-   *          If a problem occurs while performing the LDIF export.
+   * {@inheritDoc}
    */
   public void exportLDIF(ConfigEntry configEntry, DN[] baseDNs,
                          LDIFExportConfig exportConfig)
@@ -1062,16 +987,7 @@
 
 
   /**
-   * Imports information from an LDIF file into this backend.  This method
-   * should only be called if <CODE>supportsLDIFImport</CODE> returns
-   * <CODE>true</CODE>.  Note that the server will not explicitly initialize
-   * this backend before calling this method.
-   *
-   * @param configEntry  The configuration entry for this backend.
-   * @param baseDNs      The set of base DNs configured for this backend.
-   * @param importConfig The configuration to use when performing the import.
-   * @throws DirectoryException If a problem occurs while performing the LDIF
-   *                            import.
+   * {@inheritDoc}
    */
   public void importLDIF(ConfigEntry configEntry, DN[] baseDNs,
                          LDIFImportConfig importConfig)
@@ -1239,11 +1155,14 @@
                              ConfigEntry configEntry, DN[] baseDNs)
        throws InitializationException, ConfigException, DirectoryException
   {
+    JEBackendCfg backendCfg = getJEBackendCfg(configEntry);
+
     // If the backend already has the root container open, we must use the same
     // underlying root container
     boolean openRootContainer = rootContainer == null;
 
-    // If the rootContainer is open, the backend is initizlied by something else
+    // If the rootContainer is open, the backend is initialized by something
+    // else.
     // We can't do any rebuild of system indexes while others are using this
     // backend. Throw error. TODO: Need to make baseDNs disablable.
     if(!openRootContainer && rebuildConfig.includesSystemIndex())
@@ -1259,7 +1178,7 @@
       {
         // Initialize a config object.
         config = new Config();
-        config.initializeConfig(configEntry, baseDNs);
+        config.initializeConfig(backendCfg, baseDNs);
 
         // Open the database environment
         rootContainer = new RootContainer(config, this);
@@ -1316,16 +1235,7 @@
 
 
   /**
-   * Creates a backup of the contents of this backend in a form that may be
-   * restored at a later date if necessary.  This method should only be called
-   * if <CODE>supportsBackup</CODE> returns <CODE>true</CODE>.  Note that the
-   * server will not explicitly initialize this backend before calling this
-   * method.
-   *
-   * @param configEntry  The configuration entry for this backend.
-   * @param backupConfig The configuration to use when performing the backup.
-   * @throws DirectoryException If a problem occurs while performing the
-   *                            backup.
+   * {@inheritDoc}
    */
   public void createBackup(ConfigEntry configEntry, BackupConfig backupConfig)
        throws DirectoryException
@@ -1338,15 +1248,7 @@
 
 
   /**
-   * Removes the specified backup if it is possible to do so.
-   *
-   * @param backupDirectory The backup directory structure with which the
-   *                        specified backup is associated.
-   * @param backupID        The backup ID for the backup to be removed.
-   * @throws DirectoryException If it is not possible to remove the specified
-   *                            backup for some reason (e.g., no such backup
-   *                            exists or there are other backups that are
-   *                            dependent upon it).
+   * {@inheritDoc}
    */
   public void removeBackup(BackupDirectory backupDirectory, String backupID)
        throws DirectoryException
@@ -1359,15 +1261,7 @@
 
 
   /**
-   * Restores a backup of the contents of this backend.  This method should only
-   * be called if <CODE>supportsRestore</CODE> returns <CODE>true</CODE>.  Note
-   * that the server will not explicitly initialize this backend before calling
-   * this method.
-   *
-   * @param configEntry   The configuration entry for this backend.
-   * @param restoreConfig The configuration to use when performing the restore.
-   * @throws DirectoryException If a problem occurs while performing the
-   *                            restore.
+   * {@inheritDoc}
    */
   public void restoreBackup(ConfigEntry configEntry,
                             RestoreConfig restoreConfig)
@@ -1381,107 +1275,23 @@
 
 
   /**
-   * Retrieves the DN of the configuration entry with which this component is
-   * associated.
-   *
-   * @return The DN of the configuration entry with which this component is
-   *         associated.
+   * {@inheritDoc}
    */
-  public DN getConfigurableComponentEntryDN()
+  public boolean isConfigurationChangeAcceptable(
+       JEBackendCfg cfg,
+       List<String> unacceptableReasons)
   {
-    return configDN;
+    // This listener handles only the changes to the base DNs.
+    // The base DNs are checked by the backend config manager.
+    return true;
   }
 
 
 
   /**
-   * Retrieves the set of configuration attributes that are associated with this
-   * configurable component.
-   *
-   * @return The set of configuration attributes that are associated with this
-   *         configurable component.
+   * {@inheritDoc}
    */
-  public List<ConfigAttribute> getConfigurationAttributes()
-  {
-    return configAttrs;
-  }
-
-
-
-  /**
-   * Indicates whether the provided configuration entry has an acceptable
-   * configuration for this component.  If it does not, then detailed
-   * information about the problem(s) should be added to the provided list.
-   *
-   * @param configEntry         The configuration entry for which to make the
-   *                            determination.
-   * @param unacceptableReasons A list that can be used to hold messages about
-   *                            why the provided entry does not have an
-   *                            acceptable configuration.
-   * @return <CODE>true</CODE> if the provided entry has an acceptable
-   *         configuration for this component, or <CODE>false</CODE> if not.
-   */
-  public boolean hasAcceptableConfiguration(ConfigEntry configEntry,
-                                            List<String> unacceptableReasons)
-  {
-    DN[] baseDNs = null;
-    boolean acceptable = true;
-
-    try
-    {
-      DNConfigAttribute baseDNAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(baseDNStub);
-      if (baseDNAttr == null)
-      {
-        int msgID = MSGID_CONFIG_BACKEND_NO_BASE_DNS;
-        String message = getMessage(msgID, String.valueOf(configEntry.getDN()));
-        unacceptableReasons.add(message);
-      }
-      else
-      {
-        baseDNs = baseDNAttr.activeValues().toArray(new DN[0]);
-      }
-    }
-    catch (ConfigException e)
-    {
-      unacceptableReasons.add(e.getMessage());
-      acceptable = false;
-    }
-
-    Config newConfig = new Config();
-    try
-    {
-      newConfig.initializeConfig(configEntry, baseDNs);
-    }
-    catch (ConfigException e)
-    {
-      unacceptableReasons.add(e.getMessage());
-      acceptable = false;
-    }
-
-    return acceptable;
-  }
-
-
-
-  /**
-   * Makes a best-effort attempt to apply the configuration contained in the
-   * provided entry.  Information about the result of this processing should be
-   * added to the provided message list.  Information should always be added to
-   * this list if a configuration change could not be applied.  If detailed
-   * results are requested, then information about the changes applied
-   * successfully (and optionally about parameters that were not changed) should
-   * also be included.
-   *
-   * @param configEntry     The entry containing the new configuration to apply
-   *                        for this component.
-   * @param detailedResults Indicates whether detailed information about the
-   *                        processing should be added to the list.
-   *
-   * @return  Information about the result of the configuration update.
-   */
-  public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry,
-                                                  boolean detailedResults)
+  public ConfigChangeResult applyConfigurationChange(JEBackendCfg cfg)
   {
     ConfigChangeResult ccr;
     ResultCode resultCode = ResultCode.SUCCESS;
@@ -1489,22 +1299,14 @@
 
     try
     {
-      DN[] baseDNs = null;
-
-      DNConfigAttribute baseDNAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(baseDNStub);
-
-      baseDNs = baseDNAttr.activeValues().toArray(new DN[0]);
-
-      // Create a new Config object.
-      Config newConfig = new Config();
-      newConfig.initializeConfig(configEntry, baseDNs);
+      DN[] baseDNs = new DN[cfg.getBackendBaseDN().size()];
+      baseDNs = cfg.getBackendBaseDN().toArray(baseDNs);
 
       // Check for changes to the base DNs.
       for (DN baseDN : config.getBaseDNs())
       {
         boolean found = false;
-        for (DN dn : newConfig.getBaseDNs())
+        for (DN dn : baseDNs)
         {
           if (dn.equals(baseDN))
           {
@@ -1523,7 +1325,7 @@
         }
       }
 
-      for (DN baseDN : newConfig.getBaseDNs())
+      for (DN baseDN : baseDNs)
       {
         if (!rootContainer.getBaseDNs().contains(baseDN))
         {
@@ -1551,11 +1353,8 @@
         }
       }
 
-      // Apply new JE configuration
-      rootContainer.applyNewConfig(config);
-
       // Put the new configuration in place.
-      config = newConfig;
+      currentConfig = cfg;
     }
     catch (Exception e)
     {
@@ -1601,4 +1400,20 @@
     config.initializeConfig(configEntry, baseDNs);
     EnvManager.removeFiles(config.getBackendDirectory().getPath());
   }
+
+  /**
+   * Gets the JE backend configuration corresponding to a JE
+   * backend config entry.
+   *
+   * @param configEntry A JE backend config entry.
+   * @return Returns the JE backend configuration.
+   * @throws ConfigException If the config entry could not be decoded.
+   */
+  static JEBackendCfg getJEBackendCfg(ConfigEntry configEntry)
+      throws ConfigException {
+    return BackendConfigManager.getConfiguration(
+         JEBackendCfgDefn.getInstance(), configEntry);
+  }
+
+
 }
diff --git a/opends/src/server/org/opends/server/backends/jeb/Config.java b/opends/src/server/org/opends/server/backends/jeb/Config.java
index d878c76..299f7c5 100644
--- a/opends/src/server/org/opends/server/backends/jeb/Config.java
+++ b/opends/src/server/org/opends/server/backends/jeb/Config.java
@@ -28,55 +28,42 @@
 
 import static org.opends.server.messages.MessageHandler.getMessage;
 import static org.opends.server.messages.ConfigMessages.
-     MSGID_CONFIG_DESCRIPTION_BACKEND_DIRECTORY;
-import static org.opends.server.messages.ConfigMessages.
-     MSGID_CONFIG_DESCRIPTION_BACKEND_MODE;
-import static org.opends.server.messages.ConfigMessages.
     MSGID_CONFIG_BACKEND_MODE_INVALID;
 import static org.opends.server.messages.ConfigMessages.
     MSGID_CONFIG_BACKEND_INSANE_MODE;
-import static org.opends.server.config.ConfigConstants.ATTR_BACKEND_DIRECTORY;
-import static org.opends.server.config.ConfigConstants.ATTR_BACKEND_MODE;
-import static org.opends.server.messages.ConfigMessages.
-     MSGID_CONFIG_BACKEND_NO_DIRECTORY;
 import static org.opends.server.messages.JebMessages.*;
 import static org.opends.server.loggers.Error.logError;
-import static org.opends.server.util.ServerConstants.*;
 import static org.opends.server.util.StaticUtils.getFileForPath;
 
-import org.opends.server.config.BooleanConfigAttribute;
 import org.opends.server.config.ConfigConstants;
 import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.ConfigException;
 import org.opends.server.config.IntegerConfigAttribute;
-import org.opends.server.config.IntegerWithUnitConfigAttribute;
 import org.opends.server.config.MultiChoiceConfigAttribute;
 import org.opends.server.config.StringConfigAttribute;
 import org.opends.server.core.DirectoryServer;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DN;
-import org.opends.server.types.ErrorLogCategory;
-import org.opends.server.types.ErrorLogSeverity;
-import org.opends.server.types.RDN;
-import org.opends.server.types.FilePermission;
 import com.sleepycat.je.EnvironmentConfig;
 
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.List;
+import java.util.ArrayList;
 import java.util.concurrent.ConcurrentHashMap;
 import java.io.File;
 
 import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
 import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
-import org.opends.server.types.DebugLogLevel;
+import org.opends.server.types.*;
+import org.opends.server.admin.std.server.JEBackendCfg;
+import org.opends.server.admin.server.ConfigurationChangeListener;
 
 /**
  * This class represents the configuration of a JE backend.
  */
 public class Config
+     implements ConfigurationChangeListener<JEBackendCfg>
 {
 
   /**
@@ -87,13 +74,6 @@
        ConfigConstants.NAME_PREFIX_CFG + "je-index";
 
   /**
-   * The name of the object class which configures
-   * the database.
-   */
-  public static final String OBJECT_CLASS_CONFIG_DATABASE =
-       ConfigConstants.NAME_PREFIX_CFG + "je-database";
-
-  /**
    * The name of the attribute which configures
    * the attribute type of an attribute index.
    */
@@ -123,14 +103,6 @@
 
   /**
    * The name of the attribute which configures
-   * the backend index entry limit.
-   */
-  public static final String ATTR_BACKEND_INDEX_ENTRY_LIMIT =
-       ConfigConstants.NAME_PREFIX_CFG + "backend-index-entry-limit";
-
-
-  /**
-   * The name of the attribute which configures
    * the subtree delete size limit.
    */
   public static final String ATTR_SUBTREE_DELETE_SIZE_LIMIT =
@@ -196,45 +168,6 @@
 
 
   /**
-   * A set of units and their multipliers for configuration attributes
-   * representing a number of bytes.
-   */
-  private static HashMap<String, Double> memoryUnits;
-
-  /**
-   * A set of units and their multipliers for configuration attributes
-   * representing a period of time in milliseconds.
-   */
-  private static HashMap<String, Double> timeUnits;
-
-  static
-  {
-    memoryUnits = new HashMap<String, Double>();
-    memoryUnits.put(SIZE_UNIT_BYTES_ABBR, 1D);
-    memoryUnits.put(SIZE_UNIT_BYTES_FULL, 1D);
-    memoryUnits.put(SIZE_UNIT_KILOBYTES_ABBR, 1000D);
-    memoryUnits.put(SIZE_UNIT_KILOBYTES_FULL, 1000D);
-    memoryUnits.put(SIZE_UNIT_MEGABYTES_ABBR, 1000000D);
-    memoryUnits.put(SIZE_UNIT_MEGABYTES_FULL, 1000000D);
-    memoryUnits.put(SIZE_UNIT_GIGABYTES_ABBR, 1000000000D);
-    memoryUnits.put(SIZE_UNIT_GIGABYTES_FULL, 1000000000D);
-    memoryUnits.put(SIZE_UNIT_KIBIBYTES_ABBR, 1024D);
-    memoryUnits.put(SIZE_UNIT_KIBIBYTES_FULL, 1024D);
-    memoryUnits.put(SIZE_UNIT_MEBIBYTES_ABBR, (double) (1024 * 1024));
-    memoryUnits.put(SIZE_UNIT_MEBIBYTES_FULL, (double) (1024 * 1024));
-    memoryUnits.put(SIZE_UNIT_GIBIBYTES_ABBR, (double) (1024 * 1024 * 1024));
-    memoryUnits.put(SIZE_UNIT_GIBIBYTES_FULL, (double) (1024 * 1024 * 1024));
-
-    timeUnits = new HashMap<String, Double>();
-    timeUnits.put(TIME_UNIT_MILLISECONDS_ABBR, 1D);
-    timeUnits.put(TIME_UNIT_MILLISECONDS_FULL, 1D);
-    timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1000D);
-    timeUnits.put(TIME_UNIT_SECONDS_FULL, 1000D);
-    timeUnits.put(TIME_UNIT_MINUTES_ABBR, (double) (60 * 1000));
-    timeUnits.put(TIME_UNIT_MINUTES_FULL, (double) (60 * 1000));
-  }
-
-  /**
    * The set of base DNs.
    */
   private DN[] baseDNs = null;
@@ -248,76 +181,23 @@
    * The backend directory permission mode. By default, owner has read, write
    * and execute permissions on the database directory.
    */
-  private FilePermission backendPermission = new FilePermission(0700);
+  private FilePermission backendPermission;
 
   /**
-   * Number of times we should retry database transactions that get aborted
-   * due to deadlock.
+   * The current configuration.
    */
-  private int deadlockRetryLimit = 0;
-
-  /**
-   * The backend index entry limit, zero means unlimited.
-   */
-  private int backendIndexEntryLimit = 0;
-
-  /**
-   * The maximum number of entries to process in a single pass through the LDIF
-   * file.
-   */
-  private int importPassSize = Integer.MAX_VALUE;
-
-  /**
-   * The subtree delete size limit, zero means unlimited.
-   */
-  private int subtreeDeleteSizeLimit = 0;
-
-  /**
-   * The memory available for import buffering.
-   */
-  private long importBufferSize = 100*1024*1024;
-
-  /**
-   * The pathname of the directory for import temporary files.
-   */
-  private String importTempDirectory = "importTmp";
+  private JEBackendCfg currentConfig;
 
   /**
    * The set of configured attribute indexes.
    */
   private Map<AttributeType, IndexConfig> indexConfigMap = null;
 
-
-
-  /**
-   * The DN of the JE database environment configuration entry, if any.
-   */
-  private DN envConfigDN = null;
-
   /**
    * The JE environment config.
    */
   private EnvironmentConfig envConfig = null;
 
-  /**
-   * The import queue size.
-   */
-  private int importQueueSize = 100;
-
-  /**
-   * The number of import threads.
-   */
-  private int importThreadCount = 8;
-
-  /**
-   * The database cache preload time limit in milliseconds.
-   */
-  private long preloadTimeLimit = 0;
-
-  /**
-   * Whether entries should be compressed in the database.
-   */
-  private boolean entriesCompressed = false;
 
 
   /**
@@ -331,28 +211,46 @@
   public void initializeConfig(ConfigEntry configEntry, DN[] baseDNs)
        throws ConfigException
   {
-    StringConfigAttribute stub;
-    IntegerConfigAttribute intStub;
-    IntegerWithUnitConfigAttribute intWithUnitStub;
+    initializeConfig(BackendImpl.getJEBackendCfg(configEntry), configEntry,
+                     baseDNs);
+  }
 
+
+  /**
+   * Initialize this JE backend configuration from a configuration entry.
+   *
+   * @param  cfg          The backend configuration entry.
+   * @param  baseDNs      The set of base DNs that have been configured for this
+   *                      backend.
+   * @throws ConfigException If there is an error in the configuration entry.
+   */
+  public void initializeConfig(JEBackendCfg cfg, DN[] baseDNs)
+       throws ConfigException
+  {
+    initializeConfig(cfg, DirectoryServer.getConfigEntry(cfg.dn()), baseDNs);
+  }
+
+
+  /**
+   * Initialize this JE backend configuration from a configuration object
+   * and its configuration entry.
+   *
+   * @param  cfg          The backend configuration object.
+   * @param  configEntry  The backend configuration entry.
+   * @param  baseDNs      The set of base DNs that have been configured for this
+   *                      backend.
+   * @throws ConfigException If there is an error in the configuration entry.
+   */
+  private void initializeConfig(JEBackendCfg cfg, ConfigEntry configEntry,
+                                DN[] baseDNs)
+       throws ConfigException
+  {
     // Set the base DNs.
     this.baseDNs = baseDNs;
 
     // Determine the backend database directory.
-    // Required, single-valued config attribute requiring admin action on change
-    String msg = getMessage(MSGID_CONFIG_DESCRIPTION_BACKEND_DIRECTORY);
-    stub =
-         new StringConfigAttribute(ATTR_BACKEND_DIRECTORY,
-                                   msg, true, false, true);
-    StringConfigAttribute backendDirectoryAttr = (StringConfigAttribute)
-         configEntry.getConfigAttribute(stub);
-    if (backendDirectoryAttr == null)
-    {
-      int msgID = MSGID_CONFIG_BACKEND_NO_DIRECTORY;
-      String message = getMessage(msgID, configEntry.getDN().toString());
-      throw new ConfigException(msgID, message);
-    }
-    backendDirectory = getFileForPath(backendDirectoryAttr.activeValue());
+    backendDirectory = getFileForPath(cfg.getBackendDirectory());
+
     //Make sure the directory is valid.
     if (!backendDirectory.isDirectory())
     {
@@ -361,177 +259,34 @@
       throw new ConfigException(MSGID_JEB_DIRECTORY_INVALID, message);
     }
 
-    // ds-cfg-backend-mode
-    // Optional, single-valued config attribute requiring admin action on change
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_BACKEND_MODE);
-    stub =
-        new StringConfigAttribute(ATTR_BACKEND_MODE, msg, false,false, true);
-    StringConfigAttribute backendModeAttr = (StringConfigAttribute)
-         configEntry.getConfigAttribute(stub);
-    if (backendModeAttr != null)
+    FilePermission newBackendPermission;
+    try
     {
-      FilePermission newBackendPermission;
-      try
-      {
-        newBackendPermission = FilePermission.decodeUNIXMode(
-            backendModeAttr.activeValue());
-      }
-      catch(Exception e)
-      {
-        int msgID = MSGID_CONFIG_BACKEND_MODE_INVALID;
-        String message = getMessage(msgID, configEntry.getDN().toString());
-        throw new ConfigException(msgID, message);
-      }
-
-      //Make sure the mode will allow the server itself access to
-      //the database
-      if(!newBackendPermission.isOwnerWritable() ||
-           !newBackendPermission.isOwnerReadable() ||
-           !newBackendPermission.isOwnerExecutable())
-      {
-        int msgID = MSGID_CONFIG_BACKEND_INSANE_MODE;
-        String message = getMessage(msgID);
-        throw new ConfigException(msgID, message);
-      }
-      else
-      {
-        backendPermission = newBackendPermission;
-      }
+      newBackendPermission =
+           FilePermission.decodeUNIXMode(cfg.getBackendMode());
+    }
+    catch(Exception e)
+    {
+      int msgID = MSGID_CONFIG_BACKEND_MODE_INVALID;
+      String message = getMessage(msgID, cfg.dn().toString());
+      throw new ConfigException(msgID, message);
     }
 
-    // ds-cfg-backendIndexEntryLimit
-    // Optional, single-valued config attribute requiring admin action on change
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_BACKEND_INDEX_ENTRY_LIMIT);
-    intStub =
-         new IntegerConfigAttribute(ATTR_BACKEND_INDEX_ENTRY_LIMIT, msg, false,
-                                    false, true, true, 0, false, 0);
-    IntegerConfigAttribute entryLimitAttr = (IntegerConfigAttribute)
-         configEntry.getConfigAttribute(intStub);
-    if (entryLimitAttr != null)
+    //Make sure the mode will allow the server itself access to
+    //the database
+    if(!newBackendPermission.isOwnerWritable() ||
+         !newBackendPermission.isOwnerReadable() ||
+         !newBackendPermission.isOwnerExecutable())
     {
-      backendIndexEntryLimit = entryLimitAttr.activeIntValue();
+      int msgID = MSGID_CONFIG_BACKEND_INSANE_MODE;
+      String message = getMessage(msgID);
+      throw new ConfigException(msgID, message);
     }
-
-    // ds-cfg-backendSubtreeDeleteSizeLimit
-    // Optional, single-valued config attribute
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_SUBTREE_DELETE_SIZE_LIMIT);
-    intStub =
-         new IntegerConfigAttribute(ATTR_SUBTREE_DELETE_SIZE_LIMIT, msg, false,
-                                    false, false, true, 0, false, 0);
-    IntegerConfigAttribute sdslAttr = (IntegerConfigAttribute)
-         configEntry.getConfigAttribute(intStub);
-    if (sdslAttr != null)
+    else
     {
-      subtreeDeleteSizeLimit = sdslAttr.activeIntValue();
+      backendPermission = newBackendPermission;
     }
 
-    // Determine the directory for import temporary files.
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_IMPORT_TEMP_DIRECTORY);
-    stub =
-         new StringConfigAttribute(ATTR_IMPORT_TEMP_DIRECTORY,
-                                   msg, false, false, false);
-    StringConfigAttribute importTempDirAttr = (StringConfigAttribute)
-         configEntry.getConfigAttribute(stub);
-    if (importTempDirAttr != null)
-    {
-      this.importTempDirectory = importTempDirAttr.activeValue();
-    }
-
-    // Determine the memory available for import buffering.
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_IMPORT_BUFFER_SIZE);
-    intWithUnitStub =
-         new IntegerWithUnitConfigAttribute(ATTR_IMPORT_BUFFER_SIZE, msg,
-                                            false, memoryUnits,
-                                            true, 10*1024*1024, false,
-                                            0);
-    IntegerWithUnitConfigAttribute importBufferSizeAttr =
-         (IntegerWithUnitConfigAttribute)
-         configEntry.getConfigAttribute(intWithUnitStub);
-    if (importBufferSizeAttr != null)
-    {
-      importBufferSize = importBufferSizeAttr.activeCalculatedValue();
-    }
-
-    // Determine the import queue size.
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_IMPORT_QUEUE_SIZE);
-    intStub =
-         new IntegerConfigAttribute(ATTR_IMPORT_QUEUE_SIZE, msg, false,
-                                    false, false, true, 1, false, 0);
-    IntegerConfigAttribute a = (IntegerConfigAttribute)
-         configEntry.getConfigAttribute(intStub);
-    if (a != null)
-    {
-      importQueueSize = a.activeIntValue();
-    }
-
-
-    // Determine the number of import threads.
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_IMPORT_THREAD_COUNT);
-    intStub =
-         new IntegerConfigAttribute(ATTR_IMPORT_THREAD_COUNT, msg, false,
-                                    false, false, true, 1, false, 0);
-    a = (IntegerConfigAttribute)
-         configEntry.getConfigAttribute(intStub);
-    if (a != null)
-    {
-      importThreadCount = a.activeIntValue();
-    }
-
-
-    // Determine the import pass size.
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_IMPORT_PASS_SIZE);
-    intStub = new IntegerConfigAttribute(ATTR_IMPORT_PASS_SIZE, msg, true,
-                                         false, false, true, 0, true,
-                                         Integer.MAX_VALUE);
-    a = (IntegerConfigAttribute)
-         configEntry.getConfigAttribute(intStub);
-    if (a != null)
-    {
-      importPassSize = a.activeIntValue();
-    }
-
-
-    // Determine the database cache preload time limit.
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_PRELOAD_TIME_LIMIT);
-    intWithUnitStub =
-         new IntegerWithUnitConfigAttribute(ATTR_PRELOAD_TIME_LIMIT, msg,
-                                            false, timeUnits,
-                                            true, 0, false, 0);
-    IntegerWithUnitConfigAttribute preloadTimeLimitAttr =
-         (IntegerWithUnitConfigAttribute)
-         configEntry.getConfigAttribute(intWithUnitStub);
-    if (preloadTimeLimitAttr != null)
-    {
-      preloadTimeLimit = preloadTimeLimitAttr.activeCalculatedValue();
-    }
-
-
-    // Determine whether entries should be compressed in the database.
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_ENTRIES_COMPRESSED);
-    BooleanConfigAttribute booleanStub =
-         new BooleanConfigAttribute(ATTR_ENTRIES_COMPRESSED, msg, false);
-    BooleanConfigAttribute entriesCompressedAttr =
-         (BooleanConfigAttribute)
-         configEntry.getConfigAttribute(booleanStub);
-    if (entriesCompressedAttr != null)
-    {
-      entriesCompressed = entriesCompressedAttr.activeValue();
-    }
-
-
-    // Determine the deadlock retry limit.
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_DEADLOCK_RETRY_LIMIT);
-    intStub =
-         new IntegerConfigAttribute(ATTR_DEADLOCK_RETRY_LIMIT, msg, false,
-                                    false, false, true, 0, false, 0);
-    a = (IntegerConfigAttribute)
-         configEntry.getConfigAttribute(intStub);
-    if (a != null)
-    {
-      deadlockRetryLimit = a.activeIntValue();
-    }
-
-
     indexConfigMap = new HashMap<AttributeType, IndexConfig>();
 
     // Create an RDN for cn=Index.
@@ -551,31 +306,12 @@
     ConcurrentHashMap<DN, ConfigEntry> children = configEntry.getChildren();
     for (ConfigEntry childConfigEntry : children.values())
     {
-      if (childConfigEntry.hasObjectClass(OBJECT_CLASS_CONFIG_DATABASE))
-      {
-        // This is a database config entry.
-        if (envConfig != null)
-        {
-          int    msgID   = MSGID_JEB_DUPLICATE_CONFIG_ENTRY;
-          String message = getMessage(msgID,
-                                      childConfigEntry.getDN().toString(),
-                                      OBJECT_CLASS_CONFIG_DATABASE);
-          logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.MILD_ERROR,
-                   message, msgID);
-        }
-        else
-        {
-          envConfig =
-               ConfigurableEnvironment.parseConfigEntry(childConfigEntry);
-          envConfigDN = childConfigEntry.getDN();
-        }
-      }
-      else if (childConfigEntry.getDN().getRDN().equals(indexRDN))
+      if (childConfigEntry.getDN().getRDN().equals(indexRDN))
       {
         // This is the cn=Index branch entry.
 
         // Determine the index configuration.
-        configureIndexEntries(indexConfigMap, backendIndexEntryLimit,
+        configureIndexEntries(indexConfigMap, cfg.getBackendIndexEntryLimit(),
                               childConfigEntry.getChildren().values());
       }
       else
@@ -588,11 +324,9 @@
       }
     }
 
-    // Create a database configuration with defaults if we don't have one.
-    if (envConfig == null)
-    {
-      envConfig = ConfigurableEnvironment.defaultConfig();
-    }
+    envConfig = ConfigurableEnvironment.parseConfigEntry(cfg);
+
+    currentConfig = cfg;
   }
 
   /**
@@ -828,7 +562,7 @@
    */
   public int getDeadlockRetryLimit()
   {
-    return deadlockRetryLimit;
+    return currentConfig.getBackendDeadlockRetryLimit();
   }
 
   /**
@@ -838,7 +572,7 @@
    */
   public int getBackendIndexEntryLimit()
   {
-    return backendIndexEntryLimit;
+    return currentConfig.getBackendIndexEntryLimit();
   }
 
   /**
@@ -848,7 +582,7 @@
    */
   public int getSubtreeDeleteSizeLimit()
   {
-    return subtreeDeleteSizeLimit;
+    return currentConfig.getBackendSubtreeDeleteSizeLimit();
   }
 
   /**
@@ -868,7 +602,7 @@
    */
   public String getImportTempDirectory()
   {
-    return importTempDirectory;
+    return currentConfig.getBackendImportTempDirectory();
   }
 
   /**
@@ -877,7 +611,7 @@
    */
    public long getImportBufferSize()
   {
-    return importBufferSize;
+    return currentConfig.getBackendImportBufferSize();
   }
 
   /**
@@ -886,7 +620,7 @@
    */
   public int getImportQueueSize()
   {
-    return importQueueSize;
+    return currentConfig.getBackendImportQueueSize();
   }
 
   /**
@@ -895,7 +629,7 @@
    */
   public int getImportThreadCount()
   {
-    return importThreadCount;
+    return currentConfig.getBackendImportThreadCount();
   }
 
   /**
@@ -907,7 +641,7 @@
    */
   public int getImportPassSize()
   {
-    return importPassSize;
+    return currentConfig.getBackendImportPassSize();
   }
 
 
@@ -919,7 +653,7 @@
    */
   public boolean isEntriesCompressed()
   {
-    return entriesCompressed;
+    return currentConfig.isBackendEntriesCompressed();
   }
 
 
@@ -930,21 +664,122 @@
    */
   public long getPreloadTimeLimit()
   {
-    return preloadTimeLimit;
+    return currentConfig.getBackendPreloadTimeLimit();
   }
 
 
 
   /**
-   * Get the DN of the configuration entry for the JE environment, if any.
-   *
-   * @return The configuration entry DN, or null if there is none.
+   * {@inheritDoc}
    */
-  public DN getEnvConfigDN()
+  public boolean isConfigurationChangeAcceptable(
+       JEBackendCfg cfg,
+       List<String> unacceptableReasons)
   {
-    return envConfigDN;
+    boolean acceptable = true;
+
+    // This listener does not handle the changes to JE properties.
+
+    //Make sure the directory is valid.
+    if (!backendDirectory.isDirectory())
+    {
+      int msgID = MSGID_JEB_DIRECTORY_INVALID;
+      String message = getMessage(msgID, backendDirectory.getPath());
+      unacceptableReasons.add(message);
+      acceptable = false;
+    }
+
+    try
+    {
+      FilePermission newBackendPermission =
+           FilePermission.decodeUNIXMode(cfg.getBackendMode());
+
+      //Make sure the mode will allow the server itself access to
+      //the database
+      if(!newBackendPermission.isOwnerWritable() ||
+           !newBackendPermission.isOwnerReadable() ||
+           !newBackendPermission.isOwnerExecutable())
+      {
+        int msgID = MSGID_CONFIG_BACKEND_INSANE_MODE;
+        String message = getMessage(msgID);
+        unacceptableReasons.add(message);
+        acceptable = false;
+      }
+    }
+    catch(Exception e)
+    {
+      int msgID = MSGID_CONFIG_BACKEND_MODE_INVALID;
+      String message = getMessage(msgID, cfg.dn().toString());
+      unacceptableReasons.add(message);
+      acceptable = false;
+    }
+
+    return acceptable;
   }
 
 
 
+  /**
+   * {@inheritDoc}
+   */
+  public ConfigChangeResult applyConfigurationChange(JEBackendCfg cfg)
+  {
+    ConfigChangeResult ccr;
+    ResultCode resultCode = ResultCode.SUCCESS;
+    ArrayList<String> messages = new ArrayList<String>();
+
+    try
+    {
+      // Set the base DNs.
+      baseDNs = new DN[cfg.getBackendBaseDN().size()];
+      baseDNs = cfg.getBackendBaseDN().toArray(baseDNs);
+
+      // Determine the backend database directory.
+      backendDirectory = getFileForPath(cfg.getBackendDirectory());
+
+      FilePermission newPermission =
+           FilePermission.decodeUNIXMode(cfg.getBackendMode());
+
+      // Check for changes to the database directory permissions
+      FilePermission oldPermission = backendPermission;
+
+      if(FilePermission.canSetPermissions() &&
+          !FilePermission.toUNIXMode(oldPermission).equals(
+          FilePermission.toUNIXMode(newPermission)))
+      {
+        try
+        {
+          if(!FilePermission.setPermissions(backendDirectory,
+                                            newPermission))
+          {
+            throw new Exception();
+          }
+        }
+        catch(Exception e)
+        {
+          // Log a warning that the permissions were not set.
+          int msgID = MSGID_JEB_SET_PERMISSIONS_FAILED;
+          String message = getMessage(msgID,
+                                      backendDirectory.getPath());
+          logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_WARNING,
+                   message, msgID);
+        }
+      }
+
+      backendPermission = newPermission;
+
+      currentConfig = cfg;
+    }
+    catch (Exception e)
+    {
+      messages.add(e.getMessage());
+      ccr = new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(),
+                                   false, messages);
+      return ccr;
+    }
+
+    ccr = new ConfigChangeResult(resultCode, false, messages);
+    return ccr;
+  }
+
 }
diff --git a/opends/src/server/org/opends/server/backends/jeb/ConfigurableEnvironment.java b/opends/src/server/org/opends/server/backends/jeb/ConfigurableEnvironment.java
index a08561f..1684bc4 100644
--- a/opends/src/server/org/opends/server/backends/jeb/ConfigurableEnvironment.java
+++ b/opends/src/server/org/opends/server/backends/jeb/ConfigurableEnvironment.java
@@ -26,52 +26,30 @@
  */
 package org.opends.server.backends.jeb;
 
-import com.sleepycat.je.Environment;
 import com.sleepycat.je.EnvironmentConfig;
-import com.sleepycat.je.config.ConfigParam;
-import com.sleepycat.je.config.EnvironmentParams;
 
-import org.opends.server.api.ConfigurableComponent;
-import org.opends.server.config.BooleanConfigAttribute;
-import org.opends.server.config.IntegerConfigAttribute;
-import org.opends.server.config.IntegerWithUnitConfigAttribute;
-import org.opends.server.config.ConfigAttribute;
 import org.opends.server.config.ConfigConstants;
-import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.ConfigException;
-import org.opends.server.config.StringConfigAttribute;
-import org.opends.server.core.DirectoryServer;
-import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.DN;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.DebugLogLevel;
 
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
+import java.lang.reflect.Method;
 
-import static org.opends.server.messages.MessageHandler.getMessage;
-import static org.opends.server.messages.JebMessages.*;
-import static org.opends.server.util.ServerConstants.*;
+import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
+import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
+import org.opends.server.admin.std.server.JEBackendCfg;
+import org.opends.server.admin.std.meta.JEBackendCfgDefn;
+import org.opends.server.admin.DurationPropertyDefinition;
+import org.opends.server.admin.BooleanPropertyDefinition;
+import org.opends.server.admin.PropertyDefinition;
 
 /**
- * This class represents a JE environment handle that can be configured by the
- * Directory Server as a configurable component.
+ * This class maps JE properties to configuration attributes.
  */
-public class ConfigurableEnvironment implements ConfigurableComponent
+public class ConfigurableEnvironment
 {
   /**
-   * The DN of the configuration entry with which the environment is
-   * associated.
-   */
-  private DN configDN;
-
-  /**
-   * The JE environment handle.
-   */
-  private Environment environment;
-
-  /**
    * The name of the attribute which configures the database cache size as a
    * percentage of Java VM heap size.
    */
@@ -183,208 +161,172 @@
 
 
   /**
-   * A map of JE property names to their associated configuration attribute.
+   * A map of JE property names to the corresponding configuration attribute.
    */
-  private static HashMap<String, ConfigAttribute> configAttrMap =
-       new HashMap<String, ConfigAttribute>();
+  private static HashMap<String, String> attrMap =
+       new HashMap<String, String>();
 
   /**
-   * A list of registered environment configuration attributes.
+   * A map of configuration attribute names to the corresponding configuration
+   * object getter method.
    */
-  private static ArrayList<ConfigAttribute> configAttrList =
-       new ArrayList<ConfigAttribute>();
+  private static HashMap<String,Method> methodMap =
+       new HashMap<String, Method>();
 
-
-  private static final ConfigAttribute CONFIG_ATTR_CACHE_PERCENT;
-  private static final ConfigAttribute CONFIG_ATTR_CACHE_SIZE;
-  private static final ConfigAttribute CONFIG_ATTR_TXN_NO_SYNC;
-  private static final ConfigAttribute CONFIG_ATTR_TXN_WRITE_NO_SYNC;
-  private static final ConfigAttribute CONFIG_ATTR_RUN_CLEANER;
-  private static final ConfigAttribute CONFIG_ATTR_CLEANER_MIN_UTILIZATION;
-  private static final ConfigAttribute CONFIG_ATTR_EVICTOR_LRU_ONLY;
-  private static final ConfigAttribute CONFIG_ATTR_EVICTOR_NODES_PER_SCAN;
-  private static final ConfigAttribute CONFIG_ATTR_LOG_FILE_MAX;
-  private static final ConfigAttribute CONFIG_ATTR_LOGGING_FILE_HANDLER_ON;
-  private static final ConfigAttribute CONFIG_ATTR_LOGGING_LEVEL;
-  private static final ConfigAttribute CONFIG_ATTR_CHECKPOINTER_BYTES_INTERVAL;
-  private static final ConfigAttribute CONFIG_ATTR_CHECKPOINTER_WAKEUP_INTERVAL;
-  private static final ConfigAttribute CONFIG_ATTR_NUM_LOCK_TABLES;
-  private static final ConfigAttribute CONFIG_ATTR_NUM_CLEANER_THREADS;
+  /**
+   * A map of configuration attribute names to the corresponding configuration
+   * PropertyDefinition.
+   */
+  private static HashMap<String,PropertyDefinition> defnMap =
+       new HashMap<String, PropertyDefinition>();
 
 
 
   /**
-   * Register an environment property and its associated configuration
-   * attribute.
+   * Register a JE property and its corresponding configuration attribute.
    *
    * @param propertyName The name of the JE property to be registered.
-   * @param configAttr   The configuration attribute associated with the
-   *                     property.
+   * @param attrName     The name of the configuration attribute associated
+   *                     with the property.
+   * @throws Exception   If there is an error in the attribute name.
    */
-  private static void registerPropertyAttribute(String propertyName,
-                                                ConfigAttribute configAttr)
+  private static void registerProp(String propertyName, String attrName)
+       throws Exception
   {
-    configAttrMap.put(propertyName, configAttr);
-    configAttrList.add(configAttr);
+    // Strip off NAME_PREFIX_CFG.
+    String baseName = attrName.substring(7);
+
+
+    // Convert hyphenated to camel case.
+    StringBuilder builder = new StringBuilder();
+    boolean capitalize = true;
+    for (int i = 0; i < baseName.length(); i++)
+    {
+      char c = baseName.charAt(i);
+      if (c == '-')
+      {
+        capitalize = true;
+      }
+      else
+      {
+        if (capitalize)
+        {
+          builder.append(Character.toUpperCase(c));
+        }
+        else
+        {
+          builder.append(c);
+        }
+        capitalize = false;
+      }
+    }
+    String methodBaseName = builder.toString();
+
+    Class configClass = JEBackendCfg.class;
+    JEBackendCfgDefn defn = JEBackendCfgDefn.getInstance();
+    Class defClass = defn.getClass();
+
+    PropertyDefinition propDefn =
+         (PropertyDefinition)defClass.getMethod("get" + methodBaseName +
+         "PropertyDefinition").invoke(defn);
+
+    String methodName;
+    if (propDefn instanceof BooleanPropertyDefinition)
+    {
+      methodName = "is" + methodBaseName;
+    }
+    else
+    {
+      methodName = "get" + methodBaseName;
+    }
+
+    defnMap.put(attrName, propDefn);
+    methodMap.put(attrName, configClass.getMethod(methodName));
+    attrMap.put(propertyName, attrName);
+  }
+
+
+  /**
+   * Get the name of the configuration attribute associated with a JE property.
+   * @param jeProperty The name of the JE property.
+   * @return The name of the associated configuration attribute.
+   */
+  public static String getAttributeForProperty(String jeProperty)
+  {
+    return attrMap.get(jeProperty);
+  }
+
+  /**
+   * Get the value of a JE property that is mapped to a configuration attribute.
+   * @param cfg The configuration containing the property values.
+   * @param attrName The conriguration attribute type name.
+   * @return The string value of the JE property.
+   */
+  private static String getPropertyValue(JEBackendCfg cfg, String attrName)
+  {
+    try
+    {
+      PropertyDefinition propDefn = defnMap.get(attrName);
+      Method method = methodMap.get(attrName);
+
+      if (propDefn instanceof DurationPropertyDefinition)
+      {
+        Long value = (Long)method.invoke(cfg);
+
+        // JE durations are in microseconds so we must convert.
+        DurationPropertyDefinition durationPropDefn =
+             (DurationPropertyDefinition)propDefn;
+        value = 1000*durationPropDefn.getBaseUnit().getDuration(value);
+
+        return String.valueOf(value);
+      }
+      else
+      {
+        Object value = method.invoke(cfg);
+        return String.valueOf(value);
+      }
+    }
+    catch (Exception e)
+    {
+      if (debugEnabled())
+      {
+        debugCaught(DebugLogLevel.ERROR, e);
+      }
+      return "";
+    }
   }
 
 
 
   static
   {
-    HashMap<String, Double> memoryUnits = new HashMap<String, Double>();
-    memoryUnits.put(SIZE_UNIT_BYTES_ABBR, 1D);
-    memoryUnits.put(SIZE_UNIT_BYTES_FULL, 1D);
-    memoryUnits.put(SIZE_UNIT_KILOBYTES_ABBR, 1000D);
-    memoryUnits.put(SIZE_UNIT_KILOBYTES_FULL, 1000D);
-    memoryUnits.put(SIZE_UNIT_MEGABYTES_ABBR, 1000000D);
-    memoryUnits.put(SIZE_UNIT_MEGABYTES_FULL, 1000000D);
-    memoryUnits.put(SIZE_UNIT_GIGABYTES_ABBR, 1000000000D);
-    memoryUnits.put(SIZE_UNIT_GIGABYTES_FULL, 1000000000D);
-    memoryUnits.put(SIZE_UNIT_KIBIBYTES_ABBR, 1024D);
-    memoryUnits.put(SIZE_UNIT_KIBIBYTES_FULL, 1024D);
-    memoryUnits.put(SIZE_UNIT_MEBIBYTES_ABBR, (double) (1024 * 1024));
-    memoryUnits.put(SIZE_UNIT_MEBIBYTES_FULL, (double) (1024 * 1024));
-    memoryUnits.put(SIZE_UNIT_GIBIBYTES_ABBR, (double) (1024 * 1024 * 1024));
-    memoryUnits.put(SIZE_UNIT_GIBIBYTES_FULL, (double) (1024 * 1024 * 1024));
-
-    // JE time intervals are expressed in microseconds.
-    HashMap<String, Double> timeUnits = new HashMap<String, Double>();
-    timeUnits.put(TIME_UNIT_MICROSECONDS_ABBR, 1D);
-    timeUnits.put(TIME_UNIT_MICROSECONDS_FULL, 1D);
-    timeUnits.put(TIME_UNIT_MILLISECONDS_ABBR, 1000D);
-    timeUnits.put(TIME_UNIT_MILLISECONDS_FULL, 1000D);
-    timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1000000D);
-    timeUnits.put(TIME_UNIT_SECONDS_FULL, 1000000D);
-    timeUnits.put(TIME_UNIT_MINUTES_ABBR, (double) (60 * 1000000));
-    timeUnits.put(TIME_UNIT_MINUTES_FULL, (double) (60 * 1000000));
-
-    String msg;
-
-    // Create configuration attributes for the JE properties that
-    // can be configured through the Directory Server interfaces.
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_DATABASE_TXN_NO_SYNC);
-    CONFIG_ATTR_TXN_NO_SYNC =
-         new BooleanConfigAttribute(ATTR_DATABASE_TXN_NO_SYNC,
-                                    msg, false);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_DATABASE_TXN_WRITE_NO_SYNC);
-    CONFIG_ATTR_TXN_WRITE_NO_SYNC =
-         new BooleanConfigAttribute(ATTR_DATABASE_TXN_WRITE_NO_SYNC,
-                                    msg, false);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_DATABASE_CACHE_PERCENT);
-    CONFIG_ATTR_CACHE_PERCENT =
-         new IntegerConfigAttribute(ATTR_DATABASE_CACHE_PERCENT, msg, true,
-                                    false, false, true, 1, true, 90);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_DATABASE_CACHE_SIZE);
-    CONFIG_ATTR_CACHE_SIZE =
-         new IntegerWithUnitConfigAttribute(ATTR_DATABASE_CACHE_SIZE, msg,
-                                            false, memoryUnits,
-                                            true, 0, false, 0);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_DATABASE_RUN_CLEANER);
-    CONFIG_ATTR_RUN_CLEANER =
-         new BooleanConfigAttribute(ATTR_DATABASE_RUN_CLEANER,
-                                    msg, false);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_CLEANER_MIN_UTILIZATION);
-    CONFIG_ATTR_CLEANER_MIN_UTILIZATION =
-         new IntegerConfigAttribute(ATTR_CLEANER_MIN_UTILIZATION, msg, true,
-                                    false, true, true, 0, true, 100);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_EVICTOR_LRU_ONLY);
-    CONFIG_ATTR_EVICTOR_LRU_ONLY =
-         new BooleanConfigAttribute(ATTR_EVICTOR_LRU_ONLY, msg, true);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_EVICTOR_NODES_PER_SCAN);
-    CONFIG_ATTR_EVICTOR_NODES_PER_SCAN =
-         new IntegerConfigAttribute(ATTR_EVICTOR_NODES_PER_SCAN, msg, false,
-                                    false, true, true, 1, true, 1000);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_DATABASE_LOG_FILE_MAX);
-    CONFIG_ATTR_LOG_FILE_MAX =
-         new IntegerWithUnitConfigAttribute(ATTR_DATABASE_LOG_FILE_MAX, msg,
-                                            false, memoryUnits,
-                                            true, 1000000, true, 4294967296L);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_LOGGING_FILE_HANDLER_ON);
-    CONFIG_ATTR_LOGGING_FILE_HANDLER_ON =
-         new BooleanConfigAttribute(ATTR_LOGGING_FILE_HANDLER_ON, msg, true);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_LOGGING_LEVEL);
-    CONFIG_ATTR_LOGGING_LEVEL =
-         new StringConfigAttribute(ATTR_LOGGING_LEVEL, msg, false, false, true);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_CHECKPOINT_BYTES_INTERVAL);
-    CONFIG_ATTR_CHECKPOINTER_BYTES_INTERVAL =
-         new IntegerWithUnitConfigAttribute(ATTR_CHECKPOINTER_BYTES_INTERVAL,
-                                            msg, true, memoryUnits,
-                                            true, 0, false, 0);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_CHECKPOINT_WAKEUP_INTERVAL);
-    CONFIG_ATTR_CHECKPOINTER_WAKEUP_INTERVAL =
-         new IntegerWithUnitConfigAttribute(ATTR_CHECKPOINTER_WAKEUP_INTERVAL,
-                                            msg, true, timeUnits,
-                                            true, 1000000, false, 0);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_NUM_LOCK_TABLES);
-    CONFIG_ATTR_NUM_LOCK_TABLES =
-         new IntegerConfigAttribute(ATTR_NUM_LOCK_TABLES, msg, false,
-                                    false, true, true, 1, true, 32767);
-
-    msg = getMessage(MSGID_CONFIG_DESCRIPTION_NUM_CLEANER_THREADS);
-    CONFIG_ATTR_NUM_CLEANER_THREADS =
-         new IntegerConfigAttribute(ATTR_NUM_CLEANER_THREADS, msg, false,
-                                    false, false, true, 1, false, 0);
-
     // Register the parameters that have JE property names.
-    registerPropertyAttribute("je.maxMemoryPercent",
-                              CONFIG_ATTR_CACHE_PERCENT);
-    registerPropertyAttribute("je.maxMemory",
-                              CONFIG_ATTR_CACHE_SIZE);
-    registerPropertyAttribute("je.cleaner.minUtilization",
-                              CONFIG_ATTR_CLEANER_MIN_UTILIZATION);
-    registerPropertyAttribute("je.env.runCleaner",
-                              CONFIG_ATTR_RUN_CLEANER);
-    registerPropertyAttribute("je.evictor.lruOnly",
-                              CONFIG_ATTR_EVICTOR_LRU_ONLY);
-    registerPropertyAttribute("je.evictor.nodesPerScan",
-                              CONFIG_ATTR_EVICTOR_NODES_PER_SCAN);
-    registerPropertyAttribute("je.log.fileMax",
-                              CONFIG_ATTR_LOG_FILE_MAX);
-    registerPropertyAttribute("java.util.logging.FileHandler.on",
-                              CONFIG_ATTR_LOGGING_FILE_HANDLER_ON);
-    registerPropertyAttribute("java.util.logging.level",
-                              CONFIG_ATTR_LOGGING_LEVEL);
-    registerPropertyAttribute("je.checkpointer.bytesInterval",
-                              CONFIG_ATTR_CHECKPOINTER_BYTES_INTERVAL);
-    registerPropertyAttribute("je.checkpointer.wakeupInterval",
-                              CONFIG_ATTR_CHECKPOINTER_WAKEUP_INTERVAL);
-    registerPropertyAttribute("je.lock.nLockTables",
-                              CONFIG_ATTR_NUM_LOCK_TABLES);
-    registerPropertyAttribute("je.cleaner.threads",
-                              CONFIG_ATTR_NUM_CLEANER_THREADS);
-
-    // These parameters do not have JE property names.
-    configAttrList.add(CONFIG_ATTR_TXN_NO_SYNC);
-    configAttrList.add(CONFIG_ATTR_TXN_WRITE_NO_SYNC);
-  }
-
-
-
-  /**
-   * Constructs a configurable environment.
-   *
-   * @param configDN    The DN of the configuration entry with which the
-   *                    environment is associated.
-   * @param environment The JE environment handle.
-   */
-  public ConfigurableEnvironment(DN configDN, Environment environment)
-  {
-    this.configDN = configDN;
-    this.environment = environment;
+    try
+    {
+      registerProp("je.maxMemoryPercent", ATTR_DATABASE_CACHE_PERCENT);
+      registerProp("je.maxMemory", ATTR_DATABASE_CACHE_SIZE);
+      registerProp("je.cleaner.minUtilization", ATTR_CLEANER_MIN_UTILIZATION);
+      registerProp("je.env.runCleaner", ATTR_DATABASE_RUN_CLEANER);
+      registerProp("je.evictor.lruOnly", ATTR_EVICTOR_LRU_ONLY);
+      registerProp("je.evictor.nodesPerScan", ATTR_EVICTOR_NODES_PER_SCAN);
+      registerProp("je.log.fileMax", ATTR_DATABASE_LOG_FILE_MAX);
+      registerProp("java.util.logging.FileHandler.on",
+                   ATTR_LOGGING_FILE_HANDLER_ON);
+      registerProp("java.util.logging.level", ATTR_LOGGING_LEVEL);
+      registerProp("je.checkpointer.bytesInterval",
+                   ATTR_CHECKPOINTER_BYTES_INTERVAL);
+      registerProp("je.checkpointer.wakeupInterval",
+                   ATTR_CHECKPOINTER_WAKEUP_INTERVAL);
+      registerProp("je.lock.nLockTables", ATTR_NUM_LOCK_TABLES);
+      registerProp("je.cleaner.threads", ATTR_NUM_CLEANER_THREADS);
+    }
+    catch (Exception e)
+    {
+      if (debugEnabled())
+      {
+        debugCaught(DebugLogLevel.ERROR, e);
+      }
+    }
   }
 
 
@@ -417,72 +359,31 @@
 
 
   /**
-   * Parse a configuration entry associated with a JE environment and create an
+   * Parse a configuration associated with a JE environment and create an
    * environment config from it.
    *
-   * @param configEntry The configuration entry to be parsed.
+   * @param cfg The configuration to be parsed.
    * @return An environment config instance corresponding to the config entry.
    * @throws ConfigException If there is an error in the provided configuration
    * entry.
    */
-  public static EnvironmentConfig parseConfigEntry(ConfigEntry configEntry)
+  public static EnvironmentConfig parseConfigEntry(JEBackendCfg cfg)
        throws ConfigException
   {
     EnvironmentConfig envConfig = defaultConfig();
 
     // Handle the attributes that do not have a JE property.
-    BooleanConfigAttribute booleanAttr;
-    booleanAttr = (BooleanConfigAttribute)
-         configEntry.getConfigAttribute(CONFIG_ATTR_TXN_NO_SYNC);
-    if (booleanAttr != null)
-    {
-      envConfig.setTxnNoSync(booleanAttr.activeValue());
-    }
-
-    booleanAttr = (BooleanConfigAttribute)
-         configEntry.getConfigAttribute(CONFIG_ATTR_TXN_WRITE_NO_SYNC);
-    if (booleanAttr != null)
-    {
-      envConfig.setTxnWriteNoSync(booleanAttr.activeValue());
-    }
+    envConfig.setTxnNoSync(cfg.isDatabaseTxnNoSync());
+    envConfig.setTxnWriteNoSync(cfg.isDatabaseTxnWriteNoSync());
 
     // Iterate through the config attributes associated with a JE property.
-    for (Map.Entry<String, ConfigAttribute> mapEntry : configAttrMap.entrySet())
+    for (Map.Entry<String, String> mapEntry : attrMap.entrySet())
     {
-      String property = mapEntry.getKey();
-      ConfigAttribute stub = mapEntry.getValue();
+      String jeProperty = mapEntry.getKey();
+      String attrName = mapEntry.getValue();
 
-      // Check if the config entry contains this attribute.
-      ConfigAttribute configAttr = configEntry.getConfigAttribute(stub);
-      if (stub != null)
-      {
-        // Set the property.
-        if (configAttr instanceof BooleanConfigAttribute)
-        {
-          BooleanConfigAttribute attr = (BooleanConfigAttribute) configAttr;
-          boolean value = attr.activeValue();
-          envConfig.setConfigParam(property, String.valueOf(value));
-        }
-        else if (configAttr instanceof IntegerConfigAttribute)
-        {
-          IntegerConfigAttribute attr = (IntegerConfigAttribute) configAttr;
-          long value = attr.activeValue();
-          envConfig.setConfigParam(property, String.valueOf(value));
-        }
-        else if (configAttr instanceof IntegerWithUnitConfigAttribute)
-        {
-          IntegerWithUnitConfigAttribute attr =
-               (IntegerWithUnitConfigAttribute) configAttr;
-          long value = attr.activeCalculatedValue();
-          envConfig.setConfigParam(property, String.valueOf(value));
-        }
-        else if (configAttr instanceof StringConfigAttribute)
-        {
-          StringConfigAttribute attr = (StringConfigAttribute) configAttr;
-          String value = attr.activeValue();
-          envConfig.setConfigParam(property, value);
-        }
-      }
+      String value = getPropertyValue(cfg, attrName);
+      envConfig.setConfigParam(jeProperty, value);
     }
 
     return envConfig;
@@ -490,122 +391,4 @@
 
 
 
-  /**
-   * Retrieves the DN of the configuration entry with which this component is
-   * associated.
-   *
-   * @return The DN of the configuration entry with which this component is
-   *         associated.
-   */
-  public DN getConfigurableComponentEntryDN()
-  {
-    return configDN;
-  }
-
-
-
-  /**
-   * Retrieves the set of configuration attributes that are associated with this
-   * configurable component.
-   *
-   * @return The set of configuration attributes that are associated with this
-   *         configurable component.
-   */
-  public List<ConfigAttribute> getConfigurationAttributes()
-  {
-    return configAttrList;
-  }
-
-
-
-  /**
-   * Indicates whether the provided configuration entry has an acceptable
-   * configuration for this component.  If it does not, then detailed
-   * information about the problem(s) should be added to the provided list.
-   *
-   * @param configEntry         The configuration entry for which to make the
-   *                            determination.
-   * @param unacceptableReasons A list that can be used to hold messages about
-   *                            why the provided entry does not have an
-   *                            acceptable configuration.
-   * @return <CODE>true</CODE> if the provided entry has an acceptable
-   *         configuration for this component, or <CODE>false</CODE> if not.
-   */
-  public boolean hasAcceptableConfiguration(ConfigEntry configEntry,
-                                            List<String> unacceptableReasons)
-  {
-    return true;
-  }
-
-
-
-  /**
-   * Makes a best-effort attempt to apply the configuration contained in the
-   * provided entry.  Information about the result of this processing should be
-   * added to the provided message list.  Information should always be added to
-   * this list if a configuration change could not be applied.  If detailed
-   * results are requested, then information about the changes applied
-   * successfully (and optionally about parameters that were not changed) should
-   * also be included.
-   *
-   * @param configEntry     The entry containing the new configuration to apply
-   *                        for this component.
-   * @param detailedResults Indicates whether detailed information about the
-   *                        processing should be added to the list.
-   *
-   * @return  Information about the result of the configuration update.
-   */
-  public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry,
-                                                  boolean detailedResults)
-  {
-    ConfigChangeResult ccr;
-    boolean adminActionRequired = false;
-    ArrayList<String> messages = new ArrayList<String>();
-
-    try
-    {
-      // Check if any JE non-mutable properties were changed.
-      EnvironmentConfig oldEnvConfig = environment.getConfig();
-      EnvironmentConfig newEnvConfig = parseConfigEntry(configEntry);
-      Map paramsMap = EnvironmentParams.SUPPORTED_PARAMS;
-      for (Object o : paramsMap.values())
-      {
-        ConfigParam param = (ConfigParam) o;
-        if (!param.isMutable())
-        {
-          String oldValue = oldEnvConfig.getConfigParam(param.getName());
-          String newValue = newEnvConfig.getConfigParam(param.getName());
-          if (!oldValue.equalsIgnoreCase(newValue))
-          {
-            adminActionRequired = true;
-            if (detailedResults)
-            {
-              ConfigAttribute configAttr = configAttrMap.get(param.getName());
-              if (configAttr != null)
-              {
-                int msgID = MSGID_JEB_CONFIG_ATTR_REQUIRES_RESTART;
-                messages.add(getMessage(msgID, configAttr.getName()));
-              }
-            }
-          }
-        }
-      }
-
-      // This takes care of changes to the JE environment for those
-      // properties that are mutable at runtime.
-      environment.setMutableConfig(newEnvConfig);
-    }
-    catch (Exception e)
-    {
-      messages.add(e.getMessage());
-      ccr = new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(),
-                                   adminActionRequired,
-                                   messages);
-      return ccr;
-    }
-
-    ccr = new ConfigChangeResult(ResultCode.SUCCESS, adminActionRequired,
-                                 messages);
-    return ccr;
-  }
 }
diff --git a/opends/src/server/org/opends/server/backends/jeb/RootContainer.java b/opends/src/server/org/opends/server/backends/jeb/RootContainer.java
index 8cd9051..572c390 100644
--- a/opends/src/server/org/opends/server/backends/jeb/RootContainer.java
+++ b/opends/src/server/org/opends/server/backends/jeb/RootContainer.java
@@ -42,6 +42,8 @@
 import org.opends.server.types.ErrorLogCategory;
 import org.opends.server.types.ErrorLogSeverity;
 import org.opends.server.types.FilePermission;
+import org.opends.server.types.ConfigChangeResult;
+import org.opends.server.types.ResultCode;
 import static org.opends.server.loggers.Error.logError;
 import static org.opends.server.loggers.debug.DebugLogger.debugInfo;
 import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
@@ -57,7 +59,12 @@
     MSGID_JEB_CLEAN_DATABASE_FINISH;
 import static org.opends.server.messages.JebMessages.
     MSGID_JEB_SET_PERMISSIONS_FAILED;
+import static org.opends.server.messages.JebMessages.
+     MSGID_JEB_CONFIG_ATTR_REQUIRES_RESTART;
 import org.opends.server.api.Backend;
+import org.opends.server.admin.std.server.JEBackendCfg;
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.core.DirectoryServer;
 
 /**
  * Wrapper class for the JE environment. Root container holds all the entry
@@ -65,6 +72,7 @@
  * of the entry containers.
  */
 public class RootContainer
+     implements ConfigurationChangeListener<JEBackendCfg>
 {
 
   /**
@@ -88,12 +96,6 @@
   private DatabaseEnvironmentMonitor monitor;
 
   /**
-   * A configurable component to handle changes to the configuration of
-   * the database environment.
-   */
-  private ConfigurableEnvironment configurableEnv;
-
-  /**
    * The base DNs contained in this entryContainer.
    */
   private ConcurrentHashMap<DN, EntryContainer> entryContainers;
@@ -114,7 +116,6 @@
   public RootContainer(Config config, Backend backend)
   {
     this.env = null;
-    this.configurableEnv = null;
     this.monitor = null;
     this.entryContainers = new ConcurrentHashMap<DN, EntryContainer>();
     this.backend = backend;
@@ -288,7 +289,7 @@
    */
   public void openEntryContainers(DN[] baseDNs) throws DatabaseException
   {
-    EntryID id = null;
+    EntryID id;
     EntryID highestID = null;
     for(DN baseDN : baseDNs)
     {
@@ -331,26 +332,6 @@
   }
 
   /**
-   * Get the ConfigurableEnvironment object for JE environment used by this
-   * root container.
-   *
-   * @return The ConfigurableEnvironment object.
-   */
-  public ConfigurableEnvironment getConfigurableEnvironment()
-  {
-    if(configurableEnv == null)
-    {
-      DN envConfigDN = config.getEnvConfigDN();
-      if (envConfigDN != null)
-      {
-        configurableEnv = new ConfigurableEnvironment(envConfigDN, env);
-      }
-    }
-
-    return configurableEnv;
-  }
-
-  /**
    * Get the DatabaseEnvironmentMonitor object for JE environment used by this
    * root container.
    *
@@ -559,77 +540,6 @@
   }
 
   /**
-   * Apply new configuration to the JE environment.
-   *
-   * @param newConfig The new configuration to apply.
-   * @throws DatabaseException If an error occurs while applying the new
-   *                           configuration.
-   */
-  public void applyNewConfig(Config newConfig) throws DatabaseException
-  {
-    // Check for changes to the database directory permissions
-    FilePermission oldPermission = config.getBackendPermission();
-    FilePermission newPermission = newConfig.getBackendPermission();
-
-    if(FilePermission.canSetPermissions() &&
-        !FilePermission.toUNIXMode(oldPermission).equals(
-        FilePermission.toUNIXMode(newPermission)))
-    {
-      try
-      {
-        if(!FilePermission.setPermissions(newConfig.getBackendDirectory(),
-                                          newPermission))
-        {
-          throw new Exception();
-        }
-      }
-      catch(Exception e)
-      {
-        // Log an warning that the permissions were not set.
-        int msgID = MSGID_JEB_SET_PERMISSIONS_FAILED;
-        String message = getMessage(msgID,
-                                    config.getBackendDirectory().getPath());
-        logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.SEVERE_WARNING,
-                 message, msgID);
-      }
-    }
-
-    // Check if any JE non-mutable properties were changed.
-    EnvironmentConfig oldEnvConfig = this.config.getEnvironmentConfig();
-    EnvironmentConfig newEnvConfig = newConfig.getEnvironmentConfig();
-    Map paramsMap = EnvironmentParams.SUPPORTED_PARAMS;
-    for (Object o : paramsMap.values())
-    {
-      ConfigParam param = (ConfigParam)o;
-      if (!param.isMutable())
-      {
-        String oldValue = oldEnvConfig.getConfigParam(param.getName());
-        String newValue = newEnvConfig.getConfigParam(param.getName());
-        if (!oldValue.equalsIgnoreCase(newValue))
-        {
-          if(debugEnabled())
-          {
-            debugInfo("The change to the following property will " +
-                      "take effect when the backend is restarted: " +
-                      param.getName());
-          }
-        }
-      }
-    }
-
-    // This takes care of changes to the JE environment for those
-    // properties that are mutable at runtime.
-    env.setMutableConfig(newConfig.getEnvironmentConfig());
-
-    config = newConfig;
-
-    if (debugEnabled())
-    {
-      debugInfo(env.getConfig().toString());
-    }
-  }
-
-  /**
    * Get the environment stats of the JE environment used in this root
    * container.
    *
@@ -705,4 +615,99 @@
   {
     return (nextid.get() - 1);
   }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isConfigurationChangeAcceptable(
+       JEBackendCfg cfg,
+       List<String> unacceptableReasons)
+  {
+    boolean acceptable = true;
+
+    // This listener handles only the changes to JE properties.
+
+    try
+    {
+      ConfigurableEnvironment.parseConfigEntry(cfg);
+    }
+    catch (Exception e)
+    {
+      unacceptableReasons.add(e.getMessage());
+      acceptable = false;
+    }
+
+    return acceptable;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public ConfigChangeResult applyConfigurationChange(JEBackendCfg cfg)
+  {
+    ConfigChangeResult ccr;
+    boolean adminActionRequired = false;
+    ArrayList<String> messages = new ArrayList<String>();
+
+    try
+    {
+      // Check if any JE non-mutable properties were changed.
+      EnvironmentConfig oldEnvConfig = env.getConfig();
+      EnvironmentConfig newEnvConfig =
+           ConfigurableEnvironment.parseConfigEntry(cfg);
+      Map paramsMap = EnvironmentParams.SUPPORTED_PARAMS;
+      for (Object o : paramsMap.values())
+      {
+        ConfigParam param = (ConfigParam) o;
+        if (!param.isMutable())
+        {
+          String oldValue = oldEnvConfig.getConfigParam(param.getName());
+          String newValue = newEnvConfig.getConfigParam(param.getName());
+          if (!oldValue.equalsIgnoreCase(newValue))
+          {
+            adminActionRequired = true;
+            String configAttr = ConfigurableEnvironment.
+                 getAttributeForProperty(param.getName());
+            if (configAttr != null)
+            {
+              int msgID = MSGID_JEB_CONFIG_ATTR_REQUIRES_RESTART;
+              messages.add(getMessage(msgID, configAttr));
+            }
+            if(debugEnabled())
+            {
+              debugInfo("The change to the following property will " +
+                        "take effect when the backend is restarted: " +
+                        param.getName());
+            }
+          }
+        }
+      }
+
+      // This takes care of changes to the JE environment for those
+      // properties that are mutable at runtime.
+      env.setMutableConfig(newEnvConfig);
+
+      if (debugEnabled())
+      {
+        debugInfo(env.getConfig().toString());
+      }
+    }
+    catch (Exception e)
+    {
+      messages.add(e.getMessage());
+      ccr = new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(),
+                                   adminActionRequired,
+                                   messages);
+      return ccr;
+    }
+
+
+    ccr = new ConfigChangeResult(ResultCode.SUCCESS, adminActionRequired,
+                                 messages);
+    return ccr;
+  }
 }
diff --git a/opends/src/server/org/opends/server/backends/task/TaskBackend.java b/opends/src/server/org/opends/server/backends/task/TaskBackend.java
index aa3ba12..5339327 100644
--- a/opends/src/server/org/opends/server/backends/task/TaskBackend.java
+++ b/opends/src/server/org/opends/server/backends/task/TaskBackend.java
@@ -31,24 +31,19 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.locks.Lock;
 
 import org.opends.server.api.Backend;
-import org.opends.server.api.ConfigurableComponent;
-import org.opends.server.config.ConfigAttribute;
-import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.ConfigException;
-import org.opends.server.config.IntegerWithUnitConfigAttribute;
-import org.opends.server.config.StringConfigAttribute;
+import org.opends.server.config.ConfigEntry;
 import org.opends.server.core.AddOperation;
 import org.opends.server.core.DeleteOperation;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.core.ModifyOperation;
 import org.opends.server.core.ModifyDNOperation;
 import org.opends.server.core.SearchOperation;
+import org.opends.server.core.BackendConfigManager;
 import org.opends.server.types.DN;
 import org.opends.server.types.Entry;
 import org.opends.server.types.BackupConfig;
@@ -70,9 +65,11 @@
 import org.opends.server.types.DebugLogLevel;
 import static org.opends.server.messages.BackendMessages.*;
 import static org.opends.server.messages.MessageHandler.*;
-import static org.opends.server.util.ServerConstants.*;
 import static org.opends.server.util.StaticUtils.*;
-
+import org.opends.server.util.Validator;
+import org.opends.server.admin.std.server.TaskBackendCfg;
+import org.opends.server.admin.std.meta.TaskBackendCfgDefn;
+import org.opends.server.admin.server.ConfigurationChangeListener;
 
 
 /**
@@ -82,16 +79,10 @@
  */
 public class TaskBackend
        extends Backend
-       implements ConfigurableComponent
+       implements ConfigurationChangeListener<TaskBackendCfg>
 {
-  /**
-   * The set of time units that will be used for expressing the task retention
-   * time.
-   */
-  private static final LinkedHashMap<String,Double> timeUnits =
-       new LinkedHashMap<String,Double>();
-
-
+  // The current configuration state.
+  private TaskBackendCfg currentConfig;
 
   // The DN of the configuration entry for this backend.
   private DN configEntryDN;
@@ -129,22 +120,6 @@
 
 
 
-  static
-  {
-    timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1D);
-    timeUnits.put(TIME_UNIT_SECONDS_FULL, 1D);
-    timeUnits.put(TIME_UNIT_MINUTES_ABBR, 60D);
-    timeUnits.put(TIME_UNIT_MINUTES_FULL, 60D);
-    timeUnits.put(TIME_UNIT_HOURS_ABBR, (double) (60 * 60));
-    timeUnits.put(TIME_UNIT_HOURS_FULL, (double) (60 * 60));
-    timeUnits.put(TIME_UNIT_DAYS_ABBR, (double) (60 * 60 * 24));
-    timeUnits.put(TIME_UNIT_DAYS_FULL, (double) (60 * 60 * 24));
-    timeUnits.put(TIME_UNIT_WEEKS_ABBR, (double) (60 * 60 * 24 * 7));
-    timeUnits.put(TIME_UNIT_WEEKS_FULL, (double) (60 * 60 * 24 * 7));
-  }
-
-
-
   /**
    * Creates a new backend with the provided information.  All backend
    * implementations must implement a default constructor that use
@@ -158,36 +133,16 @@
   }
 
 
-
   /**
-   * Initializes this backend based on the information in the provided
-   * configuration entry.
-   *
-   * @param  configEntry  The configuration entry that contains the information
-   *                      to use to initialize this backend.
-   * @param  baseDNs      The set of base DNs that have been configured for this
-   *                      backend.
-   *
-   * @throws  ConfigException  If an unrecoverable problem arises in the
-   *                           process of performing the initialization.
-   *
-   * @throws  InitializationException  If a problem occurs during initialization
-   *                                   that is not related to the server
-   *                                   configuration.
+   * {@inheritDoc}
    */
   public void initializeBackend(ConfigEntry configEntry, DN[] baseDNs)
          throws ConfigException, InitializationException
   {
-    // Make sure that a configuration entry was provided.  If not, then we will
-    // not be able to complete the initialization.
-    if (configEntry == null)
-    {
-      int    msgID   = MSGID_TASKBE_CONFIG_ENTRY_NULL;
-      String message = getMessage(msgID);
-      throw new ConfigException(msgID, message);
-    }
+    Validator.ensureNotNull(configEntry);
+    TaskBackendCfg cfg = getTaskBackendCfg(configEntry);
 
-    configEntryDN = configEntry.getDN();
+    configEntryDN = cfg.dn();
 
 
     // Make sure that the provided set of base DNs contains exactly one value.
@@ -256,68 +211,11 @@
 
     // Get the retention time that will be used to determine how long task
     // information stays around once the associated task is completed.
-    int msgID = MSGID_TASKBE_DESCRIPTION_RETENTION_TIME;
-    IntegerWithUnitConfigAttribute retentionStub =
-         new IntegerWithUnitConfigAttribute(ATTR_TASK_RETENTION_TIME,
-                                            getMessage(msgID), false, timeUnits,
-                                            true, 0, false, 0);
-    try
-    {
-      IntegerWithUnitConfigAttribute retentionAttr =
-           (IntegerWithUnitConfigAttribute)
-           configEntry.getConfigAttribute(retentionStub);
-      if (retentionAttr == null)
-      {
-        retentionTime = DEFAULT_TASK_RETENTION_TIME;
-      }
-      else
-      {
-        retentionTime = retentionAttr.activeCalculatedValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_TASKBE_CANNOT_INITIALIZE_RETENTION_TIME;
-      String message = getMessage(msgID, stackTraceToSingleLineString(e));
-      throw new InitializationException(msgID, message, e);
-    }
+    retentionTime = cfg.getTaskRetentionTime();
 
 
     // Get the path to the task data backing file.
-    msgID = MSGID_TASKBE_DESCRIPTION_BACKING_FILE;
-    StringConfigAttribute taskFileStub =
-         new StringConfigAttribute(ATTR_TASK_BACKING_FILE, getMessage(msgID),
-                                   true, false, false);
-    try
-    {
-      StringConfigAttribute taskFileAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(taskFileStub);
-      if (taskFileAttr == null)
-      {
-        taskBackingFile = DirectoryServer.getServerRoot() + File.separator +
-                          CONFIG_DIR_NAME + File.separator + TASK_FILE_NAME;
-      }
-      else
-      {
-        taskBackingFile = taskFileAttr.activeValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_TASKBE_CANNOT_INITIALIZE_BACKING_FILE;
-      String message = getMessage(msgID, stackTraceToSingleLineString(e));
-      throw new InitializationException(msgID, message, e);
-    }
+    taskBackingFile = cfg.getTaskBackingFile();
 
 
     // Create the scheduler and initialize it from the backing file.
@@ -331,7 +229,8 @@
 
 
     // Register with the Directory Server as a configurable component.
-    DirectoryServer.registerConfigurableComponent(this);
+    currentConfig = cfg;
+    cfg.addTaskChangeListener(this);
 
 
     // Register the task base as a private suffix.
@@ -346,7 +245,7 @@
         debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      msgID = MSGID_BACKEND_CANNOT_REGISTER_BASEDN;
+      int msgID = MSGID_BACKEND_CANNOT_REGISTER_BASEDN;
       String message = getMessage(msgID, taskRootDN.toString(),
                                   stackTraceToSingleLineString(e));
       throw new InitializationException(msgID, message, e);
@@ -368,7 +267,7 @@
    */
   public void finalizeBackend()
   {
-    DirectoryServer.deregisterConfigurableComponent(this);
+    currentConfig.removeTaskChangeListener(this);
 
 
     try
@@ -1029,17 +928,7 @@
 
 
   /**
-   * Exports the contents of this backend to LDIF.  This method should only be
-   * called if <CODE>supportsLDIFExport</CODE> returns <CODE>true</CODE>.  Note
-   * that the server will not explicitly initialize this backend before calling
-   * this method.
-   *
-   * @param  configEntry   The configuration entry for this backend.
-   * @param  baseDNs       The set of base DNs configured for this backend.
-   * @param  exportConfig  The configuration to use when performing the export.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the LDIF
-   *                              export.
+   * {@inheritDoc}
    */
   public void exportLDIF(ConfigEntry configEntry, DN[] baseDNs,
                          LDIFExportConfig exportConfig)
@@ -1066,17 +955,7 @@
 
 
   /**
-   * Imports information from an LDIF file into this backend.  This method
-   * should only be called if <CODE>supportsLDIFImport</CODE> returns
-   * <CODE>true</CODE>.  Note that the server will not explicitly initialize
-   * this backend before calling this method.
-   *
-   * @param  configEntry   The configuration entry for this backend.
-   * @param  baseDNs       The set of base DNs configured for this backend.
-   * @param  importConfig  The configuration to use when performing the import.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the LDIF
-   *                              import.
+   * {@inheritDoc}
    */
   public void importLDIF(ConfigEntry configEntry, DN[] baseDNs,
                          LDIFImportConfig importConfig)
@@ -1135,17 +1014,7 @@
 
 
   /**
-   * Creates a backup of the contents of this backend in a form that may be
-   * restored at a later date if necessary.  This method should only be called
-   * if <CODE>supportsBackup</CODE> returns <CODE>true</CODE>.  Note that the
-   * server will not explicitly initialize this backend before calling this
-   * method.
-   *
-   * @param  configEntry   The configuration entry for this backend.
-   * @param  backupConfig  The configuration to use when performing the backup.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the
-   *                              backup.
+   * {@inheritDoc}
    */
   public void createBackup(ConfigEntry configEntry, BackupConfig backupConfig)
          throws DirectoryException
@@ -1191,17 +1060,7 @@
 
 
   /**
-   * Restores a backup of the contents of this backend.  This method should only
-   * be called if <CODE>supportsRestore</CODE> returns <CODE>true</CODE>.  Note
-   * that the server will not explicitly initialize this backend before calling
-   * this method.
-   *
-   * @param  configEntry    The configuration entry for this backend.
-   * @param  restoreConfig  The configuration to use when performing the
-   *                        restore.
-   *
-   * @throws  DirectoryException  If a problem occurs while performing the
-   *                              restore.
+   * {@inheritDoc}
    */
   public void restoreBackup(ConfigEntry configEntry,
                             RestoreConfig restoreConfig)
@@ -1213,116 +1072,48 @@
 
 
   /**
-   * Retrieves the DN of the configuration entry with which this component is
-   * associated.
-   *
-   * @return  The DN of the configuration entry with which this component is
-   *          associated.
+   * {@inheritDoc}
    */
-  public DN getConfigurableComponentEntryDN()
-  {
-    return configEntryDN;
-  }
-
-
-
-  /**
-   * Retrieves the set of configuration attributes that are associated with this
-   * configurable component.
-   *
-   * @return  The set of configuration attributes that are associated with this
-   *          configurable component.
-   */
-  public List<ConfigAttribute> getConfigurationAttributes()
-  {
-    LinkedList<ConfigAttribute> attrList = new LinkedList<ConfigAttribute>();
-
-    String description = getMessage(MSGID_TASKBE_DESCRIPTION_BACKING_FILE);
-    attrList.add(new StringConfigAttribute(ATTR_TASK_BACKING_FILE, description,
-                                           true, false, false,
-                                           taskBackingFile));
-
-    description = getMessage(MSGID_TASKBE_DESCRIPTION_RETENTION_TIME);
-    attrList.add(new IntegerWithUnitConfigAttribute(ATTR_TASK_RETENTION_TIME,
-                                                    description, false,
-                                                    timeUnits, true, 0, false,
-                                                    0, retentionTime,
-                                                    TIME_UNIT_SECONDS_FULL));
-
-    return attrList;
-  }
-
-
-
-  /**
-   * Indicates whether the provided configuration entry has an acceptable
-   * configuration for this component.  If it does not, then detailed
-   * information about the problem(s) should be added to the provided list.
-   *
-   * @param  configEntry          The configuration entry for which to make the
-   *                              determination.
-   * @param  unacceptableReasons  A list that can be used to hold messages about
-   *                              why the provided entry does not have an
-   *                              acceptable configuration.
-   *
-   * @return  <CODE>true</CODE> if the provided entry has an acceptable
-   *          configuration for this component, or <CODE>false</CODE> if not.
-   */
-  public boolean hasAcceptableConfiguration(ConfigEntry configEntry,
+  public boolean isConfigurationChangeAcceptable(TaskBackendCfg configEntry,
                                             List<String> unacceptableReasons)
   {
     boolean configIsAcceptable = true;
 
 
-    String description = getMessage(MSGID_TASKBE_DESCRIPTION_BACKING_FILE);
-    StringConfigAttribute backingStub =
-         new StringConfigAttribute(ATTR_TASK_BACKING_FILE, description, true,
-                                   false, false);
     try
     {
-      StringConfigAttribute backingAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(backingStub);
-      if (backingAttr == null)
+      String tmpBackingFile = configEntry.getTaskBackingFile();
+      if (! taskBackingFile.equals(tmpBackingFile))
       {
-        int msgID = MSGID_TASKBE_NO_BACKING_FILE;
-        unacceptableReasons.add(getMessage(msgID, ATTR_TASK_BACKING_FILE));
-        configIsAcceptable = false;
-      }
-      else
-      {
-        String tmpBackingFile = backingAttr.pendingValue();
-        if (! taskBackingFile.equals(tmpBackingFile))
+        File f = getFileForPath(tmpBackingFile);
+        if (f.exists())
         {
-          File f = getFileForPath(tmpBackingFile);
-          if (f.exists())
+          int msgID = MSGID_TASKBE_BACKING_FILE_EXISTS;
+          unacceptableReasons.add(getMessage(msgID, tmpBackingFile));
+          configIsAcceptable = false;
+        }
+        else
+        {
+          File p = f.getParentFile();
+          if (p == null)
           {
-            int msgID = MSGID_TASKBE_BACKING_FILE_EXISTS;
+            int msgID = MSGID_TASKBE_INVALID_BACKING_FILE_PATH;
             unacceptableReasons.add(getMessage(msgID, tmpBackingFile));
             configIsAcceptable = false;
           }
-          else
+          else if (! p.exists())
           {
-            File p = f.getParentFile();
-            if (p == null)
-            {
-              int msgID = MSGID_TASKBE_INVALID_BACKING_FILE_PATH;
-              unacceptableReasons.add(getMessage(msgID, tmpBackingFile));
-              configIsAcceptable = false;
-            }
-            else if (! p.exists())
-            {
-              int msgID = MSGID_TASKBE_BACKING_FILE_MISSING_PARENT;
-              unacceptableReasons.add(getMessage(msgID, p.getPath(),
-                                                 tmpBackingFile));
-              configIsAcceptable = false;
-            }
-            else if (! p.isDirectory())
-            {
-              int msgID = MSGID_TASKBE_BACKING_FILE_PARENT_NOT_DIRECTORY;
-              unacceptableReasons.add(getMessage(msgID, p.getPath(),
-                                                 tmpBackingFile));
-              configIsAcceptable = false;
-            }
+            int msgID = MSGID_TASKBE_BACKING_FILE_MISSING_PARENT;
+            unacceptableReasons.add(getMessage(msgID, p.getPath(),
+                                               tmpBackingFile));
+            configIsAcceptable = false;
+          }
+          else if (! p.isDirectory())
+          {
+            int msgID = MSGID_TASKBE_BACKING_FILE_PARENT_NOT_DIRECTORY;
+            unacceptableReasons.add(getMessage(msgID, p.getPath(),
+                                               tmpBackingFile));
+            configIsAcceptable = false;
           }
         }
       }
@@ -1342,36 +1133,6 @@
     }
 
 
-    description = getMessage(MSGID_TASKBE_DESCRIPTION_RETENTION_TIME);
-    IntegerWithUnitConfigAttribute retentionStub =
-         new IntegerWithUnitConfigAttribute(ATTR_TASK_RETENTION_TIME,
-                                            description, false, timeUnits,
-                                            true, 0, false, 0);
-    try
-    {
-      IntegerWithUnitConfigAttribute retentionAttr =
-           (IntegerWithUnitConfigAttribute)
-           configEntry.getConfigAttribute(retentionStub);
-      if (retentionAttr == null)
-      {
-        int msgID = MSGID_TASKBE_NO_RETENTION_TIME;
-        unacceptableReasons.add(getMessage(msgID, ATTR_TASK_RETENTION_TIME));
-        configIsAcceptable = false;
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      int msgID = MSGID_TASKBE_ERROR_GETTING_RETENTION_TIME;
-      unacceptableReasons.add(getMessage(msgID, ATTR_TASK_RETENTION_TIME,
-                                         stackTraceToSingleLineString(e)));
-
-      configIsAcceptable = false;
-    }
 
 
     return configIsAcceptable;
@@ -1380,23 +1141,9 @@
 
 
   /**
-   * Makes a best-effort attempt to apply the configuration contained in the
-   * provided entry.  Information about the result of this processing should be
-   * added to the provided message list.  Information should always be added to
-   * this list if a configuration change could not be applied.  If detailed
-   * results are requested, then information about the changes applied
-   * successfully (and optionally about parameters that were not changed) should
-   * also be included.
-   *
-   * @param  configEntry      The entry containing the new configuration to
-   *                          apply for this component.
-   * @param  detailedResults  Indicates whether detailed information about the
-   *                          processing should be added to the list.
-   *
-   * @return  Information about the result of the configuration update.
+   * {@inheritDoc}
    */
-  public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry,
-                                                  boolean detailedResults)
+  public ConfigChangeResult applyConfigurationChange(TaskBackendCfg configEntry)
   {
     ResultCode        resultCode          = ResultCode.SUCCESS;
     boolean           adminActionRequired = false;
@@ -1404,23 +1151,10 @@
 
 
     String tmpBackingFile = taskBackingFile;
-    String description = getMessage(MSGID_TASKBE_DESCRIPTION_BACKING_FILE);
-    StringConfigAttribute backingStub =
-         new StringConfigAttribute(ATTR_TASK_BACKING_FILE, description, true,
-                                   false, false);
     try
     {
-      StringConfigAttribute backingAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(backingStub);
-      if (backingAttr == null)
       {
-        int msgID = MSGID_TASKBE_NO_BACKING_FILE;
-        messages.add(getMessage(msgID, ATTR_TASK_BACKING_FILE));
-        resultCode = ResultCode.OBJECTCLASS_VIOLATION;
-      }
-      else
-      {
-        tmpBackingFile = backingAttr.pendingValue();
+        tmpBackingFile = configEntry.getTaskBackingFile();
         if (! taskBackingFile.equals(tmpBackingFile))
         {
           File f = getFileForPath(tmpBackingFile);
@@ -1470,48 +1204,7 @@
     }
 
 
-    long tmpRetentionTime = retentionTime;
-    description = getMessage(MSGID_TASKBE_DESCRIPTION_RETENTION_TIME);
-    IntegerWithUnitConfigAttribute retentionStub =
-         new IntegerWithUnitConfigAttribute(ATTR_TASK_RETENTION_TIME,
-                                            description, false, timeUnits,
-                                            true, 0, false, 0);
-    try
-    {
-      IntegerWithUnitConfigAttribute retentionAttr =
-           (IntegerWithUnitConfigAttribute)
-           configEntry.getConfigAttribute(retentionStub);
-      if (retentionAttr == null)
-      {
-        int msgID = MSGID_TASKBE_NO_RETENTION_TIME;
-        messages.add(getMessage(msgID, ATTR_TASK_RETENTION_TIME));
-
-        if (resultCode == ResultCode.SUCCESS)
-        {
-          resultCode = ResultCode.OBJECTCLASS_VIOLATION;
-        }
-      }
-      else
-      {
-        tmpRetentionTime = retentionAttr.activeCalculatedValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      int msgID = MSGID_TASKBE_ERROR_GETTING_RETENTION_TIME;
-      messages.add(getMessage(msgID, ATTR_TASK_RETENTION_TIME,
-                              stackTraceToSingleLineString(e)));
-
-      if (resultCode == ResultCode.SUCCESS)
-      {
-        resultCode = DirectoryServer.getServerErrorResultCode();
-      }
-    }
+    long tmpRetentionTime = configEntry.getTaskRetentionTime();
 
 
     if (resultCode == ResultCode.SUCCESS)
@@ -1537,6 +1230,7 @@
     }
 
 
+    currentConfig = configEntry;
     return new ConfigChangeResult(resultCode, adminActionRequired, messages);
   }
 
@@ -1653,5 +1347,13 @@
   {
     return taskScheduler.getRecurringTask(taskEntryDN);
   }
+
+
+
+  private static TaskBackendCfg getTaskBackendCfg(ConfigEntry configEntry)
+      throws ConfigException {
+    return BackendConfigManager.getConfiguration(
+         TaskBackendCfgDefn.getInstance(), configEntry);
+  }
 }
 
diff --git a/opends/src/server/org/opends/server/core/BackendConfigManager.java b/opends/src/server/org/opends/server/core/BackendConfigManager.java
index f150fd8..b932025 100644
--- a/opends/src/server/org/opends/server/core/BackendConfigManager.java
+++ b/opends/src/server/org/opends/server/core/BackendConfigManager.java
@@ -31,42 +31,38 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
-import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.opends.server.api.Backend;
 import org.opends.server.api.BackendInitializationListener;
-import org.opends.server.api.ConfigAddListener;
-import org.opends.server.api.ConfigChangeListener;
-import org.opends.server.api.ConfigDeleteListener;
 import org.opends.server.api.ConfigHandler;
-import org.opends.server.api.ConfigurableComponent;
-import org.opends.server.config.BooleanConfigAttribute;
-import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.ConfigException;
-import org.opends.server.config.DNConfigAttribute;
-import org.opends.server.config.MultiChoiceConfigAttribute;
-import org.opends.server.config.StringConfigAttribute;
-import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DN;
-import org.opends.server.types.ErrorLogCategory;
-import org.opends.server.types.ErrorLogSeverity;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.SearchFilter;
-import org.opends.server.types.WritabilityMode;
+import org.opends.server.config.ConfigEntry;
+import org.opends.server.config.ConfigConstants;
 
-import static org.opends.server.config.ConfigConstants.*;
 import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
 import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
-import org.opends.server.types.DebugLogLevel;
-import static org.opends.server.loggers.Error.*;
+import org.opends.server.types.*;
+import static org.opends.server.loggers.Error.logError;
 import static org.opends.server.messages.ConfigMessages.*;
-import static org.opends.server.messages.MessageHandler.*;
+import static org.opends.server.messages.MessageHandler.getMessage;
 import static org.opends.server.util.StaticUtils.*;
-
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.server.ConfigurationAddListener;
+import org.opends.server.admin.server.ConfigurationDeleteListener;
+import org.opends.server.admin.server.ServerManagementContext;
+import org.opends.server.admin.server.ServerManagedObject;
+import org.opends.server.admin.server.ConfigExceptionFactory;
+import org.opends.server.admin.server.ServerManagedObjectDecodingException;
+import org.opends.server.admin.std.server.BackendCfg;
+import org.opends.server.admin.std.server.RootCfg;
+import org.opends.server.admin.std.meta.BackendCfgDefn;
+import org.opends.server.admin.Configuration;
+import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.ManagedObjectPath;
+import org.opends.server.admin.DefinitionDecodingException;
 
 
 /**
@@ -76,8 +72,10 @@
  * started, and then will manage any changes to them while the server is
  * running.
  */
-public class BackendConfigManager
-       implements ConfigChangeListener, ConfigAddListener, ConfigDeleteListener
+public class BackendConfigManager implements
+     ConfigurationChangeListener<BackendCfg>,
+     ConfigurationAddListener<BackendCfg>,
+     ConfigurationDeleteListener<BackendCfg>
 {
 
 
@@ -86,9 +84,6 @@
   // backend implementations.
   private ConcurrentHashMap<DN,Backend> registeredBackends;
 
-  // The DN of the associated configuration entry.
-  private DN configEntryDN;
-
 
 
   /**
@@ -118,13 +113,21 @@
     registeredBackends = new ConcurrentHashMap<DN,Backend>();
 
 
+    // Create an internal server management context and retrieve
+    // the root configuration.
+    ServerManagementContext context = ServerManagementContext.getInstance();
+    RootCfg root = context.getRootConfiguration();
+
+    // Register add and delete listeners.
+    root.addBackendAddListener(this);
+    root.addBackendDeleteListener(this);
 
     // Get the configuration entry that is at the root of all the backends in
     // the server.
     ConfigEntry backendRoot;
     try
     {
-      configEntryDN = DN.decode(DN_BACKEND_BASE);
+      DN configEntryDN = DN.decode(ConfigConstants.DN_BACKEND_BASE);
       backendRoot   = DirectoryServer.getConfigEntry(configEntryDN);
     }
     catch (Exception e)
@@ -137,6 +140,7 @@
       int    msgID   = MSGID_CONFIG_BACKEND_CANNOT_GET_CONFIG_BASE;
       String message = getMessage(msgID, stackTraceToSingleLineString(e));
       throw new ConfigException(msgID, message, e);
+
     }
 
 
@@ -151,701 +155,313 @@
     }
 
 
-    // Register as an add and delete listener for the base entry so that we can
-    // be notified if new backends are added or existing backends are removed.
-    backendRoot.registerAddListener(this);
-    backendRoot.registerDeleteListener(this);
-
-
-    // Iterate through the set of immediate children below the backend config
-    // root.
-    for (ConfigEntry backendEntry : backendRoot.getChildren().values())
+    // Initialize existing backends.
+    for (String name : root.listBackends())
     {
-      DN backendDN = backendEntry.getDN();
+      // Get the handler's configuration.
+      // This will decode and validate its properties.
+      BackendCfg backendCfg = root.getBackend(name);
 
+      DN backendDN = backendCfg.dn();
+      String backendID = backendCfg.getBackendId();
 
-      // Register as a change listener for this backend entry so that we will
-      // be notified of any changes that may be made to it.
-      backendEntry.registerChangeListener(this);
+      // Register as a change listener for this backend so that we can be
+      // notified when it is disabled or enabled.
+      backendCfg.addChangeListener(this);
 
-
-      // Check to see if this entry appears to contain a backend configuration.
-      // If not, log a warning and skip it.
-      try
+      // Ignore this handler if it is disabled.
+      if (backendCfg.isBackendEnabled())
       {
-        SearchFilter backendFilter =
-             SearchFilter.createFilterFromString("(objectClass=" + OC_BACKEND +
-                                                 ")");
-        if (! backendFilter.matchesEntry(backendEntry.getEntry()))
+        // If there is already a backend registered with the specified ID,
+        // then log an error and skip it.
+        if (DirectoryServer.hasBackend(backendCfg.getBackendId()))
         {
-          int msgID = MSGID_CONFIG_BACKEND_ENTRY_DOES_NOT_HAVE_BACKEND_CONFIG;
-          String message = getMessage(msgID, String.valueOf(backendDN));
-          logError(ErrorLogCategory.CONFIGURATION,
-                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-          continue;
-        }
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          debugCaught(DebugLogLevel.ERROR, e);
-        }
-
-        int msgID = MSGID_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY;
-        String message = getMessage(msgID, String.valueOf(backendDN),
-                                    stackTraceToSingleLineString(e));
-        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
-                 message, msgID);
-        continue;
-      }
-
-
-      // See if the entry contains an attribute that indicates whether the
-      // backend should be enabled.  If it does not, or if it is not set to
-      // "true", then skip it.
-      int msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_ENABLED;
-      BooleanConfigAttribute enabledStub =
-           new BooleanConfigAttribute(ATTR_BACKEND_ENABLED, getMessage(msgID),
-                                      false);
-      try
-      {
-        BooleanConfigAttribute enabledAttr =
-             (BooleanConfigAttribute)
-             backendEntry.getConfigAttribute(enabledStub);
-        if (enabledAttr == null)
-        {
-          // The attribute is not present, so this backend will be disabled.
-          // Log a message and continue.
-          msgID = MSGID_CONFIG_BACKEND_NO_ENABLED_ATTR;
-          String message = getMessage(msgID, String.valueOf(backendDN));
-          logError(ErrorLogCategory.CONFIGURATION,
-                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-          continue;
-        }
-        else if (! enabledAttr.activeValue())
-        {
-          // The backend is explicitly disabled.  Log a mild warning and
-          // continue.
-          msgID = MSGID_CONFIG_BACKEND_DISABLED;
-          String message = getMessage(msgID, String.valueOf(backendDN));
-          logError(ErrorLogCategory.CONFIGURATION,
-                   ErrorLogSeverity.INFORMATIONAL, message, msgID);
-          continue;
-        }
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          debugCaught(DebugLogLevel.ERROR, e);
-        }
-
-        msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_ENABLED_STATE;
-        String message = getMessage(msgID, String.valueOf(backendDN),
-                                    stackTraceToSingleLineString(e));
-        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
-                 message, msgID);
-        continue;
-      }
-
-
-      // See if the entry contains an attribute that specifies the backend ID.
-      // If it does not, then log an error and skip it.
-      msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BACKEND_ID;
-      String backendID = null;
-      StringConfigAttribute idStub =
-           new StringConfigAttribute(ATTR_BACKEND_ID, getMessage(msgID),
-                                     true, false, true);
-      try
-      {
-        StringConfigAttribute idAttr =
-             (StringConfigAttribute) backendEntry.getConfigAttribute(idStub);
-        if (idAttr == null)
-        {
-          msgID = MSGID_CONFIG_BACKEND_NO_BACKEND_ID;
-          String message = getMessage(msgID, String.valueOf(backendDN));
-          logError(ErrorLogCategory.CONFIGURATION,
-                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-          continue;
-        }
-        else
-        {
-          backendID = idAttr.activeValue();
-
-          // If there is already a backend registered with the specified ID,
-          // then log an error and skip it.
-          if (DirectoryServer.hasBackend(backendID))
-          {
-            msgID = MSGID_CONFIG_BACKEND_DUPLICATE_BACKEND_ID;
-            String message = getMessage(msgID, backendID,
-                                        String.valueOf(backendDN));
-            logError(ErrorLogCategory.CONFIGURATION,
-                     ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-            continue;
-          }
-        }
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          debugCaught(DebugLogLevel.ERROR, e);
-        }
-
-        msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_BACKEND_ID;
-        String message = getMessage(msgID, String.valueOf(backendDN),
-                                    stackTraceToSingleLineString(e));
-        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
-                 message, msgID);
-        continue;
-      }
-
-
-      // Get the writability mode for this backend.  It must be provided.
-      LinkedHashSet<String> writabilityModes = new LinkedHashSet<String>(3);
-      writabilityModes.add(WritabilityMode.ENABLED.toString());
-      writabilityModes.add(WritabilityMode.DISABLED.toString());
-      writabilityModes.add(WritabilityMode.INTERNAL_ONLY.toString());
-
-      msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_WRITABILITY;
-      WritabilityMode writabilityMode = null;
-      MultiChoiceConfigAttribute writabilityStub =
-           new MultiChoiceConfigAttribute(ATTR_BACKEND_WRITABILITY_MODE,
-                                          getMessage(msgID), true, false, false,
-                                          writabilityModes);
-      try
-      {
-        MultiChoiceConfigAttribute writabilityAttr =
-             (MultiChoiceConfigAttribute)
-             backendEntry.getConfigAttribute(writabilityStub);
-        if (writabilityAttr == null)
-        {
-          msgID = MSGID_CONFIG_BACKEND_NO_WRITABILITY_MODE;
-          String message = getMessage(msgID, String.valueOf(backendDN));
-          logError(ErrorLogCategory.CONFIGURATION,
-                   ErrorLogSeverity.SEVERE_ERROR, message, msgID);
-          continue;
-        }
-        else
-        {
-          writabilityMode =
-               WritabilityMode.modeForName(writabilityAttr.activeValue());
-          if (writabilityMode == null)
-          {
-            msgID = MSGID_CONFIG_BACKEND_INVALID_WRITABILITY_MODE;
-            String message =
-                 getMessage(msgID, String.valueOf(backendDN),
-                            String.valueOf(writabilityAttr.activeValue()));
-            logError(ErrorLogCategory.CONFIGURATION,
-                     ErrorLogSeverity.SEVERE_ERROR, message, msgID);
-            continue;
-          }
-        }
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          debugCaught(DebugLogLevel.ERROR, e);
-        }
-
-        msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_WRITABILITY;
-        String message = getMessage(msgID, String.valueOf(backendDN),
-                                    stackTraceToSingleLineString(e));
-        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
-                 message, msgID);
-        continue;
-      }
-
-
-      // See if the entry contains an attribute that specifies the base DNs for
-      // the backend.  If it does not, then log an error and skip it.
-      msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS;
-      DN[] baseDNs = null;
-      DNConfigAttribute baseDNStub =
-           new DNConfigAttribute(ATTR_BACKEND_BASE_DN, getMessage(msgID),
-                                 true, true, true);
-      try
-      {
-        DNConfigAttribute baseDNAttr =
-             (DNConfigAttribute) backendEntry.getConfigAttribute(baseDNStub);
-        if (baseDNAttr == null)
-        {
-          msgID = MSGID_CONFIG_BACKEND_NO_BASE_DNS;
-          String message = getMessage(msgID, String.valueOf(backendDN));
-          logError(ErrorLogCategory.CONFIGURATION,
-                   ErrorLogSeverity.SEVERE_ERROR, message, msgID);
-          continue;
-        }
-        else
-        {
-          List<DN> dnList = baseDNAttr.activeValues();
-          baseDNs = new DN[dnList.size()];
-          dnList.toArray(baseDNs);
-        }
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          debugCaught(DebugLogLevel.ERROR, e);
-        }
-
-        msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_BASE_DNS;
-        String message = getMessage(msgID, String.valueOf(backendDN),
-                                    stackTraceToSingleLineString(e));
-        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
-                 message, msgID);
-        continue;
-      }
-
-
-      // See if the entry contains an attribute that specifies the class name
-      // for the backend implementation.  If it does, then load it and make sure
-      // that it's a valid backend implementation.  There is no such attribute,
-      // the specified class cannot be loaded, or it does not contain a valid
-      // backend implementation, then log an error and skip it.
-      String className;
-      msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_CLASS;
-      StringConfigAttribute classStub =
-           new StringConfigAttribute(ATTR_BACKEND_CLASS, getMessage(msgID),
-                                     true, false, true);
-      try
-      {
-        StringConfigAttribute classAttr =
-             (StringConfigAttribute) backendEntry.getConfigAttribute(classStub);
-        if (classAttr == null)
-        {
-          msgID = MSGID_CONFIG_BACKEND_NO_CLASS_ATTR;
-          String message = getMessage(msgID, String.valueOf(backendDN));
-          logError(ErrorLogCategory.CONFIGURATION,
-                   ErrorLogSeverity.SEVERE_ERROR, message, msgID);
-          continue;
-        }
-        else
-        {
-          className = classAttr.activeValue();
-        }
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          debugCaught(DebugLogLevel.ERROR, e);
-        }
-
-        msgID = MSGID_CONFIG_BACKEND_CANNOT_GET_CLASS;
-        String message = getMessage(msgID, String.valueOf(backendDN),
-                                    stackTraceToSingleLineString(e));
-        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
-                 message, msgID);
-        continue;
-      }
-
-      Backend backend;
-      try
-      {
-        Class backendClass = DirectoryServer.loadClass(className);
-        backend = (Backend) backendClass.newInstance();
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          debugCaught(DebugLogLevel.ERROR, e);
-        }
-
-        msgID = MSGID_CONFIG_BACKEND_CANNOT_INSTANTIATE;
-        String message = getMessage(msgID, String.valueOf(className),
-                                    String.valueOf(backendDN),
-                                    stackTraceToSingleLineString(e));
-        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
-                 message, msgID);
-        continue;
-      }
-
-
-      // If this backend is a configuration manager, then we don't want to do
-      // any more with it because the configuration will have already been
-      // started.
-      if (backend instanceof ConfigHandler)
-      {
-        continue;
-      }
-
-
-      // Set the backend ID and writability mode for this backend.
-      backend.setBackendID(backendID);
-      backend.setWritabilityMode(writabilityMode);
-
-
-      // Acquire a shared lock on this backend.  This will prevent operations
-      // like LDIF import or restore from occurring while the backend is active.
-      try
-      {
-        String lockFile = LockFileManager.getBackendLockFileName(backend);
-        StringBuilder failureReason = new StringBuilder();
-        if (! LockFileManager.acquireSharedLock(lockFile, failureReason))
-        {
-          msgID = MSGID_CONFIG_BACKEND_CANNOT_ACQUIRE_SHARED_LOCK;
+          int msgID = MSGID_CONFIG_BACKEND_DUPLICATE_BACKEND_ID;
           String message = getMessage(msgID, backendID,
-                                      String.valueOf(failureReason));
+                                      String.valueOf(backendDN));
           logError(ErrorLogCategory.CONFIGURATION,
                    ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-          // FIXME -- Do we need to send an admin alert?
           continue;
         }
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
+
+        // See if the entry contains an attribute that specifies the class name
+        // for the backend implementation.  If it does, then load it and make
+        // sure that it's a valid backend implementation.  There is no such
+        // attribute, the specified class cannot be loaded, or it does not
+        // contain a valid backend implementation, then log an error and skip
+        // it.
+        String className = backendCfg.getBackendClass();
+        Class backendClass;
+
+        Backend backend;
+        try
         {
-          debugCaught(DebugLogLevel.ERROR, e);
+          backendClass = DirectoryServer.loadClass(className);
+          backend = (Backend) backendClass.newInstance();
+        }
+        catch (Exception e)
+        {
+          if (debugEnabled())
+          {
+            debugCaught(DebugLogLevel.ERROR, e);
+          }
+
+          int msgID = MSGID_CONFIG_BACKEND_CANNOT_INSTANTIATE;
+          String message = getMessage(msgID, String.valueOf(className),
+                                      String.valueOf(backendDN),
+                                      stackTraceToSingleLineString(e));
+          logError(ErrorLogCategory.CONFIGURATION,
+                   ErrorLogSeverity.SEVERE_ERROR,
+                   message, msgID);
+          continue;
         }
 
-        msgID = MSGID_CONFIG_BACKEND_CANNOT_ACQUIRE_SHARED_LOCK;
-        String message = getMessage(msgID, backendID,
-                                    stackTraceToSingleLineString(e));
-        logError(ErrorLogCategory.CONFIGURATION,
-                 ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-        // FIXME -- Do we need to send an admin alert?
-        continue;
-      }
 
-
-      // Perform the necessary initialization for the backend entry.
-      try
-      {
-        backend.initializeBackend(backendEntry, baseDNs);
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
+        // If this backend is a configuration manager, then we don't want to do
+        // any more with it because the configuration will have already been
+        // started.
+        if (backend instanceof ConfigHandler)
         {
-          debugCaught(DebugLogLevel.ERROR, e);
+          continue;
         }
 
-        msgID = MSGID_CONFIG_BACKEND_CANNOT_INITIALIZE;
-        String message = getMessage(msgID, String.valueOf(className),
-                                    String.valueOf(backendDN),
-                                    stackTraceToSingleLineString(e));
-        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
-                 message, msgID);
 
+        // See if the entry contains an attribute that specifies the writability
+        // mode.
+        WritabilityMode writabilityMode = WritabilityMode.ENABLED;
+        BackendCfgDefn.BackendWritabilityMode bwm =
+             backendCfg.getBackendWritabilityMode();
+        switch (bwm)
+        {
+          case DISABLED:
+            writabilityMode = WritabilityMode.DISABLED;
+            break;
+          case ENABLED:
+            writabilityMode = WritabilityMode.ENABLED;
+            break;
+          case INTERNAL_ONLY:
+            writabilityMode = WritabilityMode.INTERNAL_ONLY;
+            break;
+        }
+
+        // Set the backend ID and writability mode for this backend.
+        backend.setBackendID(backendID);
+        backend.setWritabilityMode(writabilityMode);
+
+
+        // Acquire a shared lock on this backend.  This will prevent operations
+        // like LDIF import or restore from occurring while the backend is
+        // active.
         try
         {
           String lockFile = LockFileManager.getBackendLockFileName(backend);
           StringBuilder failureReason = new StringBuilder();
-          if (! LockFileManager.releaseLock(lockFile, failureReason))
+          if (! LockFileManager.acquireSharedLock(lockFile, failureReason))
           {
+            int msgID = MSGID_CONFIG_BACKEND_CANNOT_ACQUIRE_SHARED_LOCK;
+            String message = getMessage(msgID, backendID,
+                                        String.valueOf(failureReason));
+            logError(ErrorLogCategory.CONFIGURATION,
+                     ErrorLogSeverity.SEVERE_WARNING, message, msgID);
+            // FIXME -- Do we need to send an admin alert?
+            continue;
+          }
+        }
+        catch (Exception e)
+        {
+          if (debugEnabled())
+          {
+            debugCaught(DebugLogLevel.ERROR, e);
+          }
+
+          int msgID = MSGID_CONFIG_BACKEND_CANNOT_ACQUIRE_SHARED_LOCK;
+          String message = getMessage(msgID, backendID,
+                                      stackTraceToSingleLineString(e));
+          logError(ErrorLogCategory.CONFIGURATION,
+                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
+          // FIXME -- Do we need to send an admin alert?
+          continue;
+        }
+
+
+        // Perform the necessary initialization for the backend entry.
+        DN[] baseDNs = new DN[backendCfg.getBackendBaseDN().size()];
+        baseDNs = backendCfg.getBackendBaseDN().toArray(baseDNs);
+        try
+        {
+          backend.initializeBackend(
+               DirectoryServer.getConfigEntry(backendCfg.dn()), baseDNs);
+        }
+        catch (Exception e)
+        {
+          if (debugEnabled())
+          {
+            debugCaught(DebugLogLevel.ERROR, e);
+          }
+
+          int msgID = MSGID_CONFIG_BACKEND_CANNOT_INITIALIZE;
+          String message = getMessage(msgID, String.valueOf(className),
+                                      String.valueOf(backendDN),
+                                      stackTraceToSingleLineString(e));
+          logError(ErrorLogCategory.CONFIGURATION,
+                   ErrorLogSeverity.SEVERE_ERROR,
+                   message, msgID);
+
+          try
+          {
+            String lockFile = LockFileManager.getBackendLockFileName(backend);
+            StringBuilder failureReason = new StringBuilder();
+            if (! LockFileManager.releaseLock(lockFile, failureReason))
+            {
+              msgID = MSGID_CONFIG_BACKEND_CANNOT_RELEASE_SHARED_LOCK;
+              message = getMessage(msgID, backendID,
+                                   String.valueOf(failureReason));
+              logError(ErrorLogCategory.CONFIGURATION,
+                       ErrorLogSeverity.SEVERE_WARNING, message, msgID);
+              // FIXME -- Do we need to send an admin alert?
+            }
+          }
+          catch (Exception e2)
+          {
+            if (debugEnabled())
+            {
+              debugCaught(DebugLogLevel.ERROR, e2);
+            }
+
             msgID = MSGID_CONFIG_BACKEND_CANNOT_RELEASE_SHARED_LOCK;
             message = getMessage(msgID, backendID,
-                                 String.valueOf(failureReason));
+                                 stackTraceToSingleLineString(e2));
             logError(ErrorLogCategory.CONFIGURATION,
                      ErrorLogSeverity.SEVERE_WARNING, message, msgID);
             // FIXME -- Do we need to send an admin alert?
           }
+
+          continue;
         }
-        catch (Exception e2)
+
+
+        // Notify any backend initialization listeners.
+        for (BackendInitializationListener listener :
+             DirectoryServer.getBackendInitializationListeners())
+        {
+          listener.performBackendInitializationProcessing(backend);
+        }
+
+
+        // Register the backend with the server.
+        try
+        {
+          DirectoryServer.registerBackend(backend);
+        }
+        catch (Exception e)
         {
           if (debugEnabled())
           {
-            debugCaught(DebugLogLevel.ERROR, e2);
+            debugCaught(DebugLogLevel.ERROR, e);
           }
 
-          msgID = MSGID_CONFIG_BACKEND_CANNOT_RELEASE_SHARED_LOCK;
-          message = getMessage(msgID, backendID,
-                               stackTraceToSingleLineString(e2));
+          int msgID = MSGID_CONFIG_BACKEND_CANNOT_REGISTER_BACKEND;
+          String message = getMessage(msgID, backendID,
+                                      stackTraceToSingleLineString(e));
           logError(ErrorLogCategory.CONFIGURATION,
-                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
+                   ErrorLogSeverity.SEVERE_ERROR,
+                   message, msgID);
           // FIXME -- Do we need to send an admin alert?
         }
 
-        continue;
+
+        // Put this backend in the hash so that we will be able to find it if it
+        // is altered.
+        registeredBackends.put(backendDN, backend);
+
       }
-
-
-      // Notify any backend initialization listeners.
-      for (BackendInitializationListener listener :
-           DirectoryServer.getBackendInitializationListeners())
+      else
       {
-        listener.performBackendInitializationProcessing(backend);
+        // The backend is explicitly disabled.  Log a mild warning and
+        // continue.
+        int msgID = MSGID_CONFIG_BACKEND_DISABLED;
+        String message = getMessage(msgID, String.valueOf(backendDN));
+        logError(ErrorLogCategory.CONFIGURATION,
+                 ErrorLogSeverity.INFORMATIONAL, message, msgID);
       }
-
-
-      // Register the backend with the server.
-      try
-      {
-        DirectoryServer.registerBackend(backend);
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          debugCaught(DebugLogLevel.ERROR, e);
-        }
-
-        msgID = MSGID_CONFIG_BACKEND_CANNOT_REGISTER_BACKEND;
-        String message = getMessage(msgID, backendID,
-                                    stackTraceToSingleLineString(e));
-        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
-                 message, msgID);
-        // FIXME -- Do we need to send an admin alert?
-      }
-
-
-      // Put this backend in the hash so that we will be able to find it if it
-      // is altered.
-      registeredBackends.put(backendDN, backend);
     }
   }
 
 
-
   /**
-   * Indicates whether the configuration entry that will result from a proposed
-   * modification is acceptable to this change listener.
-   *
-   * @param  configEntry         The configuration entry that will result from
-   *                             the requested update.
-   * @param  unacceptableReason  A buffer to which this method can append a
-   *                             human-readable message explaining why the
-   *                             proposed change is not acceptable.
-   *
-   * @return  <CODE>true</CODE> if the proposed entry contains an acceptable
-   *          configuration, or <CODE>false</CODE> if it does not.
+   * {@inheritDoc}
    */
-  public boolean configChangeIsAcceptable(ConfigEntry configEntry,
-                                          StringBuilder unacceptableReason)
+  public boolean isConfigurationChangeAcceptable(
+       BackendCfg configEntry,
+       List<String> unacceptableReason)
   {
-    DN backendDN = configEntry.getDN();
+    DN backendDN = configEntry.dn();
 
 
-    // Check to see if this entry appears to contain a backend configuration.
-    // If not, log a warning and skip it.
-    try
+    Set<DN> baseDNs = configEntry.getBackendBaseDN();
+
+    // See if the backend is registered with the server.  If it is, then
+    // see what's changed and whether those changes are acceptable.
+    Backend backend = registeredBackends.get(backendDN);
+    if (backend != null)
     {
-      SearchFilter backendFilter =
-           SearchFilter.createFilterFromString("(objectClass=" + OC_BACKEND +
-                                               ")");
-      if (! backendFilter.matchesEntry(configEntry.getEntry()))
+      LinkedHashSet<DN> removedDNs = new LinkedHashSet<DN>();
+      for (DN dn : backend.getBaseDNs())
       {
-        int msgID = MSGID_CONFIG_BACKEND_ENTRY_DOES_NOT_HAVE_BACKEND_CONFIG;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
-        return false;
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
+        removedDNs.add(dn);
       }
 
-      int msgID = MSGID_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN),
-                                           stackTraceToSingleLineString(e)));
-      return false;
-    }
-
-
-    // See if the entry contains an attribute that indicates whether the
-    // backend should be enabled.  If it does not, or if it is not set to
-    // "true", then skip it.
-    int msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_ENABLED;
-    BooleanConfigAttribute enabledStub =
-         new BooleanConfigAttribute(ATTR_BACKEND_ENABLED, getMessage(msgID),
-                                    false);
-    try
-    {
-      BooleanConfigAttribute enabledAttr =
-           (BooleanConfigAttribute)
-           configEntry.getConfigAttribute(enabledStub);
-      if (enabledAttr == null)
+      LinkedHashSet<DN> addedDNs = new LinkedHashSet<DN>();
+      for (DN dn : baseDNs)
       {
-        // The attribute is not present, so this backend will be disabled.
-        msgID = MSGID_CONFIG_BACKEND_NO_ENABLED_ATTR;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
-        return false;
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
+        addedDNs.add(dn);
       }
 
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_ENABLED_STATE;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN),
-                                           stackTraceToSingleLineString(e)));
-      return false;
-    }
-
-
-    // See if the entry contains an attribute that specifies the backend ID.  If
-    // it does not, then reject it.
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BACKEND_ID;
-    StringConfigAttribute idStub =
-         new StringConfigAttribute(ATTR_BACKEND_ID, getMessage(msgID), true,
-                                   false, true);
-    try
-    {
-      StringConfigAttribute idAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(idStub);
-      if (idAttr == null)
+      Iterator<DN> iterator = removedDNs.iterator();
+      while (iterator.hasNext())
       {
-        // The attribute is not present.  We will not allow this.
-        msgID = MSGID_CONFIG_BACKEND_NO_BACKEND_ID;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
-        return false;
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_BACKEND_ID;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN),
-                                           stackTraceToSingleLineString(e)));
-      return false;
-    }
-
-
-    // See if the entry contains an attribute that specifies the writability
-    // mode.  If it does not, then reject it.
-    LinkedHashSet<String> writabilityModes = new LinkedHashSet<String>(3);
-    writabilityModes.add(WritabilityMode.ENABLED.toString());
-    writabilityModes.add(WritabilityMode.DISABLED.toString());
-    writabilityModes.add(WritabilityMode.INTERNAL_ONLY.toString());
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_WRITABILITY;
-    MultiChoiceConfigAttribute writabilityStub =
-         new MultiChoiceConfigAttribute(ATTR_BACKEND_WRITABILITY_MODE,
-                                        getMessage(msgID), true, false, false,
-                                        writabilityModes);
-    try
-    {
-      MultiChoiceConfigAttribute writabilityAttr =
-           (MultiChoiceConfigAttribute)
-           configEntry.getConfigAttribute(writabilityStub);
-      if (writabilityAttr == null)
-      {
-        msgID = MSGID_CONFIG_BACKEND_NO_WRITABILITY_MODE;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
-        return false;
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_WRITABILITY;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN),
-                                           stackTraceToSingleLineString(e)));
-      return false;
-    }
-
-
-    // See if the entry contains an attribute that specifies the set of base DNs
-    // for the backend.  If it does not, then skip it.
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS;
-    DNConfigAttribute baseDNStub =
-         new DNConfigAttribute(ATTR_BACKEND_BASE_DN, getMessage(msgID), true,
-                               true, true);
-    try
-    {
-      DNConfigAttribute baseDNAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(baseDNStub);
-      if (baseDNAttr == null)
-      {
-        // The attribute is not present.  We will not allow this.
-        msgID = MSGID_CONFIG_BACKEND_NO_BASE_DNS;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
-        return false;
-      }
-
-      // See if the backend is registered with the server.  If it is, then
-      // see what's changed and whether those changes are acceptable.
-      Backend backend = registeredBackends.get(configEntryDN);
-      if (backend != null)
-      {
-        LinkedHashSet<DN> removedDNs = new LinkedHashSet<DN>();
-        for (DN dn : backend.getBaseDNs())
+        DN dn = iterator.next();
+        if (addedDNs.remove(dn))
         {
-          removedDNs.add(dn);
-        }
-
-        LinkedHashSet<DN> addedDNs = new LinkedHashSet<DN>();
-        for (DN dn : baseDNAttr.pendingValues())
-        {
-          addedDNs.add(dn);
-        }
-
-        Iterator<DN> iterator = removedDNs.iterator();
-        while (iterator.hasNext())
-        {
-          DN dn = iterator.next();
-          if (addedDNs.remove(dn))
-          {
-            iterator.remove();
-          }
-        }
-
-        for (DN dn : addedDNs)
-        {
-          try
-          {
-            DirectoryServer.registerBaseDN(dn, backend, false, true);
-          }
-          catch (DirectoryException de)
-          {
-            if (debugEnabled())
-            {
-              debugCaught(DebugLogLevel.ERROR, de);
-            }
-
-            unacceptableReason.append(de.getMessage());
-            return false;
-          }
-        }
-
-        for (DN dn : removedDNs)
-        {
-          try
-          {
-            DirectoryServer.deregisterBaseDN(dn, true);
-          }
-          catch (DirectoryException de)
-          {
-            if (debugEnabled())
-            {
-              debugCaught(DebugLogLevel.ERROR, de);
-            }
-
-            unacceptableReason.append(de.getMessage());
-            return false;
-          }
+          iterator.remove();
         }
       }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
+
+      for (DN dn : addedDNs)
       {
-        debugCaught(DebugLogLevel.ERROR, e);
+        try
+        {
+          DirectoryServer.registerBaseDN(dn, backend, false, true);
+        }
+        catch (DirectoryException de)
+        {
+          if (debugEnabled())
+          {
+            debugCaught(DebugLogLevel.ERROR, de);
+          }
+
+          unacceptableReason.add(de.getMessage());
+          return false;
+        }
       }
 
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_BASE_DNS;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN),
-                                stackTraceToSingleLineString(e)));
-      return false;
+      for (DN dn : removedDNs)
+      {
+        try
+        {
+          DirectoryServer.deregisterBaseDN(dn, true);
+        }
+        catch (DirectoryException de)
+        {
+          if (debugEnabled())
+          {
+            debugCaught(DebugLogLevel.ERROR, de);
+          }
+
+          unacceptableReason.add(de.getMessage());
+          return false;
+        }
+      }
     }
 
 
@@ -854,47 +470,15 @@
     // that it's a valid backend implementation.  There is no such attribute,
     // the specified class cannot be loaded, or it does not contain a valid
     // backend implementation, then log an error and skip it.
-    String className;
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_CLASS;
-    StringConfigAttribute classStub =
-         new StringConfigAttribute(ATTR_BACKEND_CLASS, getMessage(msgID),
-                                   true, false, true);
-    try
-    {
-      StringConfigAttribute classAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(classStub);
-      if (classAttr == null)
-      {
-        msgID = MSGID_CONFIG_BACKEND_NO_CLASS_ATTR;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
-        return false;
-      }
-      else
-      {
-        className = classAttr.pendingValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_CANNOT_GET_CLASS;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN),
-                                           stackTraceToSingleLineString(e)));
-      return false;
-    }
-
+    String className = configEntry.getBackendClass();
     try
     {
       Class backendClass = DirectoryServer.loadClass(className);
       if (! Backend.class.isAssignableFrom(backendClass))
       {
-        msgID = MSGID_CONFIG_BACKEND_CLASS_NOT_BACKEND;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(className),
-                                             String.valueOf(backendDN)));
+        int msgID = MSGID_CONFIG_BACKEND_CLASS_NOT_BACKEND;
+        unacceptableReason.add(getMessage(msgID, String.valueOf(className),
+                                          String.valueOf(backendDN)));
         return false;
       }
     }
@@ -905,10 +489,10 @@
         debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      msgID = MSGID_CONFIG_BACKEND_CANNOT_INSTANTIATE;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(className),
-                                           String.valueOf(backendDN),
-                                           stackTraceToSingleLineString(e)));
+      int msgID = MSGID_CONFIG_BACKEND_CANNOT_INSTANTIATE;
+      unacceptableReason.add(getMessage(msgID, String.valueOf(className),
+                                        String.valueOf(backendDN),
+                                        stackTraceToSingleLineString(e)));
       return false;
     }
 
@@ -920,79 +504,24 @@
   }
 
 
-
   /**
-   * Attempts to apply a new configuration to this Directory Server component
-   * based on the provided changed entry.
-   *
-   * @param  configEntry  The configuration entry that containing the updated
-   *                      configuration for this component.
-   *
-   * @return  Information about the result of processing the configuration
-   *          change.
+   * {@inheritDoc}
    */
-  public ConfigChangeResult applyConfigurationChange(ConfigEntry configEntry)
+  public ConfigChangeResult applyConfigurationChange(BackendCfg cfg)
   {
-    DN                backendDN           = configEntry.getDN();
+    DN                backendDN           = cfg.dn();
     Backend           backend             = registeredBackends.get(backendDN);
     ResultCode        resultCode          = ResultCode.SUCCESS;
     boolean           adminActionRequired = false;
     ArrayList<String> messages            = new ArrayList<String>();
 
 
-    // Check to see if this entry appears to contain a backend configuration.
-    // If not, log a warning and skip it.
-    try
-    {
-      SearchFilter backendFilter =
-           SearchFilter.createFilterFromString("(objectClass=" + OC_BACKEND +
-                                               ")");
-      if (! backendFilter.matchesEntry(configEntry.getEntry()))
-      {
-        int msgID = MSGID_CONFIG_BACKEND_ENTRY_DOES_NOT_HAVE_BACKEND_CONFIG;
-        messages.add(getMessage(msgID, String.valueOf(backendDN)));
-        resultCode = ResultCode.UNWILLING_TO_PERFORM;
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      int msgID = MSGID_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY;
-      messages.add(getMessage(msgID, String.valueOf(backendDN),
-                              stackTraceToSingleLineString(e)));
-      resultCode = DirectoryServer.getServerErrorResultCode();
-      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
-    }
-
-
     // See if the entry contains an attribute that indicates whether the
     // backend should be enabled.
     boolean needToEnable = false;
-    int msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_ENABLED;
-    BooleanConfigAttribute enabledStub =
-         new BooleanConfigAttribute(ATTR_BACKEND_ENABLED, getMessage(msgID),
-                                    false);
     try
     {
-      BooleanConfigAttribute enabledAttr =
-           (BooleanConfigAttribute)
-           configEntry.getConfigAttribute(enabledStub);
-      if (enabledAttr == null)
-      {
-        // The attribute is not present.  We won't allow this.
-        msgID = MSGID_CONFIG_BACKEND_NO_ENABLED_ATTR;
-        messages.add(getMessage(msgID, String.valueOf(backendDN)));
-        resultCode = ResultCode.UNWILLING_TO_PERFORM;
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
-      else if (enabledAttr.pendingValue())
+      if (cfg.isBackendEnabled())
       {
         // The backend is marked as enabled.  See if that is already true.
         if (backend == null)
@@ -1029,7 +558,7 @@
             StringBuilder failureReason = new StringBuilder();
             if (! LockFileManager.releaseLock(lockFile, failureReason))
             {
-              msgID = MSGID_CONFIG_BACKEND_CANNOT_RELEASE_SHARED_LOCK;
+              int msgID = MSGID_CONFIG_BACKEND_CANNOT_RELEASE_SHARED_LOCK;
               String message = getMessage(msgID, backend.getBackendID(),
                                           String.valueOf(failureReason));
               logError(ErrorLogCategory.CONFIGURATION,
@@ -1044,7 +573,7 @@
               debugCaught(DebugLogLevel.ERROR, e2);
             }
 
-            msgID = MSGID_CONFIG_BACKEND_CANNOT_RELEASE_SHARED_LOCK;
+            int msgID = MSGID_CONFIG_BACKEND_CANNOT_RELEASE_SHARED_LOCK;
             String message = getMessage(msgID, backend.getBackendID(),
                                         stackTraceToSingleLineString(e2));
             logError(ErrorLogCategory.CONFIGURATION,
@@ -1068,7 +597,7 @@
         debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_ENABLED_STATE;
+      int msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_ENABLED_STATE;
       messages.add(getMessage(msgID, String.valueOf(backendDN),
                               stackTraceToSingleLineString(e)));
       resultCode = DirectoryServer.getServerErrorResultCode();
@@ -1078,141 +607,32 @@
 
     // See if the entry contains an attribute that specifies the backend ID for
     // the backend.
-    String backendID = null;
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BACKEND_ID;
-    StringConfigAttribute idStub =
-         new StringConfigAttribute(ATTR_BACKEND_ID, getMessage(msgID), true,
-                                   false, true);
-    try
-    {
-      StringConfigAttribute idAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(idStub);
-      if (idAttr == null)
-      {
-        // The attribute is not present.  We won't allow this.
-        msgID = MSGID_CONFIG_BACKEND_NO_BACKEND_ID;
-        messages.add(getMessage(msgID, String.valueOf(backendDN)));
-        resultCode = ResultCode.UNWILLING_TO_PERFORM;
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
-      else
-      {
-        backendID = idAttr.pendingValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_BACKEND_ID;
-      messages.add(getMessage(msgID, String.valueOf(backendDN),
-                              stackTraceToSingleLineString(e)));
-      resultCode = DirectoryServer.getServerErrorResultCode();
-      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
-    }
-
+    String backendID = cfg.getBackendId();
 
     // See if the entry contains an attribute that specifies the writability
     // mode.
-    LinkedHashSet<String> writabilityModes = new LinkedHashSet<String>(3);
-    writabilityModes.add(WritabilityMode.ENABLED.toString());
-    writabilityModes.add(WritabilityMode.DISABLED.toString());
-    writabilityModes.add(WritabilityMode.INTERNAL_ONLY.toString());
-
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_WRITABILITY;
-    WritabilityMode writabilityMode = null;
-    MultiChoiceConfigAttribute writabilityStub =
-         new MultiChoiceConfigAttribute(ATTR_BACKEND_WRITABILITY_MODE,
-                                        getMessage(msgID), true, false, false,
-                                        writabilityModes);
-    try
+    WritabilityMode writabilityMode = WritabilityMode.ENABLED;
+    BackendCfgDefn.BackendWritabilityMode bwm =
+         cfg.getBackendWritabilityMode();
+    switch (bwm)
     {
-      MultiChoiceConfigAttribute writabilityAttr =
-           (MultiChoiceConfigAttribute)
-           configEntry.getConfigAttribute(writabilityStub);
-      if (writabilityStub == null)
-      {
-        msgID = MSGID_CONFIG_BACKEND_NO_WRITABILITY_MODE;
-        messages.add(getMessage(msgID, String.valueOf(backendDN)));
-
-        resultCode = ResultCode.UNWILLING_TO_PERFORM;
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
-      else
-      {
-        writabilityMode =
-             WritabilityMode.modeForName(writabilityAttr.activeValue());
-        if (writabilityMode == null)
-        {
-          msgID = MSGID_CONFIG_BACKEND_INVALID_WRITABILITY_MODE;
-          messages.add(getMessage(msgID, String.valueOf(backendDN),
-                            String.valueOf(writabilityAttr.activeValue())));
-          resultCode = ResultCode.INVALID_ATTRIBUTE_SYNTAX;
-          return new ConfigChangeResult(resultCode, adminActionRequired,
-                                        messages);
-        }
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_WRITABILITY;
-      messages.add(getMessage(msgID, String.valueOf(backendDN),
-                              stackTraceToSingleLineString(e)));
-      resultCode = DirectoryServer.getServerErrorResultCode();
-      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+      case DISABLED:
+        writabilityMode = WritabilityMode.DISABLED;
+        break;
+      case ENABLED:
+        writabilityMode = WritabilityMode.ENABLED;
+        break;
+      case INTERNAL_ONLY:
+        writabilityMode = WritabilityMode.INTERNAL_ONLY;
+        break;
     }
 
 
     // See if the entry contains an attribute that specifies the base DNs for
     // the backend.
-    DN[] baseDNs = null;
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS;
-    DNConfigAttribute baseDNStub =
-         new DNConfigAttribute(ATTR_BACKEND_BASE_DN, getMessage(msgID), true,
-                               true, true);
-    try
-    {
-      DNConfigAttribute baseDNAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(baseDNStub);
-      if (baseDNAttr == null)
-      {
-        // The attribute is not present.  We won't allow this.
-        msgID = MSGID_CONFIG_BACKEND_NO_BASE_DNS;
-        messages.add(getMessage(msgID, String.valueOf(backendDN)));
-        resultCode = ResultCode.UNWILLING_TO_PERFORM;
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
-      else
-      {
-        List<DN> baseList = baseDNAttr.pendingValues();
-        baseDNs = new DN[baseList.size()];
-        baseList.toArray(baseDNs);
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_BASE_DNS;
-      messages.add(getMessage(msgID, String.valueOf(backendDN),
-                              stackTraceToSingleLineString(e)));
-      resultCode = DirectoryServer.getServerErrorResultCode();
-      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
-    }
+    Set<DN> baseList = cfg.getBackendBaseDN();
+    DN[] baseDNs = new DN[baseList.size()];
+    baseList.toArray(baseDNs);
 
 
     // See if the entry contains an attribute that specifies the class name
@@ -1220,42 +640,7 @@
     // that it's a valid backend implementation.  There is no such attribute,
     // the specified class cannot be loaded, or it does not contain a valid
     // backend implementation, then log an error and skip it.
-    String className;
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_CLASS;
-    StringConfigAttribute classStub =
-         new StringConfigAttribute(ATTR_BACKEND_CLASS, getMessage(msgID),
-                                   true, false, true);
-    try
-    {
-      StringConfigAttribute classAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(classStub);
-      if (classAttr == null)
-      {
-        msgID = MSGID_CONFIG_BACKEND_NO_CLASS_ATTR;
-        messages.add(getMessage(msgID, String.valueOf(backendDN)));
-        resultCode = ResultCode.UNWILLING_TO_PERFORM;
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
-      else
-      {
-        className = classAttr.pendingValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_CANNOT_GET_CLASS;
-      messages.add(getMessage(msgID, String.valueOf(backendDN),
-                              stackTraceToSingleLineString(e)));
-      resultCode = DirectoryServer.getServerErrorResultCode();
-      return new ConfigChangeResult(resultCode, adminActionRequired,
-                                    messages);
-    }
+    String className = cfg.getBackendClass();
 
 
     // See if this backend is currently active and if so if the name of the
@@ -1274,7 +659,7 @@
             // It appears to be a valid backend class.  We'll return that the
             // change is successful, but indicate that some administrative
             // action is required.
-            msgID = MSGID_CONFIG_BACKEND_ACTION_REQUIRED_TO_CHANGE_CLASS;
+            int msgID = MSGID_CONFIG_BACKEND_ACTION_REQUIRED_TO_CHANGE_CLASS;
             messages.add(getMessage(msgID, String.valueOf(backendDN),
                                     backend.getClass().getName(), className));
             adminActionRequired = true;
@@ -1284,7 +669,7 @@
           else
           {
             // It is not a valid backend class.  This is an error.
-            msgID = MSGID_CONFIG_BACKEND_CLASS_NOT_BACKEND;
+            int msgID = MSGID_CONFIG_BACKEND_CLASS_NOT_BACKEND;
             messages.add(getMessage(msgID, String.valueOf(className),
                                     String.valueOf(backendDN)));
             resultCode = ResultCode.CONSTRAINT_VIOLATION;
@@ -1299,7 +684,7 @@
             debugCaught(DebugLogLevel.ERROR, e);
           }
 
-          msgID = MSGID_CONFIG_BACKEND_CANNOT_INSTANTIATE;
+          int msgID = MSGID_CONFIG_BACKEND_CANNOT_INSTANTIATE;
           messages.add(getMessage(msgID, String.valueOf(className),
                                   String.valueOf(backendDN),
                                   stackTraceToSingleLineString(e)));
@@ -1315,15 +700,16 @@
     // backend.  Try to do so.
     if (needToEnable)
     {
+      Class backendClass;
       try
       {
-        Class backendClass = DirectoryServer.loadClass(className);
+        backendClass = DirectoryServer.loadClass(className);
         backend = (Backend) backendClass.newInstance();
       }
       catch (Exception e)
       {
         // It is not a valid backend class.  This is an error.
-        msgID = MSGID_CONFIG_BACKEND_CLASS_NOT_BACKEND;
+        int msgID = MSGID_CONFIG_BACKEND_CLASS_NOT_BACKEND;
         messages.add(getMessage(msgID, String.valueOf(className),
                                 String.valueOf(backendDN)));
         resultCode = ResultCode.CONSTRAINT_VIOLATION;
@@ -1345,7 +731,7 @@
         StringBuilder failureReason = new StringBuilder();
         if (! LockFileManager.acquireSharedLock(lockFile, failureReason))
         {
-          msgID = MSGID_CONFIG_BACKEND_CANNOT_ACQUIRE_SHARED_LOCK;
+          int msgID = MSGID_CONFIG_BACKEND_CANNOT_ACQUIRE_SHARED_LOCK;
           String message = getMessage(msgID, backendID,
                                       String.valueOf(failureReason));
           logError(ErrorLogCategory.CONFIGURATION,
@@ -1366,7 +752,7 @@
           debugCaught(DebugLogLevel.ERROR, e);
         }
 
-        msgID = MSGID_CONFIG_BACKEND_CANNOT_ACQUIRE_SHARED_LOCK;
+        int msgID = MSGID_CONFIG_BACKEND_CANNOT_ACQUIRE_SHARED_LOCK;
         String message = getMessage(msgID, backendID,
                                     stackTraceToSingleLineString(e));
         logError(ErrorLogCategory.CONFIGURATION,
@@ -1383,7 +769,8 @@
 
       try
       {
-        backend.initializeBackend(configEntry, baseDNs);
+        backend.initializeBackend(
+             DirectoryServer.getConfigEntry(cfg.dn()), baseDNs);
       }
       catch (Exception e)
       {
@@ -1392,7 +779,7 @@
           debugCaught(DebugLogLevel.ERROR, e);
         }
 
-        msgID = MSGID_CONFIG_BACKEND_CANNOT_INITIALIZE;
+        int msgID = MSGID_CONFIG_BACKEND_CANNOT_INITIALIZE;
         messages.add(getMessage(msgID, String.valueOf(className),
                                 String.valueOf(backendDN),
                                 stackTraceToSingleLineString(e)));
@@ -1452,7 +839,7 @@
           debugCaught(DebugLogLevel.ERROR, e);
         }
 
-        msgID = MSGID_CONFIG_BACKEND_CANNOT_REGISTER_BACKEND;
+        int msgID = MSGID_CONFIG_BACKEND_CANNOT_REGISTER_BACKEND;
         String message = getMessage(msgID, backendID,
                                     stackTraceToSingleLineString(e));
 
@@ -1486,203 +873,33 @@
   }
 
 
-
   /**
-   * Indicates whether the configuration entry that will result from a proposed
-   * add is acceptable to this add listener.
-   *
-   * @param  configEntry         The configuration entry that will result from
-   *                             the requested add.
-   * @param  unacceptableReason  A buffer to which this method can append a
-   *                             human-readable message explaining why the
-   *                             proposed entry is not acceptable.
-   *
-   * @return  <CODE>true</CODE> if the proposed entry contains an acceptable
-   *          configuration, or <CODE>false</CODE> if it does not.
+   * {@inheritDoc}
    */
-  public boolean configAddIsAcceptable(ConfigEntry configEntry,
-                                       StringBuilder unacceptableReason)
+  public boolean isConfigurationAddAcceptable(
+       BackendCfg configEntry,
+       List<String> unacceptableReason)
   {
-    DN backendDN = configEntry.getDN();
-
-
-    // Check to see if this entry appears to contain a backend configuration.
-    // If not then fail.
-    try
-    {
-      SearchFilter backendFilter =
-           SearchFilter.createFilterFromString("(objectClass=" + OC_BACKEND +
-                                               ")");
-      if (! backendFilter.matchesEntry(configEntry.getEntry()))
-      {
-        int msgID = MSGID_CONFIG_BACKEND_ENTRY_DOES_NOT_HAVE_BACKEND_CONFIG;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
-        return false;
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      int msgID = MSGID_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN),
-                                           stackTraceToSingleLineString(e)));
-      return false;
-    }
-
-
-    // See if the entry contains an attribute that indicates whether the
-    // backend should be enabled.  If it does not, or if it is not set to
-    // "true", then skip it.
-    int msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_ENABLED;
-    BooleanConfigAttribute enabledStub =
-         new BooleanConfigAttribute(ATTR_BACKEND_ENABLED, getMessage(msgID),
-                                    false);
-    try
-    {
-      BooleanConfigAttribute enabledAttr =
-           (BooleanConfigAttribute)
-           configEntry.getConfigAttribute(enabledStub);
-      if (enabledAttr == null)
-      {
-        // The attribute is not present.  We will not allow this.
-        msgID = MSGID_CONFIG_BACKEND_NO_ENABLED_ATTR;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
-        return false;
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_ENABLED_STATE;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN),
-                                           stackTraceToSingleLineString(e)));
-      return false;
-    }
+    DN backendDN = configEntry.dn();
 
 
     // See if the entry contains an attribute that specifies the backend ID.  If
     // it does not, then skip it.
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BACKEND_ID;
-    StringConfigAttribute idStub =
-         new StringConfigAttribute(ATTR_BACKEND_ID, getMessage(msgID), true,
-                                   false, true);
-    try
+    String backendID = configEntry.getBackendId();
+    if (DirectoryServer.hasBackend(backendID))
     {
-      StringConfigAttribute idAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(idStub);
-      if (idAttr == null)
-      {
-        // The attribute is not present.  We will not allow this.
-        msgID = MSGID_CONFIG_BACKEND_NO_BACKEND_ID;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
-        return false;
-      }
-      else
-      {
-        String backendID = idAttr.activeValue();
-        if (DirectoryServer.hasBackend(backendID))
-        {
-          msgID = MSGID_CONFIG_BACKEND_DUPLICATE_BACKEND_ID;
-          unacceptableReason.append(getMessage(msgID,
-                                               String.valueOf(backendDN)));
-          return false;
-        }
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_BACKEND_ID;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN),
-                                           stackTraceToSingleLineString(e)));
-      return false;
-    }
-
-
-    // See if the entry contains an attribute that specifies the writability
-    // mode.  If it does not, then reject it.
-    LinkedHashSet<String> writabilityModes = new LinkedHashSet<String>(3);
-    writabilityModes.add(WritabilityMode.ENABLED.toString());
-    writabilityModes.add(WritabilityMode.DISABLED.toString());
-    writabilityModes.add(WritabilityMode.INTERNAL_ONLY.toString());
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_WRITABILITY;
-    MultiChoiceConfigAttribute writabilityStub =
-         new MultiChoiceConfigAttribute(ATTR_BACKEND_WRITABILITY_MODE,
-                                        getMessage(msgID), true, false, false,
-                                        writabilityModes);
-    try
-    {
-      MultiChoiceConfigAttribute writabilityAttr =
-           (MultiChoiceConfigAttribute)
-           configEntry.getConfigAttribute(writabilityStub);
-      if (writabilityAttr == null)
-      {
-        msgID = MSGID_CONFIG_BACKEND_NO_WRITABILITY_MODE;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
-        return false;
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_WRITABILITY;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN),
-                                           stackTraceToSingleLineString(e)));
+      int msgID = MSGID_CONFIG_BACKEND_DUPLICATE_BACKEND_ID;
+      unacceptableReason.add(getMessage(msgID,
+                                        String.valueOf(backendDN)));
       return false;
     }
 
 
     // See if the entry contains an attribute that specifies the set of base DNs
     // for the backend.  If it does not, then skip it.
-    List<DN> baseDNs = null;
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS;
-    DNConfigAttribute baseDNStub =
-         new DNConfigAttribute(ATTR_BACKEND_BASE_DN, getMessage(msgID), true,
-                               true, true);
-    try
-    {
-      DNConfigAttribute baseDNAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(baseDNStub);
-      if (baseDNAttr == null)
-      {
-        // The attribute is not present.  We will not allow this.
-        msgID = MSGID_CONFIG_BACKEND_NO_BASE_DNS;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
-        return false;
-      }
-      else
-      {
-        baseDNs = baseDNAttr.pendingValues();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_BASE_DNS;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN),
-                                stackTraceToSingleLineString(e)));
-      return false;
-    }
+    Set<DN> baseList = configEntry.getBackendBaseDN();
+    DN[] baseDNs = new DN[baseList.size()];
+    baseList.toArray(baseDNs);
 
 
     // See if the entry contains an attribute that specifies the class name
@@ -1690,38 +907,7 @@
     // that it's a valid backend implementation.  There is no such attribute,
     // the specified class cannot be loaded, or it does not contain a valid
     // backend implementation, then log an error and skip it.
-    String className;
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_CLASS;
-    StringConfigAttribute classStub =
-         new StringConfigAttribute(ATTR_BACKEND_CLASS, getMessage(msgID),
-                                   true, false, true);
-    try
-    {
-      StringConfigAttribute classAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(classStub);
-      if (classAttr == null)
-      {
-        msgID = MSGID_CONFIG_BACKEND_NO_CLASS_ATTR;
-        unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
-        return false;
-      }
-      else
-      {
-        className = classAttr.pendingValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_CANNOT_GET_CLASS;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN),
-                                           stackTraceToSingleLineString(e)));
-      return false;
-    }
+    String className = configEntry.getBackendClass();
 
     Backend backend;
     try
@@ -1736,42 +922,42 @@
         debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      msgID = MSGID_CONFIG_BACKEND_CANNOT_INSTANTIATE;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(className),
-                                           String.valueOf(backendDN),
-                                           stackTraceToSingleLineString(e)));
+      int msgID = MSGID_CONFIG_BACKEND_CANNOT_INSTANTIATE;
+      unacceptableReason.add(getMessage(msgID, String.valueOf(className),
+                                        String.valueOf(backendDN),
+                                        stackTraceToSingleLineString(e)));
       return false;
     }
 
 
     // If the backend is a configurable component, then make sure that its
     // configuration is valid.
-    if (backend instanceof ConfigurableComponent)
-    {
-      ConfigurableComponent cc = (ConfigurableComponent) backend;
-      LinkedList<String> errorMessages = new LinkedList<String>();
-      if (! cc.hasAcceptableConfiguration(configEntry, errorMessages))
-      {
-        if (errorMessages.isEmpty())
-        {
-          msgID = MSGID_CONFIG_BACKEND_UNACCEPTABLE_CONFIG;
-          unacceptableReason.append(getMessage(msgID,
-                                               String.valueOf(configEntryDN)));
-        }
-        else
-        {
-          Iterator<String> iterator = errorMessages.iterator();
-          unacceptableReason.append(iterator.next());
-          while (iterator.hasNext())
-          {
-            unacceptableReason.append("  ");
-            unacceptableReason.append(iterator.next());
-          }
-        }
-
-        return false;
-      }
-    }
+//    if (backend instanceof ConfigurableComponent)
+//    {
+//      ConfigurableComponent cc = (ConfigurableComponent) backend;
+//      LinkedList<String> errorMessages = new LinkedList<String>();
+//      if (! cc.hasAcceptableConfiguration(configEntry, errorMessages))
+//      {
+//        if (errorMessages.isEmpty())
+//        {
+//          int msgID = MSGID_CONFIG_BACKEND_UNACCEPTABLE_CONFIG;
+//          unacceptableReason.add(getMessage(msgID,
+//                                            String.valueOf(configEntryDN)));
+//        }
+//        else
+//        {
+//          Iterator<String> iterator = errorMessages.iterator();
+//          unacceptableReason.add(iterator.next());
+//          while (iterator.hasNext())
+//          {
+//            unacceptableReason.add("  ");
+//            unacceptableReason.add(iterator.next());
+//          }
+//        }
+//
+//        return false;
+//      }
+//    }
 
 
     // Make sure that all of the base DNs are acceptable for use in the server.
@@ -1783,12 +969,12 @@
       }
       catch (DirectoryException de)
       {
-        unacceptableReason.append(de.getMessage());
+        unacceptableReason.add(de.getMessage());
         return false;
       }
       catch (Exception e)
       {
-        unacceptableReason.append(stackTraceToSingleLineString(e));
+        unacceptableReason.add(stackTraceToSingleLineString(e));
         return false;
       }
     }
@@ -1803,17 +989,11 @@
 
 
   /**
-   * Attempts to apply a new configuration based on the provided added entry.
-   *
-   * @param  configEntry  The new configuration entry that contains the
-   *                      configuration to apply.
-   *
-   * @return  Information about the result of processing the configuration
-   *          change.
+   * {@inheritDoc}
    */
-  public ConfigChangeResult applyConfigurationAdd(ConfigEntry configEntry)
+  public ConfigChangeResult applyConfigurationAdd(BackendCfg cfg)
   {
-    DN                backendDN           = configEntry.getDN();
+    DN                backendDN           = cfg.dn();
     ResultCode        resultCode          = ResultCode.SUCCESS;
     boolean           adminActionRequired = false;
     ArrayList<String> messages            = new ArrayList<String>();
@@ -1821,241 +1001,66 @@
 
     // Register as a change listener for this backend entry so that we will
     // be notified of any changes that may be made to it.
-    configEntry.registerChangeListener(this);
-
-
-    // Check to see if this entry appears to contain a backend configuration.
-    // If not then fail.
-    try
-    {
-      SearchFilter backendFilter =
-           SearchFilter.createFilterFromString("(objectClass=" + OC_BACKEND +
-                                               ")");
-      if (! backendFilter.matchesEntry(configEntry.getEntry()))
-      {
-        int msgID = MSGID_CONFIG_BACKEND_ENTRY_DOES_NOT_HAVE_BACKEND_CONFIG;
-        messages.add(getMessage(msgID, String.valueOf(backendDN)));
-        resultCode = ResultCode.UNWILLING_TO_PERFORM;
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      int msgID = MSGID_CONFIG_BACKEND_ERROR_INTERACTING_WITH_BACKEND_ENTRY;
-      messages.add(getMessage(msgID, String.valueOf(backendDN),
-                              stackTraceToSingleLineString(e)));
-      resultCode = DirectoryServer.getServerErrorResultCode();
-      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
-    }
+    cfg.addChangeListener(this);
 
 
     // See if the entry contains an attribute that indicates whether the
     // backend should be enabled.  If it does not, or if it is not set to
     // "true", then skip it.
-    int msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_ENABLED;
-    BooleanConfigAttribute enabledStub =
-         new BooleanConfigAttribute(ATTR_BACKEND_ENABLED, getMessage(msgID),
-                                    false);
-    try
+    if (!cfg.isBackendEnabled())
     {
-      BooleanConfigAttribute enabledAttr =
-           (BooleanConfigAttribute)
-           configEntry.getConfigAttribute(enabledStub);
-      if (enabledAttr == null)
-      {
-        // The attribute is not present, so this backend will be disabled.  We
-        // will log a message to indicate that it won't be enabled and return.
-        msgID = MSGID_CONFIG_BACKEND_NO_ENABLED_ATTR;
-        String message = getMessage(msgID, String.valueOf(backendDN));
-        logError(ErrorLogCategory.CONFIGURATION,
-                 ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-        messages.add(message);
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
-      else if (! enabledAttr.activeValue())
-      {
-        // The backend is explicitly disabled.  We will log a message to
-        // indicate that it won't be enabled and return.
-        msgID = MSGID_CONFIG_BACKEND_DISABLED;
-        String message = getMessage(msgID, String.valueOf(backendDN));
-        logError(ErrorLogCategory.CONFIGURATION,
-                 ErrorLogSeverity.INFORMATIONAL, message, msgID);
-        messages.add(message);
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
+      // The backend is explicitly disabled.  We will log a message to
+      // indicate that it won't be enabled and return.
+      int msgID = MSGID_CONFIG_BACKEND_DISABLED;
+      String message = getMessage(msgID, String.valueOf(backendDN));
+      logError(ErrorLogCategory.CONFIGURATION,
+               ErrorLogSeverity.INFORMATIONAL, message, msgID);
+      messages.add(message);
+      return new ConfigChangeResult(resultCode, adminActionRequired,
+                                    messages);
     }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
 
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_ENABLED_STATE;
-      messages.add(getMessage(msgID, String.valueOf(backendDN),
-                              stackTraceToSingleLineString(e)));
-      resultCode = DirectoryServer.getServerErrorResultCode();
-      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
-    }
 
 
     // See if the entry contains an attribute that specifies the backend ID.  If
     // it does not, then skip it.
-    String backendID;
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BACKEND_ID;
-    StringConfigAttribute idStub =
-         new StringConfigAttribute(ATTR_BACKEND_ID, getMessage(msgID), true,
-                                   false, true);
-    try
+    String backendID = cfg.getBackendId();
+    if (DirectoryServer.hasBackend(backendID))
     {
-      StringConfigAttribute idAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(idStub);
-      if (idAttr == null)
-      {
-        msgID = MSGID_CONFIG_BACKEND_NO_BACKEND_ID;
-        String message = getMessage(msgID, String.valueOf(backendDN));
-        logError(ErrorLogCategory.CONFIGURATION,
-                 ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-        messages.add(message);
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
-      else
-      {
-        backendID = idAttr.pendingValue();
-        if (DirectoryServer.hasBackend(backendID))
-        {
-          msgID = MSGID_CONFIG_BACKEND_DUPLICATE_BACKEND_ID;
-          String message = getMessage(msgID, String.valueOf(backendDN));
-          logError(ErrorLogCategory.CONFIGURATION,
-                   ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-          messages.add(message);
-          return new ConfigChangeResult(resultCode, adminActionRequired,
-                                        messages);
-        }
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_BACKEND_ID;
-      messages.add(getMessage(msgID, String.valueOf(backendDN),
-                              stackTraceToSingleLineString(e)));
-      resultCode = DirectoryServer.getServerErrorResultCode();
-      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+      int msgID = MSGID_CONFIG_BACKEND_DUPLICATE_BACKEND_ID;
+      String message = getMessage(msgID, String.valueOf(backendDN));
+      logError(ErrorLogCategory.CONFIGURATION,
+               ErrorLogSeverity.SEVERE_WARNING, message, msgID);
+      messages.add(message);
+      return new ConfigChangeResult(resultCode, adminActionRequired,
+                                    messages);
     }
 
 
     // See if the entry contains an attribute that specifies the writability
     // mode.
-    LinkedHashSet<String> writabilityModes = new LinkedHashSet<String>(3);
-    writabilityModes.add(WritabilityMode.ENABLED.toString());
-    writabilityModes.add(WritabilityMode.DISABLED.toString());
-    writabilityModes.add(WritabilityMode.INTERNAL_ONLY.toString());
-
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_WRITABILITY;
-    WritabilityMode writabilityMode = null;
-    MultiChoiceConfigAttribute writabilityStub =
-         new MultiChoiceConfigAttribute(ATTR_BACKEND_WRITABILITY_MODE,
-                                        getMessage(msgID), true, false, false,
-                                        writabilityModes);
-    try
+    WritabilityMode writabilityMode = WritabilityMode.ENABLED;
+    BackendCfgDefn.BackendWritabilityMode bwm =
+         cfg.getBackendWritabilityMode();
+    switch (bwm)
     {
-      MultiChoiceConfigAttribute writabilityAttr =
-           (MultiChoiceConfigAttribute)
-           configEntry.getConfigAttribute(writabilityStub);
-      if (writabilityAttr == null)
-      {
-        msgID = MSGID_CONFIG_BACKEND_NO_WRITABILITY_MODE;
-        messages.add(getMessage(msgID, String.valueOf(backendDN)));
-
-        resultCode = ResultCode.UNWILLING_TO_PERFORM;
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
-      else
-      {
-        writabilityMode =
-             WritabilityMode.modeForName(writabilityAttr.activeValue());
-        if (writabilityMode == null)
-        {
-          msgID = MSGID_CONFIG_BACKEND_INVALID_WRITABILITY_MODE;
-          messages.add(getMessage(msgID, String.valueOf(backendDN),
-                            String.valueOf(writabilityAttr.activeValue())));
-          resultCode = ResultCode.INVALID_ATTRIBUTE_SYNTAX;
-          return new ConfigChangeResult(resultCode, adminActionRequired,
-                                        messages);
-        }
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_WRITABILITY;
-      messages.add(getMessage(msgID, String.valueOf(backendDN),
-                              stackTraceToSingleLineString(e)));
-      resultCode = DirectoryServer.getServerErrorResultCode();
-      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+      case DISABLED:
+        writabilityMode = WritabilityMode.DISABLED;
+        break;
+      case ENABLED:
+        writabilityMode = WritabilityMode.ENABLED;
+        break;
+      case INTERNAL_ONLY:
+        writabilityMode = WritabilityMode.INTERNAL_ONLY;
+        break;
     }
 
 
     // See if the entry contains an attribute that specifies the base DNs for
     // the entry.  If it does not, then skip it.
-    DN[] baseDNs = null;
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS;
-    DNConfigAttribute baseDNStub =
-         new DNConfigAttribute(ATTR_BACKEND_BASE_DN, getMessage(msgID),
-                               true, true, true);
-    try
-    {
-      DNConfigAttribute baseDNAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(baseDNStub);
-      if (baseDNAttr == null)
-      {
-        msgID = MSGID_CONFIG_BACKEND_NO_BASE_DNS;
-        String message = getMessage(msgID, String.valueOf(backendDN));
-        logError(ErrorLogCategory.CONFIGURATION,
-                 ErrorLogSeverity.SEVERE_WARNING, message, msgID);
-        messages.add(message);
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
-      else
-      {
-        List<DN> dnList = baseDNAttr.pendingValues();
-        baseDNs = new DN[dnList.size()];
-        dnList.toArray(baseDNs);
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_UNABLE_TO_DETERMINE_BASE_DNS;
-      messages.add(getMessage(msgID, String.valueOf(backendDN),
-                              stackTraceToSingleLineString(e)));
-      resultCode = DirectoryServer.getServerErrorResultCode();
-      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
-    }
+    Set<DN> dnList = cfg.getBackendBaseDN();
+    DN[] baseDNs = new DN[dnList.size()];
+    dnList.toArray(baseDNs);
 
 
     // See if the entry contains an attribute that specifies the class name
@@ -2063,46 +1068,13 @@
     // that it's a valid backend implementation.  There is no such attribute,
     // the specified class cannot be loaded, or it does not contain a valid
     // backend implementation, then log an error and skip it.
-    String className;
-    msgID = MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_CLASS;
-    StringConfigAttribute classStub =
-         new StringConfigAttribute(ATTR_BACKEND_CLASS, getMessage(msgID),
-                                   true, false, true);
-    try
-    {
-      StringConfigAttribute classAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(classStub);
-      if (classAttr == null)
-      {
-        msgID = MSGID_CONFIG_BACKEND_NO_CLASS_ATTR;
-        messages.add(getMessage(msgID, String.valueOf(backendDN)));
-        resultCode = ResultCode.UNWILLING_TO_PERFORM;
-        return new ConfigChangeResult(resultCode, adminActionRequired,
-                                      messages);
-      }
-      else
-      {
-        className = classAttr.activeValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_CONFIG_BACKEND_CANNOT_GET_CLASS;
-      messages.add(getMessage(msgID, String.valueOf(backendDN),
-                              stackTraceToSingleLineString(e)));
-      resultCode = DirectoryServer.getServerErrorResultCode();
-      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
-    }
+    String className = cfg.getBackendClass();
+    Class backendClass;
 
     Backend backend;
     try
     {
-      Class backendClass = DirectoryServer.loadClass(className);
+      backendClass = DirectoryServer.loadClass(className);
       backend = (Backend) backendClass.newInstance();
     }
     catch (Exception e)
@@ -2112,7 +1084,7 @@
         debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      msgID = MSGID_CONFIG_BACKEND_CANNOT_INSTANTIATE;
+      int msgID = MSGID_CONFIG_BACKEND_CANNOT_INSTANTIATE;
       messages.add(getMessage(msgID, String.valueOf(className),
                               String.valueOf(backendDN),
                               stackTraceToSingleLineString(e)));
@@ -2135,7 +1107,7 @@
       StringBuilder failureReason = new StringBuilder();
       if (! LockFileManager.acquireSharedLock(lockFile, failureReason))
       {
-        msgID = MSGID_CONFIG_BACKEND_CANNOT_ACQUIRE_SHARED_LOCK;
+        int msgID = MSGID_CONFIG_BACKEND_CANNOT_ACQUIRE_SHARED_LOCK;
         String message = getMessage(msgID, backendID,
                                     String.valueOf(failureReason));
         logError(ErrorLogCategory.CONFIGURATION,
@@ -2156,7 +1128,7 @@
         debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      msgID = MSGID_CONFIG_BACKEND_CANNOT_ACQUIRE_SHARED_LOCK;
+      int msgID = MSGID_CONFIG_BACKEND_CANNOT_ACQUIRE_SHARED_LOCK;
       String message = getMessage(msgID, backendID,
                                   stackTraceToSingleLineString(e));
       logError(ErrorLogCategory.CONFIGURATION,
@@ -2174,7 +1146,8 @@
     // Perform the necessary initialization for the backend entry.
     try
     {
-      backend.initializeBackend(configEntry, baseDNs);
+      backend.initializeBackend(
+           DirectoryServer.getConfigEntry(cfg.dn()), baseDNs);
     }
     catch (Exception e)
     {
@@ -2183,7 +1156,7 @@
         debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      msgID = MSGID_CONFIG_BACKEND_CANNOT_INITIALIZE;
+      int msgID = MSGID_CONFIG_BACKEND_CANNOT_INITIALIZE;
       messages.add(getMessage(msgID, String.valueOf(className),
                               String.valueOf(backendDN),
                               stackTraceToSingleLineString(e)));
@@ -2243,7 +1216,7 @@
         debugCaught(DebugLogLevel.ERROR, e);
       }
 
-      msgID = MSGID_CONFIG_BACKEND_CANNOT_REGISTER_BACKEND;
+      int msgID = MSGID_CONFIG_BACKEND_CANNOT_REGISTER_BACKEND;
       String message = getMessage(msgID, backendID,
                                   stackTraceToSingleLineString(e));
 
@@ -2263,24 +1236,14 @@
   }
 
 
-
   /**
-   * Indicates whether it is acceptable to remove the provided configuration
-   * entry.
-   *
-   * @param  configEntry         The configuration entry that will be removed
-   *                             from the configuration.
-   * @param  unacceptableReason  A buffer to which this method can append a
-   *                             human-readable message explaining why the
-   *                             proposed delete is not acceptable.
-   *
-   * @return  <CODE>true</CODE> if the proposed entry may be removed from the
-   *          configuration, or <CODE>false</CODE> if not.
+   * {@inheritDoc}
    */
-  public boolean configDeleteIsAcceptable(ConfigEntry configEntry,
-                                          StringBuilder unacceptableReason)
+  public boolean isConfigurationDeleteAcceptable(
+       BackendCfg configEntry,
+       List<String> unacceptableReason)
   {
-    DN backendDN = configEntry.getDN();
+    DN backendDN = configEntry.dn();
 
 
     // See if this backend config manager has a backend registered with the
@@ -2304,24 +1267,18 @@
     else
     {
       int msgID = MSGID_CONFIG_BACKEND_CANNOT_REMOVE_BACKEND_WITH_SUBORDINATES;
-      unacceptableReason.append(getMessage(msgID, String.valueOf(backendDN)));
+      unacceptableReason.add(getMessage(msgID, String.valueOf(backendDN)));
       return false;
     }
   }
 
 
-
   /**
-   * Attempts to apply a new configuration based on the provided deleted entry.
-   *
-   * @param  configEntry  The new configuration entry that has been deleted.
-   *
-   * @return  Information about the result of processing the configuration
-   *          change.
+   * {@inheritDoc}
    */
-  public ConfigChangeResult applyConfigurationDelete(ConfigEntry configEntry)
+  public ConfigChangeResult applyConfigurationDelete(BackendCfg configEntry)
   {
-    DN                backendDN           = configEntry.getDN();
+    DN                backendDN           = configEntry.dn();
     ResultCode        resultCode          = ResultCode.SUCCESS;
     boolean           adminActionRequired = false;
     ArrayList<String> messages            = new ArrayList<String>();
@@ -2363,7 +1320,7 @@
       }
 
       DirectoryServer.deregisterBackend(backend);
-      configEntry.deregisterChangeListener(this);
+      configEntry.removeChangeListener(this);
 
       // Remove the shared lock for this backend.
       try
@@ -2406,5 +1363,54 @@
       return new ConfigChangeResult(resultCode, adminActionRequired, messages);
     }
   }
+
+  /**
+   * Gets the configuration corresponding to a config entry.
+   *
+   * @param <S>
+   *          The type of server configuration.
+   * @param definition
+   *          The required definition of the required managed object.
+   * @param configEntry
+   *          A configuration entry.
+   * @return Returns the server-side configuration.
+   * @throws ConfigException
+   *           If the entry could not be decoded.
+   */
+  public static <S extends Configuration> S getConfiguration(
+      AbstractManagedObjectDefinition<?, S> definition, ConfigEntry configEntry)
+      throws ConfigException {
+
+    try {
+      ServerManagedObject<? extends S> mo = ServerManagedObject
+          .decode(ManagedObjectPath.emptyPath(), definition,
+              configEntry);
+      return mo.getConfiguration();
+    } catch (DefinitionDecodingException e) {
+      throw ConfigExceptionFactory.getInstance()
+          .createDecodingExceptionAdaptor(configEntry.getDN(), e);
+    } catch (ServerManagedObjectDecodingException e) {
+      throw ConfigExceptionFactory.getInstance()
+          .createDecodingExceptionAdaptor(e);
+    }
+  }
+
+
+
+  /**
+   * Gets the backend configuration corresponding to a backend config entry.
+   *
+   * @param configEntry A backend config entry.
+   * @return Returns the backend configuration.
+   * @throws ConfigException If the config entry could not be decoded.
+   */
+  public static BackendCfg getBackendCfg(ConfigEntry configEntry)
+      throws ConfigException
+  {
+    return getConfiguration(BackendCfgDefn.getInstance(), configEntry);
+  }
+
+
+
 }
 
diff --git a/opends/src/server/org/opends/server/core/DirectoryServer.java b/opends/src/server/org/opends/server/core/DirectoryServer.java
index f017b69..2472675 100644
--- a/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -4196,8 +4196,11 @@
           baseName = "___NAME___";
         }
 
-        lines.add("  <adm:property name=\"" + baseName + "\" mandatory=\"" +
-                  String.valueOf(attr.isRequired()) + "\">");
+        lines.add("  <adm:property name=\"" + baseName + "\"");
+        lines.add("    mandatory=\""
+             + String.valueOf(attr.isRequired()) + "\"");
+        lines.add("    multi-valued=\""
+             + String.valueOf(attr.isMultiValued()) + "\">");
         lines.add("    <adm:synopsis>");
         lines.add("      ___SYNOPSIS___");
         lines.add("    </adm:synopsis>");
@@ -4238,6 +4241,18 @@
         }
 
         lines.add("    </adm:description>");
+        if (attr.requiresAdminAction())
+        {
+          lines.add("    <adm:requires-admin-action>");
+          lines.add("      <adm:server-restart/>");
+          lines.add("    </adm:requires-admin-action>");
+        }
+        if (!attr.isRequired())
+        {
+          lines.add("    <adm:default-behavior>");
+          lines.add("      <adm:undefined/>");
+          lines.add("    </adm:default-behavior>");
+        }
         lines.add("    <adm:syntax>");
 
         if (attr instanceof org.opends.server.config.BooleanConfigAttribute)
diff --git a/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java b/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
index 431f2e2..ffd4d8f 100644
--- a/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
+++ b/opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
@@ -1379,6 +1379,9 @@
     }
 
 
+    // Save this configuration for future reference.
+    currentConfig = config;
+
     return new ConfigChangeResult(resultCode, adminActionRequired, messages);
   }
 }
diff --git a/opends/src/server/org/opends/server/messages/AdminMessages.java b/opends/src/server/org/opends/server/messages/AdminMessages.java
index 8f01119..608483c 100644
--- a/opends/src/server/org/opends/server/messages/AdminMessages.java
+++ b/opends/src/server/org/opends/server/messages/AdminMessages.java
@@ -223,7 +223,7 @@
             + "retrieve the managed object configuration entry %s: %s.");
 
     registerMessage(MSGID_ADMIN_MANAGED_OBJECT_DOES_NOT_EXIST,
-        "The the managed object configuration entry %s does not "
+        "The managed object configuration entry %s does not "
             + "appear to exist in the Directory Server "
             + "configuration. This is a required entry.");
 
diff --git a/opends/src/server/org/opends/server/messages/CoreMessages.java b/opends/src/server/org/opends/server/messages/CoreMessages.java
index b969e7e..5102b7e 100644
--- a/opends/src/server/org/opends/server/messages/CoreMessages.java
+++ b/opends/src/server/org/opends/server/messages/CoreMessages.java
@@ -1015,7 +1015,7 @@
    * The message ID for the message that will be used if an attempt is made to
    * normalize the value for an attribute type that does not have an equality
    * matching rule.  This takes two arguments, which are the value to normalize
-   * and the the name of the attribute type.
+   * and the name of the attribute type.
    */
   public static final int MSGID_ATTR_TYPE_NORMALIZE_NO_MR =
        CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 125;
@@ -6269,7 +6269,7 @@
                     "The Directory Server has completed the configuration " +
                     "bootstrapping process.");
     registerMessage(MSGID_CANNOT_LOAD_CONFIG_HANDLER_CLASS,
-                    "Unable to load class %s to serve as the the Directory " +
+                    "Unable to load class %s to serve as the Directory " +
                     "Server configuration handler:  %s.");
     registerMessage(MSGID_CANNOT_INSTANTIATE_CONFIG_HANDLER,
                     "Unable to create an instance of class %s to serve as " +
@@ -6727,7 +6727,7 @@
     registerMessage(MSGID_ADD_ASSERTION_FAILED,
                     "Entry %s cannot be added because the request contained " +
                     "an LDAP assertion control and the associated filter did " +
-                    "not match the contents of the the provided entry.");
+                    "not match the contents of the provided entry.");
     registerMessage(MSGID_ADD_CANNOT_PROCESS_ASSERTION_FILTER,
                     "Entry %s cannot be added because the request contained " +
                     "an LDAP assertion control, but an error occurred while " +
diff --git a/opends/src/server/org/opends/server/messages/JebMessages.java b/opends/src/server/org/opends/server/messages/JebMessages.java
index 9eb79c1..3433efa 100644
--- a/opends/src/server/org/opends/server/messages/JebMessages.java
+++ b/opends/src/server/org/opends/server/messages/JebMessages.java
@@ -63,11 +63,6 @@
   public static final int MSGID_JEB_OPEN_ENV_FAIL =
        CATEGORY_MASK_JEB | SEVERITY_MASK_SEVERE_ERROR | 3;
 
-/*
-  public static final int MSGID_JEB_EMPTY_MESSAGE =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 4;
-*/
-
   /**
    * The message ID of an error indicating that the current highest entry ID
    * in the database could not be determined.  This message takes no arguments.
@@ -132,11 +127,6 @@
   public static final int MSGID_JEB_ENTRY_DATABASE_CORRUPT =
        CATEGORY_MASK_JEB | SEVERITY_MASK_SEVERE_ERROR | 12;
 
-/*
-  public static final int MSGID_JEB_SUFFIXES_NOT_SPECIFIED =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_SEVERE_ERROR | 13;
-*/
-
   /**
    * The message ID of an error indicating that an exception was raised by the
    * JE library while accessing the database.  This message takes one string
@@ -145,11 +135,6 @@
   public static final int MSGID_JEB_DATABASE_EXCEPTION =
        CATEGORY_MASK_JEB | SEVERITY_MASK_SEVERE_ERROR | 14;
 
-/*
-  public static final int MSGID_JEB_JMX_CANNOT_REGISTER_MBEAN =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_SEVERE_ERROR | 15;
-*/
-
   /**
    * The message ID used to describe the attribute which configures
    * the attribute type of an attribute index.
@@ -176,55 +161,6 @@
 
   /**
    * The message ID used to describe the attribute which configures
-   * the database cache size as a percentage of Java VM heap size.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_DATABASE_CACHE_PERCENT =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 19;
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the database cache size as an approximate number of bytes.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_DATABASE_CACHE_SIZE =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 20;
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * whether data updated by a database transaction is forced to disk.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_DATABASE_TXN_NO_SYNC =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 21;
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * whether data updated by a database transaction is written
-   * from the Java VM to the O/S.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_DATABASE_TXN_WRITE_NO_SYNC =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 22;
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * whether the database background cleaner thread runs.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_DATABASE_RUN_CLEANER =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 23;
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the backend entry limit for indexing.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_BACKEND_INDEX_ENTRY_LIMIT =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 24;
-
-
-  /**
-   * The message ID used to describe the attribute which configures
    * the substring length for an attribute index.
    */
   public static final int MSGID_CONFIG_DESCRIPTION_INDEX_SUBSTRING_LENGTH =
@@ -241,11 +177,6 @@
   public static final int MSGID_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE =
        CATEGORY_MASK_JEB | SEVERITY_MASK_SEVERE_ERROR | 26;
 
-/*
-  public static final int MSGID_JEB_CANNOT_ACQUIRE_LOCK =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_MILD_ERROR | 27;
-*/
-
   /**
    * The message ID of an error indicating that an unchecked exception was
    * raised during a database transaction.  This message takes no arguments.
@@ -297,21 +228,6 @@
        CATEGORY_MASK_JEB | SEVERITY_MASK_NOTICE | 33;
 
   /**
-   * The message ID used to describe the attribute which configures
-   * the minimum percentage of log space that must be used in log files.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_CLEANER_MIN_UTILIZATION =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 34;
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the subtree delete size limit.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_SUBTREE_DELETE_SIZE_LIMIT =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 35;
-
-
-  /**
    * The message ID of an error indicating that the JE backend configuration
    * contains more than one configuration entry of a given object class where
    * only one entry of that object class is allowed.  This message takes two
@@ -493,57 +409,6 @@
        CATEGORY_MASK_JEB | SEVERITY_MASK_MILD_ERROR | 54;
 
   /**
-   * The message ID used to describe the attribute which configures
-   * the pathname of the directory for import temporary files.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_IMPORT_TEMP_DIRECTORY =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 55;
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the amount of memory available for import buffering.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_IMPORT_BUFFER_SIZE =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 56;
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the import queue size.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_IMPORT_QUEUE_SIZE =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 57;
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the number of import worker threads.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_IMPORT_THREAD_COUNT =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 58;
-
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the database cache eviction algorithm.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_EVICTOR_LRU_ONLY =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 59;
-
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the number of nodes in one scan of the database cache evictor.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_EVICTOR_NODES_PER_SCAN =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 60;
-
-
-
-  /**
    * The message ID used to log the size of the database cache after preloading.
    */
   public static final int MSGID_JEB_CACHE_SIZE_AFTER_PRELOAD =
@@ -552,15 +417,6 @@
 
 
   /**
-   * The message ID used to describe the attribute which configures
-   * the maximum time to spend preloading the database cache.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_PRELOAD_TIME_LIMIT =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 62;
-
-
-
-  /**
    * The message ID for the message that will be used if an error occurs while
    * attempting to obtain the MAC provider for the backend backup.  This takes
    * two arguments, which are the name of the desired MAC algorithm and a string
@@ -746,24 +602,6 @@
 
 
   /**
-   * The message ID used to describe the attribute which configures
-   * whether entries should be compressed in the database.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_ENTRIES_COMPRESSED =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 80;
-
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the maximum size of each individual JE log file, in bytes.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_DATABASE_LOG_FILE_MAX =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 81;
-
-
-
-  /**
    * The message ID used to log an informational message in the backup process.
    * This message takes one argument, the name of a file that was not changed
    * since the previous backup.
@@ -1090,61 +928,6 @@
 
 
   /**
-   * The message ID used to describe the attribute which configures
-   * whether the logging file handler will be on or off.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_LOGGING_FILE_HANDLER_ON =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 113;
-
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the trace log message level.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_LOGGING_LEVEL =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 114;
-
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * how many bytes are written to the log before the checkpointer runs.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_CHECKPOINT_BYTES_INTERVAL =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 115;
-
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the amount of time between runs of the checkpointer.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_CHECKPOINT_WAKEUP_INTERVAL =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 116;
-
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the number of times a database transaction will be retried after it is
-   * aborted due to deadlock with another thread.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_DEADLOCK_RETRY_LIMIT =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 117;
-
-
-
-  /**
-   * The message ID used to describe the attribute which configures
-   * the number of database lock tables.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_NUM_LOCK_TABLES =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 118;
-
-
-
-  /**
    * The message ID used to log an informational message in the import process.
    * This message takes one argument, a string representation of the JE
    * environment configuration properties.
@@ -1154,15 +937,6 @@
 
 
   /**
-   * The message ID used to describe the attribute which configures
-   * the import pass size.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_IMPORT_PASS_SIZE =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 120;
-
-
-
-  /**
    * The message ID used to indicate that an LDIF import pass has completed and
    * it is time to begin the intermediate index merge process.  This takes a
    * single argument, which is the pass number that has completed.
@@ -1204,15 +978,6 @@
 
 
   /**
-   * The message ID used to describe the attribute which configures
-   * the number of threads allocated by the cleaner for log file processing.
-   */
-  public static final int MSGID_CONFIG_DESCRIPTION_NUM_CLEANER_THREADS =
-       CATEGORY_MASK_JEB | SEVERITY_MASK_INFORMATIONAL | 125;
-
-
-
-  /**
    * The message ID of an error indicating the version of DatabaseEntry is
    * incompatible and can not be decoded.
    */
@@ -1308,7 +1073,7 @@
 
   /**
    * The message ID used to indicate that another rebuild process for an index
-   * is alreadly in progress. This message takes the name of the conflicting
+   * is already in progress. This message takes the name of the conflicting
    * index as the argument.
    */
   public static final int MSGID_JEB_REBUILD_INDEX_CONFLICT =
@@ -1339,68 +1104,32 @@
                     "The backend does not contain that part of the Directory " +
                     "Information Tree pertaining to the entry " +
                     "'%s'.");
-
     registerMessage(MSGID_JEB_OPEN_DATABASE_FAIL,
                     "The database could not be opened: %s.");
-
     registerMessage(MSGID_JEB_OPEN_ENV_FAIL,
                     "The database environment could not be opened: %s.");
-
-/*
-    registerMessage(MSGID_JEB_EMPTY_MESSAGE,
-                    "");
-*/
-
     registerMessage(MSGID_JEB_HIGHEST_ID_FAIL,
                     "The database highest entry identifier could not be " +
                     "determined.");
-
     registerMessage(MSGID_JEB_FUNCTION_NOT_SUPPORTED,
                     "The requested operation is not supported by this " +
                     "backend.");
-
     registerMessage(MSGID_JEB_CREATE_FAIL,
                     "The backend database directory could not be created: %s.");
-
     registerMessage(MSGID_JEB_REMOVE_FAIL,
                     "The backend database files could not be removed: %s.");
-
     registerMessage(MSGID_JEB_DIRECTORY_INVALID,
                     "The backend database directory '%s' is not a valid " +
                     "directory.");
-
     registerMessage(MSGID_JEB_MISSING_DN2ID_RECORD,
                     "The DN database does not contain a record for '%s'.");
-
     registerMessage(MSGID_JEB_MISSING_ID2ENTRY_RECORD,
                     "The entry database does not contain a record for ID %s.");
-
     registerMessage(MSGID_JEB_ENTRY_DATABASE_CORRUPT,
                     "The entry database does not contain a valid record " +
                     "for ID %s.");
-
-/*
-    registerMessage(MSGID_JEB_SUFFIXES_NOT_SPECIFIED,
-                    "No suffixes specified for the backend.");
-*/
-
     registerMessage(MSGID_JEB_DATABASE_EXCEPTION,
                     "Database exception: %s");
-
-/*
-    registerMessage(MSGID_JEB_JMX_CANNOT_REGISTER_MBEAN,
-                    "The backend could not register a JMX MBean for " +
-                    "the database in directory '%s':  " +
-                    "%s ");
-*/
-
-    registerMessage(MSGID_CONFIG_DESCRIPTION_BACKEND_INDEX_ENTRY_LIMIT,
-                    "A performance tuning parameter for attribute indexes. " +
-                    "The default entry limit for attribute indexes, where " +
-                    "a value of 0 means there is no limit. " +
-                    "When the number of entries " +
-                    "matching an index value reaches the limit, the " +
-                    "value is no longer maintained in the index.");
     registerMessage(MSGID_CONFIG_DESCRIPTION_INDEX_ATTRIBUTE,
                     "The attribute type name of the attribute index.");
     registerMessage(MSGID_CONFIG_DESCRIPTION_INDEX_TYPE,
@@ -1414,65 +1143,13 @@
                     "When the number of entries " +
                     "matching an index value reaches the limit, the " +
                     "value is no longer maintained in the index.");
-
-    registerMessage(MSGID_CONFIG_DESCRIPTION_DATABASE_CACHE_PERCENT,
-                    "The percentage of JVM memory to allocate to the database" +
-                    " cache.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_DATABASE_CACHE_SIZE,
-                    "The approximate amount of JVM memory to allocate to the " +
-                    "database cache. The default value of zero indicates " +
-                    "that the database cache is sized by the cachePercent " +
-                    "configuration attribute. A non-zero value overrides the " +
-                    "cachePercent configuration attribute.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_DATABASE_TXN_NO_SYNC,
-                    "If true, do not write or synchronously flush the " +
-                    "database log on transaction commit. This means that " +
-                    "transactions exhibit the ACI (Atomicity, Consistency, " +
-                    "and Isolation) properties, but not D (Durability); " +
-                    "that is, database integrity is maintained, but if the " +
-                    "JVM or operating system fails, it is possible some " +
-                    "number of the most recently committed transactions " +
-                    "may be undone during recovery. The number of " +
-                    "transactions at risk is governed by how many " +
-                    "updates fit into a log buffer, how often the " +
-                    "operating system flushes dirty buffers to disk, and " +
-                    "how often the database environment is checkpointed.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_DATABASE_TXN_WRITE_NO_SYNC,
-                    "If true, write but do not synchronously flush the " +
-                    "database log on transaction commit. This means that " +
-                    "transactions exhibit the ACI (Atomicity, Consistency, " +
-                    "and Isolation) properties, but not D (Durability); " +
-                    "that is, database integrity is maintained, but if the " +
-                    "JVM or operating system fails, it is possible some " +
-                    "number of the most recently committed transactions may " +
-                    "be undone during recovery. The number of transactions " +
-                    "at risk is governed by how often the operating system " +
-                    "flushes dirty buffers to disk, and how often the " +
-                    "database environment is checkpointed. " +
-                    "The motivation for this attribute is to provide a " +
-                    "transaction that has more durability than asynchronous " +
-                    "(nosync) transactions, but has higher performance than " +
-                    "synchronous transactions. ");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_DATABASE_RUN_CLEANER,
-                    "If false, do not run the background cleaner thread " +
-                    "responsible for freeing up disk space consumed by " +
-                    "data records no longer in use.");
-
     registerMessage(MSGID_CONFIG_DESCRIPTION_INDEX_SUBSTRING_LENGTH,
                     "The length of substrings in a substring index.");
-
     registerMessage(MSGID_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE,
                     "The attribute '%s' cannot have indexing of type '%s' " +
                     "because it does not have a corresponding matching rule.");
-
-/*
-    registerMessage(MSGID_JEB_CANNOT_ACQUIRE_LOCK,
-                    "Unable to acquire a lock on the entry '%s'.");
-*/
-
     registerMessage(MSGID_JEB_UNCHECKED_EXCEPTION,
                     "Unchecked exception during database transaction.");
-
     registerMessage(MSGID_JEB_CLEAN_DATABASE_START,
                     "Starting database cleaning on %d log file(s) in '%s'.");
     registerMessage(MSGID_JEB_CLEAN_DATABASE_MARKED,
@@ -1480,22 +1157,6 @@
     registerMessage(MSGID_JEB_CLEAN_DATABASE_FINISH,
                     "Finished database cleaning; " +
                     "now %d log file(s) remaining.");
-
-    registerMessage(MSGID_CONFIG_DESCRIPTION_CLEANER_MIN_UTILIZATION,
-                    "A minimum log utilization property to determine how " +
-                    "much database cleaning to perform.  Changes to this " +
-                    "property do not take effect until the backend is " +
-                    "restarted.  The log files " +
-                    "contain both obsolete and utilized records. Obsolete " +
-                    "records are records that are no longer in use, either " +
-                    "because they have been modified or because they have " +
-                    "been deleted.  Utilized records are those records that " +
-                    "are currently in use. This property identifies the " +
-                    "minimum percentage of log space that must be used by " +
-                    "utilized records.  If this minimum percentage is not " +
-                    "met, then log files are cleaned until the minimum " +
-                    "percentage is met.");
-
     registerMessage(MSGID_JEB_SUBTREE_DELETE_SIZE_LIMIT_EXCEEDED,
                     "Exceeded the administrative limit on the number of " +
                     "entries that may be deleted in a subtree delete " +
@@ -1504,14 +1165,6 @@
                     "in the subtree have been deleted.");
     registerMessage(MSGID_JEB_DELETED_ENTRY_COUNT,
                     "The number of entries deleted was %d.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_SUBTREE_DELETE_SIZE_LIMIT,
-                    "The maximum number of entries that can be deleted " +
-                    "by a delete entry operation with the subtree delete " +
-                    "control specified. To delete subtrees containing more " +
-                    "entries than this value, the operation must be repeated " +
-                    "as many times as necessary to complete the subtree " +
-                    "delete.");
-
     registerMessage(MSGID_JEB_DUPLICATE_CONFIG_ENTRY,
                     "The configuration entry '%s' will be ignored. " +
                     "Only one configuration entry with object class '%s' is " +
@@ -1527,27 +1180,17 @@
                     "because it specifies the attribute type '%s', " +
                     "which has already been defined in another " +
                     "index configuration entry.");
-
     registerMessage(MSGID_JEB_IO_ERROR,
                     "I/O error during backend operation: %s");
-
-/*
-    registerMessage(MSGID_JEB_INDEX_THREAD_EXCEPTION,
-                    "An index worker thread raised an exception: %s");
-*/
-
     registerMessage(MSGID_JEB_BACKEND_STARTED,
                     "A database backend containing %d entries has started.");
-
     registerMessage(MSGID_JEB_IMPORT_PARENT_NOT_FOUND,
                     "The parent entry '%s' does not exist.");
     registerMessage(MSGID_JEB_IMPORT_ENTRY_EXISTS,
                     "The entry exists and the import options do not " +
                     "allow it to be replaced.");
-
     registerMessage(MSGID_JEB_ATTRIBUTE_INDEX_NOT_CONFIGURED,
                     "There is no index configured for attribute type '%s'.");
-
     registerMessage(MSGID_JEB_SEARCH_NO_SUCH_OBJECT,
                     "The search base entry '%s' does not exist.");
     registerMessage(MSGID_JEB_ADD_NO_SUCH_OBJECT,
@@ -1574,64 +1217,8 @@
     registerMessage(MSGID_JEB_NEW_SUPERIOR_NO_SUCH_OBJECT,
                     "The entry cannot be moved because the new parent " +
                     "entry '%s' does not exist.");
-
-    registerMessage(MSGID_CONFIG_DESCRIPTION_IMPORT_TEMP_DIRECTORY,
-                    "The pathname of a directory to hold temporary working " +
-                    "files generated during an import process.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_IMPORT_BUFFER_SIZE,
-                    "The amount of memory that is available to an import " +
-                    "process for its buffers.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_IMPORT_QUEUE_SIZE,
-                    "The maximum number of entries that can be on the import " +
-                    "queue waiting to be processed.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_IMPORT_THREAD_COUNT,
-                    "The number of worker threads that will be created to " +
-                    "import entries from LDIF.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_IMPORT_PASS_SIZE,
-                    "The maximum number of entries that can be processed in " +
-                    "a single pass before index merging occurs.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_EVICTOR_LRU_ONLY,
-                    "Changes to this property do not take effect until the " +
-                    "backend is restarted.  " +
-                    "The default database cache eviction algorithm is LRU " +
-                    "(least recently used) and the default setting for the " +
-                    "lruOnly parameter is true. With the default algorithm, " +
-                    "only the LRU of a Btree node is taken into account " +
-                    "when choosing the next Btree node to be evicted.  " +
-                    "When lruOnly is set to false, the eviction algorithm is " +
-                    "instead primarily based on the level of the node in " +
-                    "the Btree. The lowest level nodes (the leaf nodes) are " +
-                    "always evicted first, even if higher level nodes are " +
-                    "less recently used. In addition, dirty nodes are " +
-                    "evicted after non-dirty nodes.  " +
-                    "Setting lruOnly to false benefits random access " +
-                    "applications because it keeps higher level Btree " +
-                    "nodes in the tree for as long as possible. For a " +
-                    "random key, this increases the likelihood that the " +
-                    "relevant Btree internal nodes will be in the cache.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_EVICTOR_NODES_PER_SCAN,
-                    "Changes to this property do not take effect until the " +
-                    "backend is restarted.  " +
-                    "It is recommended that you also change nodesPerScan " +
-                    "when you set lruOnly to false. This setting controls " +
-                    "the number of Btree nodes that are considered, or " +
-                    "sampled, each time a node is evicted. A setting of 100 " +
-                    "often produces good results, but this may vary from " +
-                    "application to application. The larger the " +
-                    "nodesPerScan, the more accurate the algorithm. However, " +
-                    "setting it too high is detrimental; the need to " +
-                    "consider larger numbers of nodes for each eviction may " +
-                    "delay the completion of a given database operation, " +
-                    "which will impact the response time of the application " +
-                    "thread.");
     registerMessage(MSGID_JEB_CACHE_SIZE_AFTER_PRELOAD,
                     "The database cache is %d MB after pre-loading.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_PRELOAD_TIME_LIMIT,
-                    "The maximum time to spend pre-loading the database " +
-                    "cache when the backend starts. The time units may be ms " +
-                    "(milliseconds), s (seconds) or m (minutes). A value of " +
-                    "zero means there will be no pre-load.");
-
     registerMessage(MSGID_JEB_BACKUP_CANNOT_GET_MAC,
                     "An error occurred while attempting to obtain the %s MAC " +
                     "provider to create the signed hash for the backup:  %s.");
@@ -1684,15 +1271,6 @@
     registerMessage(MSGID_JEB_BACKUP_MISSING_BACKUPID,
                     "The information for backup %s could not be found in " +
                     "the backup directory %s.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_ENTRIES_COMPRESSED,
-                    "Set to true to indicate that the backend should " +
-                    "attempt to compress entries when writing " +
-                    "to the database.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_DATABASE_LOG_FILE_MAX,
-                    "The maximum size of each individual database log file, " +
-                    "in bytes.  Changes to this property do not take effect " +
-                    "until the backend is restarted.");
-
     registerMessage(MSGID_JEB_BACKUP_FILE_UNCHANGED,
                     "Not changed: %s");
     registerMessage(MSGID_JEB_BACKUP_CLEANER_ACTIVITY,
@@ -1780,40 +1358,8 @@
     registerMessage(MSGID_JEB_REFERRAL_RESULT_MESSAGE,
                     "A referral entry %s indicates that the operation must " +
                     "be processed at a different server.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_LOGGING_FILE_HANDLER_ON,
-                    "Determines whether database trace logging is written to " +
-                    "a je.info file in the backend database directory.  " +
-                    "Changes to this property do not take effect until the " +
-                    "backend is restarted.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_LOGGING_LEVEL,
-                    "The database trace logging level chosen from: SEVERE, " +
-                    "WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL or " +
-                    "OFF.  Changes to this property do not take effect until " +
-                    "the backend is restarted.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_CHECKPOINT_BYTES_INTERVAL,
-                    "The checkpointer runs every time this number of bytes" +
-                    "have been written to the database log.  If this property" +
-                    "is set to a non-zero value, the checkpointer wakeup " +
-                    "interval is not used.  To use time based checkpointing, " +
-                    "set this property to zero.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_CHECKPOINT_WAKEUP_INTERVAL,
-                    "The checkpointer wakeup interval.  If the checkpointer " +
-                    "bytes interval is zero, the checkpointer runs at time " +
-                    "intervals determined by this property.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_DEADLOCK_RETRY_LIMIT,
-                    "The number of times a database transaction will be " +
-                    "retried after it has been aborted due to deadlock with " +
-                    "another thread.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_NUM_LOCK_TABLES,
-                    "The number of database lock tables.  It should be set " +
-                    "to a prime number, and in general not higher than the " +
-                    "number of server worker threads.");
     registerMessage(MSGID_JEB_IMPORT_ENVIRONMENT_CONFIG,
                     "Database environment properties: %s.");
-    registerMessage(MSGID_CONFIG_DESCRIPTION_NUM_CLEANER_THREADS,
-                    "The number of threads allocated by the cleaner for log " +
-                    "file processing. If the cleaner backlog becomes large, " +
-                    "increase this number.");
     registerMessage(MSGID_JEB_INCOMPATIBLE_ENTRY_VERSION,
                     "Entry record with ID %s is not compatible with this " +
                     "version of the backend database. " +
@@ -1844,7 +1390,7 @@
                     "An error occured while inserting entry into the %s " +
                     "database/index: %s");
     registerMessage(MSGID_JEB_REBUILD_INDEX_CONFLICT,
-                    "Another rebuild of index %s is alreadly in progress.");
+                    "Another rebuild of index %s is already in progress.");
     registerMessage(MSGID_JEB_REBUILD_BACKEND_ONLINE,
                     "Rebuilding system index(es) must be done with the " +
                     "backend containing the base DN disabled.");
diff --git a/opends/src/server/org/opends/server/messages/UtilityMessages.java b/opends/src/server/org/opends/server/messages/UtilityMessages.java
index 947c996..54bd436 100644
--- a/opends/src/server/org/opends/server/messages/UtilityMessages.java
+++ b/opends/src/server/org/opends/server/messages/UtilityMessages.java
@@ -1918,7 +1918,7 @@
     registerMessage(MSGID_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_NAME,
                     "There is already another global argument named \"%s\".");
     registerMessage(MSGID_SUBCMDPARSER_GLOBAL_ARG_NAME_SUBCMD_CONFLICT,
-                    "The argument name %s conflicts the the name of another " +
+                    "The argument name %s conflicts with the name of another " +
                     "argument associated with the %s subcommand.");
     registerMessage(MSGID_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_SHORT_ID,
                     "Short ID -%s for global argument %s conflicts with the " +
diff --git a/opends/tests/unit-tests-testng/resource/config-changes.ldif b/opends/tests/unit-tests-testng/resource/config-changes.ldif
index 1aa7cf1..dbd4763 100644
--- a/opends/tests/unit-tests-testng/resource/config-changes.ldif
+++ b/opends/tests/unit-tests-testng/resource/config-changes.ldif
@@ -378,28 +378,6 @@
 ds-cfg-index-type: ordering
 ds-cfg-index-type: approximate
 
-dn: cn=JE Database,ds-cfg-backend-id=rebuildRoot,cn=Backends,cn=config
-changetype: add
-objectClass: top
-objectClass: ds-cfg-je-database
-cn: JE Database
-ds-cfg-database-cache-percent: 10
-ds-cfg-database-cache-size: 0 megabytes
-ds-cfg-database-txn-no-sync: false
-ds-cfg-database-txn-write-no-sync: true
-ds-cfg-database-run-cleaner: true
-ds-cfg-database-cleaner-num-threads: 1
-ds-cfg-database-cleaner-min-utilization: 75
-ds-cfg-database-evictor-lru-only: true
-ds-cfg-database-evictor-nodes-per-scan: 10
-ds-cfg-database-log-file-max: 50 megabytes
-ds-cfg-database-logging-file-handler-on: true
-ds-cfg-database-logging-level: CONFIG
-ds-cfg-database-checkpointer-bytes-interval: 20 megabytes
-ds-cfg-database-checkpointer-wakeup-interval: 30 seconds
-ds-cfg-database-lock-num-lock-tables: 19
-
-
 dn: ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
 changetype: add
 objectClass: top
@@ -482,7 +460,6 @@
 ds-cfg-index-type: equality
 ds-cfg-index-type: substring
 
-
 dn: ds-cfg-index-attribute=uid,cn=Index,ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
 changetype: add
 objectClass: top
@@ -504,26 +481,131 @@
 ds-cfg-index-attribute: entryuuid
 ds-cfg-index-type: equality
 
-dn: cn=JE Database,ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config
+dn: ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
 changetype: add
 objectClass: top
-objectClass: ds-cfg-je-database
-cn: JE Database
-ds-cfg-database-cache-percent: 10
-ds-cfg-database-cache-size: 0 megabytes
-ds-cfg-database-txn-no-sync: false
-ds-cfg-database-txn-write-no-sync: true
-ds-cfg-database-run-cleaner: true
-ds-cfg-database-cleaner-num-threads: 1
-ds-cfg-database-cleaner-min-utilization: 75
-ds-cfg-database-evictor-lru-only: true
-ds-cfg-database-evictor-nodes-per-scan: 10
-ds-cfg-database-log-file-max: 50 megabytes
-ds-cfg-database-logging-file-handler-on: true
-ds-cfg-database-logging-level: CONFIG
-ds-cfg-database-checkpointer-bytes-interval: 20 megabytes
-ds-cfg-database-checkpointer-wakeup-interval: 30 seconds
-ds-cfg-database-lock-num-lock-tables: 19
+objectClass: ds-cfg-backend
+objectClass: ds-cfg-je-backend
+ds-cfg-backend-enabled: true
+ds-cfg-backend-class: org.opends.server.backends.jeb.BackendImpl
+ds-cfg-backend-id: indexTestRoot
+ds-cfg-backend-writability-mode: enabled
+ds-cfg-backend-base-dn: dc=test,dc=com
+ds-cfg-backend-base-dn: dc=test1,dc=com
+ds-cfg-backend-directory: db_index_test
+ds-cfg-backend-mode: 700
+ds-cfg-backend-index-entry-limit: 13
+ds-cfg-backend-subtree-delete-size-limit: 100000
+ds-cfg-backend-preload-time-limit: 0 seconds
+ds-cfg-backend-import-temp-directory: importTmp
+ds-cfg-backend-import-buffer-size: 256 megabytes
+ds-cfg-backend-import-queue-size: 100
+ds-cfg-backend-import-pass-size: 0
+ds-cfg-backend-import-thread-count: 8
+ds-cfg-backend-entries-compressed: false
+ds-cfg-backend-deadlock-retry-limit: 10
+
+dn: cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-branch
+cn: Index
+
+dn: ds-cfg-index-attribute=cn,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-je-index
+ds-cfg-index-attribute: cn
+ds-cfg-index-type: presence
+ds-cfg-index-type: equality
+ds-cfg-index-type: substring
+ds-cfg-index-type: ordering
+ds-cfg-index-type: approximate
+
+dn: ds-cfg-index-attribute=employeeNumber,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-je-index
+ds-cfg-index-attribute: employeeNumber
+ds-cfg-index-type: presence
+ds-cfg-index-type: equality
+ds-cfg-index-type: substring
+ds-cfg-index-type: ordering
+
+dn: ds-cfg-index-attribute=title,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-je-index
+ds-cfg-index-attribute: title
+ds-cfg-index-type: presence
+ds-cfg-index-type: equality
+ds-cfg-index-type: substring
+ds-cfg-index-type: ordering
+
+dn: ds-cfg-index-attribute=givenName,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-je-index
+ds-cfg-index-attribute: givenName
+ds-cfg-index-type: presence
+ds-cfg-index-type: equality
+ds-cfg-index-type: substring
+
+dn: ds-cfg-index-attribute=mail,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-je-index
+ds-cfg-index-attribute: mail
+ds-cfg-index-type: presence
+ds-cfg-index-type: equality
+ds-cfg-index-type: substring
+ds-cfg-index-type: ordering
+
+dn: ds-cfg-index-attribute=member,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-je-index
+ds-cfg-index-attribute: member
+ds-cfg-index-type: equality
+
+dn: ds-cfg-index-attribute=sn,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-je-index
+ds-cfg-index-attribute: sn
+ds-cfg-index-type: presence
+ds-cfg-index-type: equality
+ds-cfg-index-type: substring
+
+dn: ds-cfg-index-attribute=telephoneNumber,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-je-index
+ds-cfg-index-attribute: telephoneNumber
+ds-cfg-index-type: presence
+ds-cfg-index-type: equality
+ds-cfg-index-type: substring
+
+dn: ds-cfg-index-attribute=uid,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-je-index
+ds-cfg-index-attribute: uid
+ds-cfg-index-type: equality
+
+dn: ds-cfg-index-attribute=ds-sync-hist,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-je-index
+ds-cfg-index-attribute: ds-sync-hist
+ds-cfg-index-type: ordering
+
+dn: ds-cfg-index-attribute=entryuuid,cn=Index,ds-cfg-backend-id=indexRoot,cn=Backends,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-je-index
+ds-cfg-index-attribute: entryuuid
+ds-cfg-index-type: equality
 
 dn: cn=Virtual Static member,cn=Virtual Attributes,cn=config
 changetype: modify
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
index ca0f3d9..eecfbf9 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/TestCaseUtils.java
@@ -190,7 +190,8 @@
     //db_rebuild is the third jeb backend used by the jeb rebuild test cases
     String[] subDirectories = { "bak", "bin", "changelogDb", "classes",
                                 "config", "db", "db_verify", "ldif", "lib",
-                                "locks", "logs", "db_rebuild" };
+                                "locks", "logs", "db_rebuild",
+                                "db_index_test" };
     for (String s : subDirectories)
     {
       new File(testRoot, s).mkdir();
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java
index 35f7e23..f621287 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java
@@ -5377,7 +5377,7 @@
          throws Exception
   {
     DN configEntryDN =
-            DN.decode("ds-cfg-backend-id=schema,cn=Backends,cn=config");
+            DN.decode("cn=schema,cn=Backends,cn=config");
     DN[] baseDNs = { DN.decode("cn=schema") };
 
     ConfigEntry configEntry =
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
index 3389651..67c3943 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
@@ -26,31 +26,26 @@
  */
 package org.opends.server.backends.jeb;
 
-import java.io.File;
 import java.util.*;
 
 import org.opends.server.TestCaseUtils;
-import static
-    org.opends.server.messages.ConfigMessages.MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS;
-import static org.opends.server.messages.MessageHandler.getMessage;
+import org.opends.server.admin.std.server.JEBackendCfg;
+import org.opends.server.admin.std.meta.JEBackendCfgDefn;
+import org.opends.server.admin.server.AdminTestCaseUtils;
 import org.opends.server.core.DeleteOperation;
 import org.opends.server.core.ModifyOperation;
 import org.opends.server.core.ModifyDNOperation;
+import org.opends.server.core.DirectoryServer;
 import org.opends.server.protocols.internal.InternalClientConnection;
 import org.opends.server.protocols.internal.InternalSearchOperation;
 import org.opends.server.protocols.ldap.LDAPFilter;
-import org.opends.server.protocols.ldap.LDAPControl;
 import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.config.ConfigEntry;
-import org.opends.server.config.DNConfigAttribute;
-import static org.opends.server.config.ConfigConstants.ATTR_BACKEND_BASE_DN;
 import org.opends.server.types.*;
 import org.opends.server.util.Base64;
 import static
     org.opends.server.util.ServerConstants.OID_SUBTREE_DELETE_CONTROL;
 import org.testng.annotations.Test;
 import org.testng.annotations.BeforeClass;
-import org.testng.annotations.AfterTest;
 import org.testng.annotations.AfterClass;
 
 import static org.testng.Assert.*;
@@ -61,10 +56,8 @@
  * BackendImpl Tester.
  */
 public class TestBackendImpl extends JebTestCase {
-  private File tempDir;
   private String homeDirName;
 
-  private DN[] baseDNs;
   private BackendImpl backend;
 
   private List<Entry> topEntries;
@@ -84,81 +77,9 @@
     // sure the server is started.
     TestCaseUtils.startServer();
 
-    tempDir = TestCaseUtils.createTemporaryDirectory("jebimporttest");
-    homeDirName = tempDir.getAbsolutePath();
+    homeDirName = "db_index_test";
 
-    EnvManager.createHomeDir(homeDirName);
-
-    Entry configEntry = TestCaseUtils.makeEntry(
-        "dn: ds-cfg-backend-id=userRoot,cn=Backends,cn=config",
-        "objectClass: top",
-        "objectClass: ds-cfg-backend",
-        "objectClass: ds-cfg-je-backend",
-        "ds-cfg-backend-index-entry-limit: 13",
-        "ds-cfg-backend-enabled: true",
-        "ds-cfg-backend-class: org.opends.server.backends.jeb.BackendImpl",
-        "ds-cfg-backend-id: userRoot",
-        "ds-cfg-backend-directory:: " +
-            Base64.encode(homeDirName.getBytes()));
-
-    ConfigEntry backendConfigEntry = new ConfigEntry(configEntry, null);
-
-    Entry indexEntry = TestCaseUtils.makeEntry(
-        "dn: cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config\n" +
-            "objectClass: top\n" +
-            "objectClass: ds-cfg-branch\n" +
-            "cn: Index\n");
-
-    ConfigEntry indexConfigEntry = new ConfigEntry(indexEntry,
-        backendConfigEntry);
-    backendConfigEntry.addChild(indexConfigEntry);
-
-    List<Entry> indexEntries = TestCaseUtils.makeEntries(
-        "dn: ds-cfg-index-attribute=cn,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config\n" +
-            "objectClass: top\n" +
-            "objectClass: ds-cfg-je-index\n" +
-            "ds-cfg-index-attribute: cn\n" +
-            "ds-cfg-index-type: presence\n" +
-            "ds-cfg-index-type: equality\n" +
-            "ds-cfg-index-type: substring\n" +
-            "ds-cfg-index-type: ordering\n" +
-            "ds-cfg-index-type: approximate\n" +
-            "\n" +
-            "dn: ds-cfg-index-attribute=employeeNumber,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config\n" +
-            "objectClass: top\n" +
-            "objectClass: ds-cfg-je-index\n" +
-            "ds-cfg-index-attribute: employeeNumber\n" +
-            "ds-cfg-index-type: presence\n" +
-            "ds-cfg-index-type: equality\n" +
-            "ds-cfg-index-type: substring\n" +
-            "ds-cfg-index-type: ordering\n" +
-            "\n" +
-            "dn: ds-cfg-index-attribute=title,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config\n" +
-            "objectClass: top\n" +
-            "objectClass: ds-cfg-je-index\n" +
-            "ds-cfg-index-attribute: title\n" +
-            "ds-cfg-index-type: presence\n" +
-            "ds-cfg-index-type: equality\n" +
-            "ds-cfg-index-type: substring\n" +
-            "ds-cfg-index-type: ordering\n");
-
-    ConfigEntry attribIndexConfigEntry;
-
-    for (Entry attribIndexEntry : indexEntries) {
-      attribIndexConfigEntry = new ConfigEntry(attribIndexEntry,
-          indexConfigEntry);
-      indexConfigEntry.addChild(attribIndexConfigEntry);
-    }
-
-
-    baseDNs = new DN[]
-        {
-            DN.decode("dc=test,dc=com"),
-            DN.decode("dc=test1,dc=com")
-        };
-
-    backend = new BackendImpl();
-    backend.initializeBackend(backendConfigEntry, baseDNs);
+    backend = (BackendImpl)DirectoryServer.getBackend("indexTestRoot");
 
     topEntries = TestCaseUtils.makeEntries(
         "dn: dc=test,dc=com",
@@ -594,8 +515,6 @@
 
   @AfterClass
   public void cleanUp() throws Exception {
-    backend.finalizeBackend();
-    TestCaseUtils.deleteDirectory(tempDir);
   }
 
   @Test(expectedExceptions = DirectoryException.class)
@@ -620,7 +539,6 @@
 
   @Test(dependsOnMethods = "testAdd")
   public void testSearchScope() throws Exception {
-    ArrayList<Control> noControls = new ArrayList<Control>(0);
     InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
 
@@ -667,7 +585,6 @@
 
   @Test(dependsOnMethods = "testAdd")
   public void testSearchIndex() throws Exception {
-    ArrayList<Control> noControls = new ArrayList<Control>(0);
     InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
     LinkedHashSet<String> attribs = new LinkedHashSet<String>();
@@ -923,7 +840,6 @@
     AttributeIndex index;
     HashSet<ASN1OctetString> addKeys;
     DatabaseEntry key;
-    PresenceIndexer presenceIndexer;
     EqualityIndexer equalityIndexer;
     SubstringIndexer substringIndexer;
     OrderingIndexer orderingIndexer;
@@ -1235,21 +1151,24 @@
       "testModifyDNNewSuperior"})
   public void testApplyConfig() throws Exception {
     Entry configEntry = TestCaseUtils.makeEntry(
-        "dn: ds-cfg-backend-id=userRoot,cn=Backends,cn=config",
+        "dn: ds-cfg-backend-id=indexRoot,cn=Backends,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-backend",
         "objectClass: ds-cfg-je-backend",
         "ds-cfg-backend-base-dn: dc=test,dc=com",
         "ds-cfg-backend-base-dn: dc=newsuffix,dc=com",
         "ds-cfg-backend-enabled: true",
+        "ds-cfg-backend-writability-mode: enabled",
         "ds-cfg-backend-class: org.opends.server.backends.jeb.BackendImpl",
-        "ds-cfg-backend-id: userRoot",
+        "ds-cfg-backend-id: indexTestRoot",
         "ds-cfg-backend-directory:: " +
-            Base64.encode(homeDirName.getBytes()));
+            Base64.encode(homeDirName.getBytes()),
+        "ds-cfg-backend-import-temp-directory: importTmp");
 
-    ConfigEntry backendConfigEntry = new ConfigEntry(configEntry, null);
+    JEBackendCfg cfg = AdminTestCaseUtils.getConfiguration(
+         JEBackendCfgDefn.getInstance(), configEntry);
 
-    backend.applyNewConfiguration(backendConfigEntry, true);
+    backend.applyConfigurationChange(cfg);
 
     RootContainer rootContainer = backend.getRootContainer();
 
@@ -1267,16 +1186,12 @@
       assertNotNull(backend.getEntry(entry.getDN()));
     }
 
-    ArrayList<Control> noControls = new ArrayList<Control>(0);
     InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
     LinkedHashSet<String> attribs = new LinkedHashSet<String>();
     attribs.add(ATTR_DEBUG_SEARCH_INDEX);
 
     String debugString;
-    int finalStartPos;
-    int finalEndPos;
-    int finalCount;
 
     InternalSearchOperation search =
         conn.processSearch(DN.decode("dc=test,dc=com"),
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestEntryContainer.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestEntryContainer.java
index d3b8f52..bba1d8f 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestEntryContainer.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestEntryContainer.java
@@ -28,26 +28,21 @@
 
 import static org.testng.AssertJUnit.assertTrue;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.OutputStreamWriter;
-import java.util.ArrayList;
+import java.util.List;
 
 import org.opends.server.TestCaseUtils;
-import org.opends.server.core.DirectoryServer;
+import org.opends.server.admin.std.server.JEBackendCfg;
+import org.opends.server.admin.std.meta.JEBackendCfgDefn;
+import org.opends.server.admin.server.AdminTestCaseUtils;
 import org.opends.server.types.Entry;
-import org.opends.server.types.LDIFImportConfig;
 import org.opends.server.types.FilePermission;
 import org.opends.server.types.DN;
-import org.opends.server.util.LDIFReader;
+import org.opends.server.util.Base64;
 import org.testng.annotations.Test;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.AfterClass;
 
-import com.sleepycat.je.Environment;
-import com.sleepycat.je.EnvironmentConfig;
-
 /**
  * EntryContainer tester.
  */
@@ -121,7 +116,7 @@
   private File tempDir;
   private String homeDirName;
 
-  private ArrayList<Entry> entryList;
+  private List<Entry> entryList;
 
   private long calculatedHighestID = 0;
 
@@ -140,28 +135,11 @@
     tempDir = TestCaseUtils.createTemporaryDirectory("jebtest");
     homeDirName = tempDir.getAbsolutePath();
 
-    // Convert the test LDIF string to a byte array
-    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
-        byteArrayOutputStream);
-    outputStreamWriter.write(ldifString);
-    outputStreamWriter.flush();
-    byte[] originalLDIFBytes = byteArrayOutputStream.toByteArray();
-
-    LDIFReader reader = new LDIFReader(new LDIFImportConfig(
-        new ByteArrayInputStream(originalLDIFBytes)));
-
     // Create a set of entries
-    entryList = new ArrayList<Entry>();
-    long entryID = 0;
-    Entry entry;
-    while ((entry = reader.readEntry(false)) != null) {
-      entryID++;
-      entryList.add(entry);
-    }
+    entryList = TestCaseUtils.entriesFromLdifString(ldifString);
 
     // Remember the highest entryID
-    calculatedHighestID = entryID;
+    calculatedHighestID = entryList.size();
   }
 
   /**
@@ -184,13 +162,32 @@
   @Test()
   public void test1() throws Exception {
     EnvManager.createHomeDir(homeDirName);
-    RootContainer rootContainer = new RootContainer(new Config(), null);
+    Entry configEntry = TestCaseUtils.makeEntry(
+         "dn: ds-cfg-backend-id=userRoot,cn=Backends,cn=config",
+              "objectClass: top",
+              "objectClass: ds-cfg-backend",
+              "objectClass: ds-cfg-je-backend",
+              "ds-cfg-backend-enabled: true",
+              "ds-cfg-backend-class: " +
+                   "org.opends.server.backends.jeb.BackendImpl",
+              "ds-cfg-backend-id: userRoot",
+              "ds-cfg-backend-writability-mode: enabled",
+              "ds-cfg-backend-base-dn: dc=com",
+              "ds-cfg-backend-directory:: " +
+                   Base64.encode(homeDirName.getBytes()),
+              "ds-cfg-backend-import-temp-directory: importTmp");
+    JEBackendCfg cfg = AdminTestCaseUtils.getConfiguration(
+         JEBackendCfgDefn.getInstance(), configEntry);
+    Config backendConfig = new Config();
+    backendConfig.initializeConfig(cfg,
+                                   cfg.getBackendBaseDN().toArray(new DN[0]));
+    RootContainer rootContainer = new RootContainer(backendConfig, null);
     rootContainer.open(new File(homeDirName),
                        new FilePermission(true, true, true),
                        false, true, true, false, true, true);
 
     EntryContainer entryContainer =
-        rootContainer.openEntryContainer(DirectoryServer.getSchemaDN());
+        rootContainer.openEntryContainer(DN.decode("dc=com"));
 
     EntryID actualHighestID = entryContainer.getHighestEntryID();
     assertTrue(actualHighestID.equals(new EntryID(0)));
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java
index b6af139..acda6d8 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java
@@ -238,6 +238,9 @@
       "objectClass: top",
       "objectClass: ds-cfg-backend",
       "objectClass: ds-cfg-je-backend",
+      "ds-cfg-backend-base-dn: dc=example,dc=com",
+      "ds-cfg-backend-base-dn: dc=example1,dc=com",
+      "ds-cfg-backend-writability-mode: enabled",
       "ds-cfg-backend-enabled: true",
       "ds-cfg-backend-class: org.opends.server.backends.jeb.BackendImpl",
       "ds-cfg-backend-id: userRoot",

--
Gitblit v1.10.0