From 0e8d607d49d683199d938e0dba22c79342937991 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Fri, 07 Mar 2014 09:28:45 +0000
Subject: [PATCH] OPENDJ-1343: Migrate dsconfig

---
 opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/DNBuilder.java             |   41 +-
 /dev/null                                                                                      |  114 -------
 opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/LDAPClientTest.java        |  497 ++++++++++++++++++---------------
 opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPDriver.java            |   84 +++--
 opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/AggregationClientTest.java |  115 ++++--
 opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPManagedObject.java     |   15 
 opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPManagementContext.java |    5 
 7 files changed, 427 insertions(+), 444 deletions(-)

diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPNameBuilder.java b/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/DNBuilder.java
similarity index 85%
rename from opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPNameBuilder.java
rename to opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/DNBuilder.java
index 6699487..c679936 100644
--- a/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPNameBuilder.java
+++ b/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/DNBuilder.java
@@ -20,8 +20,8 @@
  *
  * CDDL HEADER END
  *
- *
  *      Copyright 2008-2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 
 package org.forgerock.opendj.config.client.ldap;
@@ -48,7 +48,7 @@
 /**
  * A strategy for creating <code>DN</code>s from managed object paths.
  */
-final class LDAPNameBuilder implements ManagedObjectPathSerializer {
+final class DNBuilder implements ManagedObjectPathSerializer {
 
     /**
      * Creates a new DN representing the specified managed object path.
@@ -59,10 +59,10 @@
      *            The LDAP profile which should be used to construct LDAP names.
      * @return Returns a new DN representing the specified managed object path.
      */
-    public static DN create(ManagedObjectPath<?, ?> path, LDAPProfile profile) {
-        LDAPNameBuilder builder = new LDAPNameBuilder(profile);
+    static DN create(ManagedObjectPath<?, ?> path, LDAPProfile profile) {
+        DNBuilder builder = new DNBuilder(profile);
         path.serialize(builder);
-        return builder.getInstance();
+        return builder.build();
     }
 
     /**
@@ -78,12 +78,12 @@
      * @return Returns a new DN representing the specified managed object path
      *         and instantiable relation.
      */
-    public static DN create(ManagedObjectPath<?, ?> path, InstantiableRelationDefinition<?, ?> relation,
-            LDAPProfile profile) {
-        LDAPNameBuilder builder = new LDAPNameBuilder(profile);
+    static DN create(ManagedObjectPath<?, ?> path,
+            InstantiableRelationDefinition<?, ?> relation, LDAPProfile profile) {
+        DNBuilder builder = new DNBuilder(profile);
         path.serialize(builder);
         builder.appendManagedObjectPathElement(relation);
-        return builder.getInstance();
+        return builder.build();
     }
 
     /**
@@ -99,11 +99,12 @@
      * @return Returns a new DN representing the specified managed object path
      *         and set relation.
      */
-    public static DN create(ManagedObjectPath<?, ?> path, SetRelationDefinition<?, ?> relation, LDAPProfile profile) {
-        LDAPNameBuilder builder = new LDAPNameBuilder(profile);
+    static DN create(ManagedObjectPath<?, ?> path, SetRelationDefinition<?, ?> relation,
+            LDAPProfile profile) {
+        DNBuilder builder = new DNBuilder(profile);
         path.serialize(builder);
         builder.appendManagedObjectPathElement(relation);
-        return builder.getInstance();
+        return builder.build();
     }
 
     /** The list of RDNs in big-endian order. */
@@ -117,7 +118,7 @@
      * @param profile
      *            The LDAP profile which should be used to construct DNs.
      */
-    public LDAPNameBuilder(LDAPProfile profile) {
+    private DNBuilder(LDAPProfile profile) {
         this.rdns = new LinkedList<RDN>();
         this.profile = profile;
     }
@@ -126,8 +127,8 @@
      * {@inheritDoc}
      */
     public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement(
-        InstantiableRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d,
-        String name) {
+            InstantiableRelationDefinition<? super C, ? super S> r,
+            AbstractManagedObjectDefinition<C, S> d, String name) {
         // Add the RDN sequence representing the relation.
         appendManagedObjectPathElement(r);
 
@@ -144,7 +145,7 @@
      * @param r
      *            The relation definition.
      */
-    public void appendManagedObjectPathElement(RelationDefinition<?, ?> r) {
+    private void appendManagedObjectPathElement(RelationDefinition<?, ?> r) {
         // Add the RDN sequence representing the relation.
         DN dn = DN.valueOf(profile.getRelationRDNSequence(r));
         List<RDN> rdnsOfDn = getRdnsInBigEndianOrder(dn);
@@ -171,7 +172,8 @@
      * {@inheritDoc}
      */
     public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement(
-            OptionalRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) {
+            OptionalRelationDefinition<? super C, ? super S> r,
+            AbstractManagedObjectDefinition<C, S> d) {
         // Add the RDN sequence representing the relation.
         appendManagedObjectPathElement(r);
     }
@@ -180,7 +182,8 @@
      * {@inheritDoc}
      */
     public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement(
-            SingletonRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) {
+            SingletonRelationDefinition<? super C, ? super S> r,
+            AbstractManagedObjectDefinition<C, S> d) {
         // Add the RDN sequence representing the relation.
         appendManagedObjectPathElement(r);
     }
@@ -204,7 +207,7 @@
      *
      * @return Returns the new DN instance.
      */
-    public DN getInstance() {
+    private DN build() {
         DN dn = DN.rootDN();
         for (RDN rdn : rdns) {
             dn = dn.child(rdn);
diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPConnection.java b/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPConnection.java
deleted file mode 100644
index 1f29090..0000000
--- a/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPConnection.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at legal-notices/CDDLv1_0.txt.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2008 Sun Microsystems, Inc.
- */
-package org.forgerock.opendj.config.client.ldap;
-
-import java.util.Collection;
-
-import org.forgerock.opendj.ldap.DN;
-import org.forgerock.opendj.ldap.Entry;
-import org.forgerock.opendj.ldap.ErrorResultException;
-import org.forgerock.opendj.ldap.requests.ModifyRequest;
-import org.forgerock.opendj.ldap.responses.SearchResultEntry;
-
-/**
- * An LDAP connection adaptor interface which is used to perform LDAP client
- * operations.
- * <p>
- * This interface is provided in order to make it easier to keep track of which
- * JNDI DirContext methods we require and also to facilitate implementation of
- * mock JNDI contexts for unit-testing.
- */
-public abstract class LDAPConnection {
-
-    /**
-     * Create a new LDAP connection.
-     */
-    protected LDAPConnection() {
-        // No implementation required.
-    }
-
-    /**
-     * Creates a new entry.
-     *
-     * @param entry
-     *            The entry to create.
-     * @throws ErrorResultException
-     *             If an error occurred whilst creating the entry.
-     */
-    public abstract void createEntry(Entry entry) throws ErrorResultException;
-
-    /**
-     * Deletes the named subtree.
-     *
-     * @param dn
-     *            The name of the subtree to be deleted.
-     * @throws ErrorResultException
-     *             If an error occurred whilst deleting the subtree.
-     */
-    public abstract void deleteSubtree(DN dn) throws ErrorResultException;
-
-    /**
-     * Determines whether or not the named entry exists.
-     *
-     * @param dn
-     *            The name of the entry.
-     * @return Returns <code>true</code> if the entry exists.
-     * @throws ErrorResultException
-     *             If an error occurred whilst making the determination.
-     */
-    public abstract boolean entryExists(DN dn) throws ErrorResultException;
-
-    /**
-     * Lists the children of the named entry.
-     *
-     * @param dn
-     *            The name of the entry to list.
-     * @param filter
-     *            An LDAP filter string, or <code>null</code> indicating the
-     *            default filter of <code>(objectclass=*)</code>.
-     * @return Returns the names of the children.
-     * @throws ErrorResultException
-     *             If an error occurred whilst listing the children.
-     */
-    public abstract Collection<DN> listEntries(DN dn, String filter) throws ErrorResultException;
-
-    /**
-     * Modifies an entry according to the provided modify request.
-     *
-     * @param request
-     *            The modification request to perform.
-     * @throws ErrorResultException
-     *             If an error occurred whilst applying the modifications.
-     */
-    public abstract void modifyEntry(ModifyRequest request) throws ErrorResultException;
-
-    /**
-     * Reads the attributes of the named entry.
-     *
-     * @param dn
-     *            The name of the entry to be read.
-     * @param attrIds
-     *            The list of attributes to be retrievd.
-     * @return Returns the attributes of the requested entry.
-     * @throws ErrorResultException
-     *             If an error occurred whilst reading the entry.
-     */
-    public abstract SearchResultEntry readEntry(DN dn, Collection<String> attrIds) throws ErrorResultException;
-
-    /**
-     * Closes the LDAP connection.
-     */
-    public abstract void unbind();
-}
diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPDriver.java b/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPDriver.java
index 7fa3165..26bd074 100644
--- a/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPDriver.java
+++ b/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPDriver.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2008-2009 Sun Microsystems, Inc.
- *      Portions Copyright 2013 ForgeRock, AS.
+ *      Portions Copyright 2013-2014 ForgeRock, AS.
  */
 package org.forgerock.opendj.config.client.ldap;
 
@@ -66,10 +66,17 @@
 import org.forgerock.opendj.config.client.spi.PropertySet;
 import org.forgerock.opendj.ldap.Attribute;
 import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.DN;
+import org.forgerock.opendj.ldap.EntryNotFoundException;
 import org.forgerock.opendj.ldap.ErrorResultException;
+import org.forgerock.opendj.ldap.ErrorResultIOException;
+import org.forgerock.opendj.ldap.Filter;
 import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.SearchResultReferenceIOException;
+import org.forgerock.opendj.ldap.SearchScope;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
+import org.forgerock.opendj.ldif.ConnectionEntryReader;
 
 /**
  * The LDAP management context driver implementation.
@@ -132,7 +139,7 @@
 
     private LDAPManagementContext context;
 
-    private final LDAPConnection connection;
+    private final Connection connection;
 
     // The LDAP profile which should be used to construct LDAP
     // requests and decode LDAP responses.
@@ -147,7 +154,7 @@
      * @param profile
      *            The LDAP profile.
      */
-    public LDAPDriver(LDAPConnection connection, LDAPProfile profile) {
+    LDAPDriver(Connection connection, LDAPProfile profile) {
         this.connection = connection;
         this.profile = profile;
     }
@@ -161,7 +168,7 @@
      */
     @Override
     public void close() {
-        connection.unbind();
+        connection.close();
     }
 
     /**
@@ -177,7 +184,7 @@
 
         try {
             // Read the entry associated with the managed object.
-            DN dn = LDAPNameBuilder.create(path, profile);
+            DN dn = DNBuilder.create(path, profile);
             AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition();
             ManagedObjectDefinition<? extends C, ? extends S> mod = getEntryDefinition(d, dn);
 
@@ -186,8 +193,8 @@
                 String attrId = profile.getAttributeName(mod, pd);
                 attrIds.add(attrId);
             }
-
-            SearchResultEntry searchResultEntry = connection.readEntry(dn, attrIds);
+            SearchResultEntry searchResultEntry =
+                    connection.readEntry(dn, attrIds.toArray(new String[0]));
 
             // Build the managed object's properties.
             List<PropertyException> exceptions = new LinkedList<PropertyException>();
@@ -241,7 +248,7 @@
 
         try {
             // Read the entry associated with the managed object.
-            DN dn = LDAPNameBuilder.create(path, profile);
+            DN dn = DNBuilder.create(path, profile);
             ManagedObjectDefinition<? extends C, ? extends S> objectDef = getEntryDefinition(d, dn);
 
             // Make sure we use the correct property definition, the
@@ -250,7 +257,7 @@
             propertyDef = (PropertyDefinition<P>) objectDef.getPropertyDefinition(propertyDef.getName());
 
             String attrID = profile.getAttributeName(objectDef, propertyDef);
-            SearchResultEntry resultEntry = connection.readEntry(dn, Collections.singleton(attrID));
+            SearchResultEntry resultEntry = connection.readEntry(dn, attrID);
             Attribute attribute = resultEntry.getAttribute(attrID);
 
             // Decode the values.
@@ -309,19 +316,14 @@
         }
 
         // Get the search base DN.
-        DN dn = LDAPNameBuilder.create(parent, rd, profile);
+        DN dn = DNBuilder.create(parent, rd, profile);
 
         // Retrieve only those entries which are sub-types of the
         // specified definition.
-        StringBuilder builder = new StringBuilder();
-        builder.append("(objectclass=");
-        builder.append(profile.getObjectClass(d));
-        builder.append(')');
-        String filter = builder.toString();
-
+        Filter filter = Filter.equality("objectClass", profile.getObjectClass(d));
         List<String> children = new ArrayList<String>();
         try {
-            for (DN child : connection.listEntries(dn, filter)) {
+            for (DN child : listEntries(dn, filter)) {
                 children.add(child.rdn().getFirstAVA().getAttributeValue().toString());
             }
         } catch (ErrorResultException e) {
@@ -351,19 +353,14 @@
         }
 
         // Get the search base DN.
-        DN dn = LDAPNameBuilder.create(parent, rd, profile);
+        DN dn = DNBuilder.create(parent, rd, profile);
 
         // Retrieve only those entries which are sub-types of the
         // specified definition.
-        StringBuilder builder = new StringBuilder();
-        builder.append("(objectclass=");
-        builder.append(profile.getObjectClass(d));
-        builder.append(')');
-        String filter = builder.toString();
-
+        Filter filter = Filter.equality("objectClass", profile.getObjectClass(d));
         List<String> children = new ArrayList<String>();
         try {
-            for (DN child : connection.listEntries(dn, filter)) {
+            for (DN child : listEntries(dn, filter)) {
                 children.add(child.rdn().getFirstAVA().getAttributeValue().toString());
             }
         } catch (ErrorResultException e) {
@@ -390,12 +387,12 @@
         }
 
         ManagedObjectPath<?, ?> parent = path.parent();
-        DN dn = LDAPNameBuilder.create(parent, profile);
+        DN dn = DNBuilder.create(parent, profile);
         if (!entryExists(dn)) {
             throw new ManagedObjectNotFoundException();
         }
 
-        dn = LDAPNameBuilder.create(path, profile);
+        dn = DNBuilder.create(path, profile);
         return entryExists(dn);
     }
 
@@ -406,9 +403,9 @@
     protected <C extends ConfigurationClient, S extends Configuration> void deleteManagedObject(
         ManagedObjectPath<C, S> path) throws OperationRejectedException, ErrorResultException {
         // Delete the entry and any subordinate entries.
-        DN dn = LDAPNameBuilder.create(path, profile);
+        DN dn = DNBuilder.create(path, profile);
         try {
-            connection.deleteSubtree(dn);
+            connection.deleteSubtree(dn.toString());
         } catch (ErrorResultException e) {
             if (e.getResult().getResultCode() == ResultCode.UNWILLING_TO_PERFORM) {
                 AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition();
@@ -437,7 +434,12 @@
      *             if a problem occurs.
      */
     boolean entryExists(DN dn) throws ErrorResultException {
-        return connection.entryExists(dn);
+        try {
+            connection.readEntry(dn, "1.1");
+            return true;
+        } catch (EntryNotFoundException e) {
+            return false;
+        }
     }
 
     /**
@@ -445,7 +447,7 @@
      *
      * @return Returns the LDAP connection used for interacting with the server.
      */
-    LDAPConnection getLDAPConnection() {
+    Connection getLDAPConnection() {
         return connection;
     }
 
@@ -525,7 +527,7 @@
         getEntryDefinition(AbstractManagedObjectDefinition<C, S> d, DN dn) throws ErrorResultException,
         DefinitionDecodingException {
         // @Checkstyle:on
-        SearchResultEntry searchResultEntry = connection.readEntry(dn, Collections.singleton("objectclass"));
+        SearchResultEntry searchResultEntry = connection.readEntry(dn, "objectclass");
         Attribute objectClassAttr = searchResultEntry.getAttribute("objectclass");
 
         if (objectClassAttr == null) {
@@ -554,4 +556,22 @@
 
         return d.resolveManagedObjectDefinition(resolver);
     }
+
+    private Collection<DN> listEntries(DN dn, Filter filter) throws ErrorResultException {
+        List<DN> names = new LinkedList<DN>();
+        ConnectionEntryReader reader =
+                connection.search(dn.toString(), SearchScope.SINGLE_LEVEL, filter.toString());
+        try {
+            while (reader.hasNext()) {
+                names.add(reader.readEntry().getName());
+            }
+        } catch (ErrorResultIOException e) {
+            throw e.getCause();
+        } catch (SearchResultReferenceIOException e) {
+            // Ignore.
+        } finally {
+            reader.close();
+        }
+        return names;
+    }
 }
diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPManagedObject.java b/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPManagedObject.java
index fc46e5a..397e294 100644
--- a/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPManagedObject.java
+++ b/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPManagedObject.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2007-2009 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 
 package org.forgerock.opendj.config.client.ldap;
@@ -159,10 +160,10 @@
             // be required anyway).
             DN dn;
             if (r instanceof InstantiableRelationDefinition) {
-                dn = LDAPNameBuilder.create(parent, (InstantiableRelationDefinition<?, ?>) r,
+                dn = DNBuilder.create(parent, (InstantiableRelationDefinition<?, ?>) r,
                         driver.getLDAPProfile());
             } else {
-                dn = LDAPNameBuilder.create(parent, (SetRelationDefinition<?, ?>) r,
+                dn = DNBuilder.create(parent, (SetRelationDefinition<?, ?>) r,
                         driver.getLDAPProfile());
             }
 
@@ -178,7 +179,7 @@
 
                 // Create the entry.
                 try {
-                    driver.getLDAPConnection().createEntry(entry);
+                    driver.getLDAPConnection().add(entry);
                 } catch (ErrorResultException e) {
                     if (e.getResult().getResultCode() == ResultCode.UNWILLING_TO_PERFORM) {
                         LocalizableMessage m = LocalizableMessage.raw("%s", e.getLocalizedMessage());
@@ -191,7 +192,7 @@
         }
 
         // Now add the entry representing this new managed object.
-        DN dn = LDAPNameBuilder.create(path, driver.getLDAPProfile());
+        DN dn = DNBuilder.create(path, driver.getLDAPProfile());
         Entry entry = new LinkedHashMapEntry(dn);
 
         // Create the object class attribute.
@@ -217,7 +218,7 @@
 
         try {
             // Create the entry.
-            driver.getLDAPConnection().createEntry(entry);
+            driver.getLDAPConnection().add(entry);
         } catch (ErrorResultException e) {
             if (e.getResult().getResultCode() == ResultCode.ENTRY_ALREADY_EXISTS) {
                 throw new ManagedObjectAlreadyExistsException();
@@ -254,7 +255,7 @@
             ErrorResultException {
         // Build the modify request
         ManagedObjectPath<?, ?> path = getManagedObjectPath();
-        DN dn = LDAPNameBuilder.create(path, driver.getLDAPProfile());
+        DN dn = DNBuilder.create(path, driver.getLDAPProfile());
         ModifyRequest request = Requests.newModifyRequest(dn);
         ManagedObjectDefinition<?, ?> d = getManagedObjectDefinition();
         for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
@@ -271,7 +272,7 @@
         // Perform the LDAP modification if something has changed.
         if (!request.getModifications().isEmpty()) {
             try {
-                driver.getLDAPConnection().modifyEntry(request);
+                driver.getLDAPConnection().modify(request);
             } catch (ErrorResultException e) {
                 if (e.getResult().getResultCode() == ResultCode.UNWILLING_TO_PERFORM) {
                     LocalizableMessage m = LocalizableMessage.raw("%s", e.getLocalizedMessage());
diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPManagementContext.java b/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPManagementContext.java
index 784be53..f352842 100644
--- a/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPManagementContext.java
+++ b/opendj-config/src/main/java/org/forgerock/opendj/config/client/ldap/LDAPManagementContext.java
@@ -22,6 +22,7 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 
 package org.forgerock.opendj.config.client.ldap;
@@ -29,13 +30,13 @@
 import org.forgerock.opendj.config.LDAPProfile;
 import org.forgerock.opendj.config.client.ManagementContext;
 import org.forgerock.opendj.config.client.spi.Driver;
+import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.util.Reject;
 
 /**
  * An LDAP management connection context.
  */
 public final class LDAPManagementContext extends ManagementContext {
-
     /**
      * Create a new LDAP management context using the provided LDAP connection.
      *
@@ -45,7 +46,7 @@
      *            The LDAP profile.
      * @return Returns the new management context.
      */
-    public static ManagementContext createFromContext(LDAPConnection connection, LDAPProfile profile) {
+    public static ManagementContext newManagementContext(Connection connection, LDAPProfile profile) {
         Reject.ifNull(connection, profile);
         LDAPDriver driver = new LDAPDriver(connection, profile);
         LDAPManagementContext context = new LDAPManagementContext(driver);
diff --git a/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/AggregationClientTest.java b/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/AggregationClientTest.java
index 5835fe0..749af52 100644
--- a/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/AggregationClientTest.java
+++ b/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/AggregationClientTest.java
@@ -22,9 +22,13 @@
  *
  *
  *      Copyright 2007-2008 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.config.client.ldap;
 
+import static org.fest.assertions.Assertions.assertThat;
+import static org.forgerock.opendj.ldap.Connections.newInternalConnection;
+
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -32,8 +36,8 @@
 import java.util.TreeSet;
 
 import org.forgerock.opendj.config.AdminTestCase;
-import org.forgerock.opendj.config.PropertyException;
 import org.forgerock.opendj.config.LDAPProfile;
+import org.forgerock.opendj.config.PropertyException;
 import org.forgerock.opendj.config.TestCfg;
 import org.forgerock.opendj.config.TestChildCfgClient;
 import org.forgerock.opendj.config.TestChildCfgDefn;
@@ -41,7 +45,11 @@
 import org.forgerock.opendj.config.client.ManagedObject;
 import org.forgerock.opendj.config.client.ManagedObjectDecodingException;
 import org.forgerock.opendj.config.client.ManagementContext;
+import org.forgerock.opendj.ldap.Connection;
+import org.forgerock.opendj.ldap.LinkedHashMapEntry;
+import org.forgerock.opendj.ldap.MemoryBackend;
 import org.forgerock.opendj.ldap.schema.Schema;
+import org.forgerock.opendj.ldif.LDIFEntryReader;
 import org.forgerock.opendj.server.config.client.RootCfgClient;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
@@ -54,7 +62,12 @@
 
     // Test LDIF.
     private static final String[] TEST_LDIF = new String[] {
+        // @formatter:off
         // Base entries.
+        "dn:",
+        "objectclass: top",
+        "objectclass: ds-cfg-branch",
+        "",
         "dn: cn=config",
         "objectclass: top",
         "objectclass: ds-cfg-branch",
@@ -151,6 +164,7 @@
         "ds-cfg-enabled: false",
         "ds-cfg-listen-port: 1689",
         "" };
+    // @formatter:on
 
     @BeforeClass
     public void setUp() throws Exception {
@@ -174,9 +188,10 @@
      */
     @Test
     public void testAggregationEmpty() throws Exception {
-        MockLDAPConnection c = new MockLDAPConnection();
-        c.importLDIF(TEST_LDIF);
-        ManagementContext ctx = LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
+        ManagementContext ctx =
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
         TestChildCfgClient child = parent.getTestChild("test child 1");
         assertSetEquals(child.getAggregationProperty(), new String[0]);
@@ -191,9 +206,10 @@
      */
     @Test
     public void testAggregationSingle() throws Exception {
-        MockLDAPConnection c = new MockLDAPConnection();
-        c.importLDIF(TEST_LDIF);
-        ManagementContext ctx = LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
+        ManagementContext ctx =
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
         TestChildCfgClient child = parent.getTestChild("test child 2");
 
@@ -212,12 +228,14 @@
      */
     @Test
     public void testAggregationMultiple() throws Exception {
-        MockLDAPConnection c = new MockLDAPConnection();
-        c.importLDIF(TEST_LDIF);
-        ManagementContext ctx = LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
+        ManagementContext ctx =
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
         TestChildCfgClient child = parent.getTestChild("test child 3");
-        assertSetEquals(child.getAggregationProperty(), "LDAPS Connection Handler", "LDAP Connection Handler");
+        assertSetEquals(child.getAggregationProperty(), "LDAPS Connection Handler",
+                "LDAP Connection Handler");
     }
 
     /**
@@ -229,14 +247,16 @@
      */
     @Test
     public void testAggregationBadBaseDN() throws Exception {
-        MockLDAPConnection c = new MockLDAPConnection();
-        c.importLDIF(TEST_LDIF);
-        ManagementContext ctx = LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
+        ManagementContext ctx =
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
 
         try {
             parent.getTestChild("test child 4");
-            Assert.fail("Unexpectedly retrieved test child 4" + " when it had a bad aggregation value");
+            Assert.fail("Unexpectedly retrieved test child 4"
+                    + " when it had a bad aggregation value");
         } catch (ManagedObjectDecodingException e) {
             Collection<PropertyException> causes = e.getCauses();
             Assert.assertEquals(causes.size(), 1);
@@ -261,27 +281,29 @@
      */
     @Test
     public void testCreateChildManagedObject() throws Exception {
-        CreateEntryMockLDAPConnection c = new CreateEntryMockLDAPConnection(
-                "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config");
-        c.importLDIF(TEST_LDIF);
-        c.addExpectedAttribute("cn", "test child new");
-        c.addExpectedAttribute("objectClass", "top", "ds-cfg-test-child-dummy");
-        c.addExpectedAttribute("ds-cfg-enabled", "true");
-        c.addExpectedAttribute("ds-cfg-java-class",
-                "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
-        c.addExpectedAttribute("ds-cfg-attribute-type", "description");
-        c.addExpectedAttribute("ds-cfg-rotation-policy",
-                "cn=LDAP Connection Handler,cn=connection handlers, cn=config");
-
-        ManagementContext ctx = LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
+        ManagementContext ctx =
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
-        TestChildCfgClient child = parent.createTestChild(TestChildCfgDefn.getInstance(), "test child new", null);
+        TestChildCfgClient child =
+                parent.createTestChild(TestChildCfgDefn.getInstance(), "test child new", null);
         child.setMandatoryBooleanProperty(true);
-        child.setMandatoryReadOnlyAttributeTypeProperty(Schema.getDefaultSchema().getAttributeType("description"));
+        child.setMandatoryReadOnlyAttributeTypeProperty(Schema.getDefaultSchema().getAttributeType(
+                "description"));
         child.setAggregationProperty(Collections.singleton("LDAP Connection Handler"));
         child.commit();
 
-        c.assertEntryIsCreated();
+        String dn = "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config";
+        assertThat(backend.get(dn)).isEqualTo(new LinkedHashMapEntry(
+                "dn: " + dn,
+                "cn: test child new",
+                "objectClass: top",
+                "objectClass: ds-cfg-test-child-dummy",
+                "ds-cfg-enabled: true",
+                "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+                "ds-cfg-attribute-type: description",
+                "ds-cfg-rotation-policy: cn=LDAP Connection Handler,cn=connection handlers, cn=config"));
     }
 
     /**
@@ -293,30 +315,35 @@
      */
     @Test
     public void testModifyChildManagedObject() throws Exception {
-        ModifyEntryMockLDAPConnection c = new ModifyEntryMockLDAPConnection(
-                "cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config");
-        c.importLDIF(TEST_LDIF);
-        c.addExpectedModification("ds-cfg-rotation-policy",
-            "cn=HTTP Connection Handler,cn=connection handlers, cn=config",
-            "cn=JMX Connection Handler,cn=connection handlers, cn=config");
-        ManagementContext ctx = LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
+        ManagementContext ctx =
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
         TestChildCfgClient child = parent.getTestChild("test child 2");
-        child.setAggregationProperty(Arrays.asList("JMX Connection Handler", "HTTP Connection Handler"));
+        child.setAggregationProperty(Arrays.asList("JMX Connection Handler",
+                "HTTP Connection Handler"));
         child.commit();
-        Assert.assertTrue(c.isEntryModified());
+
+        String dn = "cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config";
+        assertThat(backend.get(dn).parseAttribute("ds-cfg-rotation-policy").asSetOfString())
+                .containsOnly("cn=HTTP Connection Handler,cn=connection handlers, cn=config",
+                        "cn=JMX Connection Handler,cn=connection handlers, cn=config");
     }
 
     // Retrieve the named test parent managed object.
-    private TestParentCfgClient getTestParent(ManagementContext context, String name) throws Exception {
+    private TestParentCfgClient getTestParent(ManagementContext context, String name)
+            throws Exception {
         ManagedObject<RootCfgClient> root = context.getRootConfigurationManagedObject();
-        return root.getChild(TestCfg.getTestOneToManyParentRelationDefinition(), name).getConfiguration();
+        return root.getChild(TestCfg.getTestOneToManyParentRelationDefinition(), name)
+                .getConfiguration();
     }
 
     // Asserts that the actual set of DNs contains the expected values.
     private void assertSetEquals(SortedSet<String> actual, String... expected) {
-        SortedSet<String> values = new TreeSet<String>(TestChildCfgDefn.getInstance()
-                .getAggregationPropertyPropertyDefinition());
+        SortedSet<String> values =
+                new TreeSet<String>(TestChildCfgDefn.getInstance()
+                        .getAggregationPropertyPropertyDefinition());
         if (expected != null) {
             for (String value : expected) {
                 values.add(value);
diff --git a/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/CreateEntryMockLDAPConnection.java b/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/CreateEntryMockLDAPConnection.java
deleted file mode 100644
index 65e9e62..0000000
--- a/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/CreateEntryMockLDAPConnection.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at legal-notices/CDDLv1_0.txt.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2008 Sun Microsystems, Inc.
- */
-package org.forgerock.opendj.config.client.ldap;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.forgerock.opendj.ldap.Attribute;
-import org.forgerock.opendj.ldap.DN;
-import org.forgerock.opendj.ldap.Entry;
-import org.forgerock.opendj.ldap.ErrorResultException;
-import org.forgerock.util.Reject;
-import org.testng.Assert;
-
-/**
- * A mock LDAP connection which is used to verify that an add operation was
- * requested and that it has the correct parameters.
- */
-public final class CreateEntryMockLDAPConnection extends MockLDAPConnection {
-
-    // Detect multiple calls.
-    private boolean alreadyAdded = false;
-
-    // The expected set of attributes (attribute name -> list of
-    // values).
-    private final Map<String, List<String>> attributes = new HashMap<String, List<String>>();
-
-    // The expected DN.
-    private final DN expectedDN;
-
-    /**
-     * Create a new mock ldap connection for detecting add operations.
-     *
-     * @param dn
-     *            The expected DN of the entry to be added.
-     */
-    public CreateEntryMockLDAPConnection(String dn) {
-        this.expectedDN = DN.valueOf(dn);
-    }
-
-    /**
-     * Add an attribute which should be part of the add operation.
-     *
-     * @param expectedName
-     *            The name of the expected attribute.
-     * @param expectedValues
-     *            The attribute's expected values (never empty).
-     */
-    public void addExpectedAttribute(String expectedName, String... expectedValues) {
-        Reject.ifNull(expectedName);
-        Reject.ifNull(expectedValues);
-        Reject.ifFalse(expectedValues.length > 0, "should have at least one expected value");
-        attributes.put(expectedName, Arrays.asList(expectedValues));
-    }
-
-    /**
-     * Asserts that the entry was created.
-     */
-    public void assertEntryIsCreated() {
-        Assert.assertTrue(alreadyAdded);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void createEntry(Entry entry) throws ErrorResultException {
-        Assert.assertFalse(alreadyAdded);
-        Assert.assertEquals(entry.getName(), expectedDN);
-
-        Map<String, List<String>> expected = new HashMap<String, List<String>>(this.attributes);
-        for (Attribute attribute : entry.getAllAttributes()) {
-            String attrName = attribute.getAttributeDescription().getAttributeType().getNameOrOID();
-            List<String> values = expected.remove(attrName);
-            if (values == null) {
-                Assert.fail("Unexpected attribute " + attrName);
-            }
-            assertAttributeEquals(attribute, values);
-        }
-        if (!expected.isEmpty()) {
-            Assert.fail("Missing expected attributes: " + expected.keySet());
-        }
-
-        alreadyAdded = true;
-    }
-}
diff --git a/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/DeleteSubtreeMockLDAPConnection.java b/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/DeleteSubtreeMockLDAPConnection.java
deleted file mode 100644
index a25cb58..0000000
--- a/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/DeleteSubtreeMockLDAPConnection.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at legal-notices/CDDLv1_0.txt.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2008 Sun Microsystems, Inc.
- */
-package org.forgerock.opendj.config.client.ldap;
-
-import org.forgerock.opendj.ldap.DN;
-import org.forgerock.opendj.ldap.ErrorResultException;
-import org.testng.Assert;
-
-/**
- * A mock LDAP connection which is used to verify that a delete subtree takes
- * place.
- */
-public final class DeleteSubtreeMockLDAPConnection extends MockLDAPConnection {
-
-    // Detect multiple calls.
-    private boolean alreadyDeleted = false;
-
-    // The expected DN.
-    private final DN expectedDN;
-
-    /**
-     * Create a new mock ldap connection for detecting subtree deletes.
-     *
-     * @param dn
-     *            The expected subtree DN.
-     */
-    public DeleteSubtreeMockLDAPConnection(String dn) {
-        this.expectedDN = DN.valueOf(dn);
-    }
-
-    /**
-     * Asserts that the subtree was deleted.
-     */
-    public void assertSubtreeIsDeleted() {
-        Assert.assertTrue(alreadyDeleted);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void deleteSubtree(DN dn) throws ErrorResultException {
-        Assert.assertFalse(alreadyDeleted);
-        Assert.assertEquals(dn, expectedDN);
-        alreadyDeleted = true;
-    }
-}
diff --git a/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/LDAPClientTest.java b/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/LDAPClientTest.java
index 7cc6c8e..4e2ba01 100644
--- a/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/LDAPClientTest.java
+++ b/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/LDAPClientTest.java
@@ -22,15 +22,17 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
+ *      Portions copyright 2014 ForgeRock AS.
  */
 package org.forgerock.opendj.config.client.ldap;
 
 import static org.fest.assertions.Assertions.assertThat;
+import static org.forgerock.opendj.ldap.Connections.newInternalConnection;
 
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.SortedSet;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.forgerock.opendj.config.AdminTestCase;
 import org.forgerock.opendj.config.Constraint;
@@ -45,13 +47,20 @@
 import org.forgerock.opendj.config.client.ManagedObject;
 import org.forgerock.opendj.config.client.ManagementContext;
 import org.forgerock.opendj.config.client.OperationRejectedException;
+import org.forgerock.opendj.ldap.AbstractConnectionWrapper;
+import org.forgerock.opendj.ldap.Connection;
 import org.forgerock.opendj.ldap.DN;
 import org.forgerock.opendj.ldap.Entry;
 import org.forgerock.opendj.ldap.ErrorResultException;
+import org.forgerock.opendj.ldap.LinkedHashMapEntry;
+import org.forgerock.opendj.ldap.MemoryBackend;
 import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.requests.ModifyRequest;
+import org.forgerock.opendj.ldap.responses.Result;
 import org.forgerock.opendj.ldap.responses.SearchResultEntry;
 import org.forgerock.opendj.ldap.schema.AttributeType;
 import org.forgerock.opendj.ldap.schema.Schema;
+import org.forgerock.opendj.ldif.LDIFEntryReader;
 import org.forgerock.opendj.server.config.client.RootCfgClient;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
@@ -66,6 +75,10 @@
     // @Checkstyle:off
     private static final String[] TEST_LDIF = new String[] {
         // Base entries.
+        "dn:",
+        "objectclass: top",
+        "objectclass: ds-cfg-branch",
+        "",
         "dn: cn=config",
         "objectclass: top",
         "objectclass: ds-cfg-branch",
@@ -162,10 +175,12 @@
         // Child 4 inherits overridden defaults for both
         // optional-multi-valued-dn-property1 and
         // optional-multi-valued-dn-property2.
-        "dn: cn=test child 1,cn=test children,cn=test parent 2,cn=test parents,cn=config", "objectclass: top",
-        "objectclass: ds-cfg-test-child-dummy", "cn: test child 1", "ds-cfg-enabled: true",
+        "dn: cn=test child 1,cn=test children,cn=test parent 2,cn=test parents,cn=config",
+        "objectclass: top", "objectclass: ds-cfg-test-child-dummy", "cn: test child 1",
+        "ds-cfg-enabled: true",
         "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
         "ds-cfg-attribute-type: description", "", };
+
     // @Checkstyle:on
 
     /**
@@ -201,7 +216,8 @@
             { ResultCode.NO_SUCH_OBJECT, ManagedObjectNotFoundException.class, null },
             { ResultCode.INSUFFICIENT_ACCESS_RIGHTS, ErrorResultException.class,
                 ResultCode.INSUFFICIENT_ACCESS_RIGHTS },
-            { ResultCode.UNWILLING_TO_PERFORM, ErrorResultException.class, ResultCode.UNWILLING_TO_PERFORM } };
+            { ResultCode.UNWILLING_TO_PERFORM, ErrorResultException.class,
+                ResultCode.UNWILLING_TO_PERFORM } };
     }
 
     @BeforeClass
@@ -222,26 +238,28 @@
      */
     @Test
     public void testCreateChildManagedObject() throws Exception {
-        CreateEntryMockLDAPConnection c =
-            new CreateEntryMockLDAPConnection(
-                "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config");
-        c.importLDIF(TEST_LDIF);
-        c.addExpectedAttribute("cn", "test child new");
-        c.addExpectedAttribute("objectClass", "top", "ds-cfg-test-child-dummy");
-        c.addExpectedAttribute("ds-cfg-enabled", "true");
-        c.addExpectedAttribute("ds-cfg-java-class",
-            "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
-        c.addExpectedAttribute("ds-cfg-attribute-type", "description");
-
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
-        TestChildCfgClient child = parent.createTestChild(TestChildCfgDefn.getInstance(), "test child new", null);
+        TestChildCfgClient child =
+                parent.createTestChild(TestChildCfgDefn.getInstance(), "test child new", null);
         child.setMandatoryBooleanProperty(true);
         child.setMandatoryReadOnlyAttributeTypeProperty(getAttributeType("description"));
         child.commit();
 
-        c.assertEntryIsCreated();
+        String dn = "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config";
+        assertThat(backend.get(dn))
+                .isEqualTo(
+                        new LinkedHashMapEntry(
+                                "dn: " + dn,
+                                "cn: test child new",
+                                "objectClass: top",
+                                "objectClass: ds-cfg-test-child-dummy",
+                                "ds-cfg-enabled: true",
+                                "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+                                "ds-cfg-attribute-type: description"));
     }
 
     /**
@@ -250,18 +268,17 @@
      */
     @Test(dataProvider = "createManagedObjectExceptions")
     public void testCreateManagedObjectException(final ResultCode resultCodeOfThrownException,
-        Class<? extends Exception> expectedExceptionClass, ResultCode expectedCode) {
-        MockLDAPConnection conn = new MockLDAPConnection() {
-
+            Class<? extends Exception> expectedExceptionClass, ResultCode expectedCode)
+            throws Exception {
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = new AbstractConnectionWrapper<Connection>(newInternalConnection(backend)) {
             @Override
-            public void createEntry(Entry entry) throws ErrorResultException {
+            public Result add(Entry entry) throws ErrorResultException {
                 throw ErrorResultException.newErrorResult(resultCodeOfThrownException);
             }
-
         };
-        conn.importLDIF(TEST_LDIF);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(conn, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         try {
             TestParentCfgClient parent = createTestParent(ctx, "test parent new");
             parent.setMandatoryBooleanProperty(true);
@@ -270,7 +287,8 @@
         } catch (Exception e) {
             if (expectedExceptionClass.equals(ErrorResultException.class)) {
                 assertThat(e).isInstanceOf(ErrorResultException.class);
-                assertThat(((ErrorResultException) e).getResult().getResultCode()).isEqualTo(expectedCode);
+                assertThat(((ErrorResultException) e).getResult().getResultCode()).isEqualTo(
+                        expectedCode);
             } else {
                 assertThat(e).isInstanceOf(expectedExceptionClass);
             }
@@ -285,22 +303,26 @@
      */
     @Test
     public void testCreateTopLevelManagedObject() throws Exception {
-        CreateEntryMockLDAPConnection c =
-            new CreateEntryMockLDAPConnection("cn=test parent new,cn=test parents,cn=config");
-        c.importLDIF(TEST_LDIF);
-        c.addExpectedAttribute("cn", "test parent new");
-        c.addExpectedAttribute("objectClass", "top", "ds-cfg-test-parent-dummy");
-        c.addExpectedAttribute("ds-cfg-enabled", "true");
-        c.addExpectedAttribute("ds-cfg-java-class", "org.opends.server.extensions.SomeVirtualAttributeProvider");
-        c.addExpectedAttribute("ds-cfg-attribute-type", "description");
-
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = createTestParent(ctx, "test parent new");
         parent.setMandatoryBooleanProperty(true);
         parent.setMandatoryReadOnlyAttributeTypeProperty(getAttributeType("description"));
         parent.commit();
-        c.assertEntryIsCreated();
+
+        String dn = "cn=test parent new,cn=test parents,cn=config";
+        assertThat(backend.get(dn))
+                .isEqualTo(
+                        new LinkedHashMapEntry(
+                                "dn: " + dn,
+                                "cn: test parent new",
+                                "objectClass: top",
+                                "objectClass: ds-cfg-test-parent-dummy",
+                                "ds-cfg-enabled: true",
+                                "ds-cfg-java-class: org.opends.server.extensions.SomeVirtualAttributeProvider",
+                                "ds-cfg-attribute-type: description"));
     }
 
     /**
@@ -311,21 +333,21 @@
      */
     @Test
     public void testGetChildManagedObject() throws Exception {
-        MockLDAPConnection c = new MockLDAPConnection();
-        c.importLDIF(TEST_LDIF);
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
         TestChildCfgClient child = parent.getTestChild("test child 3");
         Assert.assertEquals(child.isMandatoryBooleanProperty(), Boolean.TRUE);
         Assert.assertEquals(child.getMandatoryClassProperty(),
-            "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+                "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
         Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
-            getAttributeType("description"));
-        assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(), "dc=default value c3v1,dc=com",
-            "dc=default value c3v2,dc=com");
-        assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(), "dc=default value c3v3,dc=com",
-            "dc=default value c3v4,dc=com");
+                getAttributeType("description"));
+        assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(),
+                "dc=default value c3v1,dc=com", "dc=default value c3v2,dc=com");
+        assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(),
+                "dc=default value c3v3,dc=com", "dc=default value c3v4,dc=com");
     }
 
     /**
@@ -336,21 +358,21 @@
      */
     @Test
     public void testGetChildManagedObjectDefault() throws Exception {
-        MockLDAPConnection c = new MockLDAPConnection();
-        c.importLDIF(TEST_LDIF);
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
         TestChildCfgClient child = parent.getTestChild("test child 1");
         Assert.assertEquals(child.isMandatoryBooleanProperty(), Boolean.TRUE);
         Assert.assertEquals(child.getMandatoryClassProperty(),
-            "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+                "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
         Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
-            getAttributeType("description"));
-        assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(), "dc=domain1,dc=com", "dc=domain2,dc=com",
-            "dc=domain3,dc=com");
-        assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(), "dc=domain1,dc=com", "dc=domain2,dc=com",
-            "dc=domain3,dc=com");
+                getAttributeType("description"));
+        assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(), "dc=domain1,dc=com",
+                "dc=domain2,dc=com", "dc=domain3,dc=com");
+        assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(), "dc=domain1,dc=com",
+                "dc=domain2,dc=com", "dc=domain3,dc=com");
         Assert.assertEquals(child.isMandatoryBooleanProperty(), Boolean.TRUE);
     }
 
@@ -365,24 +387,25 @@
      */
     @Test(dataProvider = "getManagedObjectExceptions")
     public void testGetManagedObjectException(final ResultCode resultCodeOfThrownException,
-        final Class<? extends Exception> expectedExceptionClass, final ResultCode expectedCode) {
-        MockLDAPConnection c = new MockLDAPConnection() {
-
+            final Class<? extends Exception> expectedExceptionClass, final ResultCode expectedCode)
+            throws Exception {
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = new AbstractConnectionWrapper<Connection>(newInternalConnection(backend)) {
             @Override
-            public SearchResultEntry readEntry(DN dn, Collection<String> attrIds) throws ErrorResultException {
+            public SearchResultEntry readEntry(DN name, String... attributeDescriptions)
+                    throws ErrorResultException {
                 throw ErrorResultException.newErrorResult(resultCodeOfThrownException);
             }
-
         };
-        c.importLDIF(TEST_LDIF);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         try {
             getTestParent(ctx, "test parent 2");
         } catch (Exception e) {
             if (expectedExceptionClass.equals(ErrorResultException.class)) {
                 assertThat(e).isInstanceOf(ErrorResultException.class);
-                assertThat(((ErrorResultException) e).getResult().getResultCode()).isEqualTo(expectedCode);
+                assertThat(((ErrorResultException) e).getResult().getResultCode()).isEqualTo(
+                        expectedCode);
             } else {
                 assertThat(e).isInstanceOf(expectedExceptionClass);
             }
@@ -397,18 +420,18 @@
      */
     @Test
     public void testGetTopLevelManagedObject() throws Exception {
-        MockLDAPConnection c = new MockLDAPConnection();
-        c.importLDIF(TEST_LDIF);
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 2");
         Assert.assertEquals(parent.isMandatoryBooleanProperty(), Boolean.TRUE);
         Assert.assertEquals(parent.getMandatoryClassProperty(),
-            "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+                "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
         Assert.assertEquals(parent.getMandatoryReadOnlyAttributeTypeProperty(),
-            getAttributeType("description"));
-        assertDNSetEquals(parent.getOptionalMultiValuedDNProperty(), "dc=default value p2v1,dc=com",
-            "dc=default value p2v2,dc=com");
+                getAttributeType("description"));
+        assertDNSetEquals(parent.getOptionalMultiValuedDNProperty(),
+                "dc=default value p2v1,dc=com", "dc=default value p2v2,dc=com");
     }
 
     /**
@@ -419,18 +442,18 @@
      */
     @Test
     public void testGetTopLevelManagedObjectDefault() throws Exception {
-        MockLDAPConnection c = new MockLDAPConnection();
-        c.importLDIF(TEST_LDIF);
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
         Assert.assertEquals(parent.isMandatoryBooleanProperty(), Boolean.TRUE);
         Assert.assertEquals(parent.getMandatoryClassProperty(),
-            "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+                "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
         Assert.assertEquals(parent.getMandatoryReadOnlyAttributeTypeProperty(),
-            getAttributeType("description"));
-        assertDNSetEquals(parent.getOptionalMultiValuedDNProperty(), "dc=domain1,dc=com", "dc=domain2,dc=com",
-            "dc=domain3,dc=com");
+                getAttributeType("description"));
+        assertDNSetEquals(parent.getOptionalMultiValuedDNProperty(), "dc=domain1,dc=com",
+                "dc=domain2,dc=com", "dc=domain3,dc=com");
     }
 
     /**
@@ -441,38 +464,40 @@
      */
     @Test
     public void testInheritedDefaultValues1() throws Exception {
-        CreateEntryMockLDAPConnection c =
-            new CreateEntryMockLDAPConnection(
-                "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config");
-        c.importLDIF(TEST_LDIF);
-        c.addExpectedAttribute("cn", "test child new");
-        c.addExpectedAttribute("objectClass", "top", "ds-cfg-test-child-dummy");
-        c.addExpectedAttribute("ds-cfg-enabled", "true");
-        c.addExpectedAttribute("ds-cfg-java-class",
-            "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
-        c.addExpectedAttribute("ds-cfg-attribute-type", "description");
-
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
-        TestChildCfgClient child = parent.createTestChild(TestChildCfgDefn.getInstance(), "test child new", null);
+        TestChildCfgClient child =
+                parent.createTestChild(TestChildCfgDefn.getInstance(), "test child new", null);
 
         // Check pre-commit values.
         Assert.assertEquals(child.isMandatoryBooleanProperty(), null);
         Assert.assertEquals(child.getMandatoryClassProperty(),
-            "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+                "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
         Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(), null);
-        assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(), "dc=domain1,dc=com", "dc=domain2,dc=com",
-            "dc=domain3,dc=com");
-        assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(), "dc=domain1,dc=com", "dc=domain2,dc=com",
-            "dc=domain3,dc=com");
+        assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(), "dc=domain1,dc=com",
+                "dc=domain2,dc=com", "dc=domain3,dc=com");
+        assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(), "dc=domain1,dc=com",
+                "dc=domain2,dc=com", "dc=domain3,dc=com");
 
         // Check that the default values are not committed.
         child.setMandatoryBooleanProperty(true);
         child.setMandatoryReadOnlyAttributeTypeProperty(getAttributeType("description"));
         child.commit();
 
-        c.assertEntryIsCreated();
+        String dn = "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config";
+        assertThat(backend.get(dn))
+                .isEqualTo(
+                        new LinkedHashMapEntry(
+                                "dn: " + dn,
+                                "cn: test child new",
+                                "objectClass: top",
+                                "objectClass: ds-cfg-test-child-dummy",
+                                "ds-cfg-enabled: true",
+                                "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+                                "ds-cfg-attribute-type: description"));
     }
 
     /**
@@ -483,38 +508,40 @@
      */
     @Test
     public void testInheritedDefaultValues2() throws Exception {
-        CreateEntryMockLDAPConnection c =
-            new CreateEntryMockLDAPConnection(
-                "cn=test child new,cn=test children,cn=test parent 2,cn=test parents,cn=config");
-        c.importLDIF(TEST_LDIF);
-        c.addExpectedAttribute("cn", "test child new");
-        c.addExpectedAttribute("objectClass", "top", "ds-cfg-test-child-dummy");
-        c.addExpectedAttribute("ds-cfg-enabled", "true");
-        c.addExpectedAttribute("ds-cfg-java-class",
-            "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
-        c.addExpectedAttribute("ds-cfg-attribute-type", "description");
-
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 2");
-        TestChildCfgClient child = parent.createTestChild(TestChildCfgDefn.getInstance(), "test child new", null);
+        TestChildCfgClient child =
+                parent.createTestChild(TestChildCfgDefn.getInstance(), "test child new", null);
 
         // Check pre-commit values.
         Assert.assertEquals(child.isMandatoryBooleanProperty(), null);
         Assert.assertEquals(child.getMandatoryClassProperty(),
-            "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+                "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
         Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(), null);
-        assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(), "dc=default value p2v1,dc=com",
-            "dc=default value p2v2,dc=com");
-        assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(), "dc=default value p2v1,dc=com",
-            "dc=default value p2v2,dc=com");
+        assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(),
+                "dc=default value p2v1,dc=com", "dc=default value p2v2,dc=com");
+        assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(),
+                "dc=default value p2v1,dc=com", "dc=default value p2v2,dc=com");
 
         // Check that the default values are not committed.
         child.setMandatoryBooleanProperty(true);
         child.setMandatoryReadOnlyAttributeTypeProperty(getAttributeType("description"));
         child.commit();
 
-        c.assertEntryIsCreated();
+        String dn = "cn=test child new,cn=test children,cn=test parent 2,cn=test parents,cn=config";
+        assertThat(backend.get(dn))
+                .isEqualTo(
+                        new LinkedHashMapEntry(
+                                "dn: " + dn,
+                                "cn: test child new",
+                                "objectClass: top",
+                                "objectClass: ds-cfg-test-child-dummy",
+                                "ds-cfg-enabled: true",
+                                "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+                                "ds-cfg-attribute-type: description"));
     }
 
     /**
@@ -525,10 +552,10 @@
      */
     @Test
     public void testListChildManagedObjects() throws Exception {
-        MockLDAPConnection c = new MockLDAPConnection();
-        c.importLDIF(TEST_LDIF);
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
         String[] actual = parent.listTestChildren();
         String[] expected = new String[] { "test child 1", "test child 2", "test child 3" };
@@ -543,10 +570,10 @@
      */
     @Test
     public void testListChildManagedObjectsEmpty() throws Exception {
-        MockLDAPConnection c = new MockLDAPConnection();
-        c.importLDIF(TEST_LDIF);
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 3");
         String[] actual = parent.listTestChildren();
         String[] expected = new String[] {};
@@ -561,10 +588,10 @@
      */
     @Test
     public void testListTopLevelManagedObjects() throws Exception {
-        MockLDAPConnection c = new MockLDAPConnection();
-        c.importLDIF(TEST_LDIF);
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         String[] actual = listTestParents(ctx);
         String[] expected = new String[] { "test parent 1", "test parent 2", "test parent 3" };
         Assert.assertEqualsNoOrder(actual, expected);
@@ -578,9 +605,10 @@
      */
     @Test
     public void testListTopLevelManagedObjectsEmpty() throws Exception {
-        MockLDAPConnection c = new MockLDAPConnection();
+        MemoryBackend backend = new MemoryBackend();
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         String[] actual = listTestParents(ctx);
         String[] expected = new String[] {};
         Assert.assertEqualsNoOrder(actual, expected);
@@ -594,18 +622,26 @@
      */
     @Test
     public void testModifyChildManagedObjectResetToDefault() throws Exception {
-        ModifyEntryMockLDAPConnection c =
-            new ModifyEntryMockLDAPConnection(
-                "cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config");
-        c.importLDIF(TEST_LDIF);
-        c.addExpectedModification("ds-cfg-base-dn");
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
         TestChildCfgClient child = parent.getTestChild("test child 2");
         child.setOptionalMultiValuedDNProperty1(Collections.<DN> emptySet());
         child.commit();
-        Assert.assertTrue(c.isEntryModified());
+
+        String dn = "cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config";
+        assertThat(backend.get(dn))
+                .isEqualTo(
+                        new LinkedHashMapEntry(
+                                "dn: " + dn,
+                                "cn: test child 2",
+                                "objectClass: top",
+                                "objectClass: ds-cfg-test-child-dummy",
+                                "ds-cfg-enabled: true",
+                                "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+                                "ds-cfg-attribute-type: description"));
     }
 
     /**
@@ -616,14 +652,20 @@
      */
     @Test
     public void testModifyTopLevelManagedObjectNoChanges() throws Exception {
-        ModifyEntryMockLDAPConnection c =
-            new ModifyEntryMockLDAPConnection("cn=test parent 1,cn=test parents,cn=config");
-        c.importLDIF(TEST_LDIF);
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        final AtomicBoolean isModified = new AtomicBoolean();
+        Connection c = new AbstractConnectionWrapper<Connection>(newInternalConnection(backend)) {
+            @Override
+            public Result modify(ModifyRequest request) throws ErrorResultException {
+                isModified.set(true);
+                return super.modify(request);
+            }
+        };
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
         parent.commit();
-        Assert.assertFalse(c.isEntryModified());
+        assertThat(isModified.get()).isFalse(); // Nothing to do, so no modify.
     }
 
     /**
@@ -634,19 +676,37 @@
      */
     @Test
     public void testModifyTopLevelManagedObjectWithChanges() throws Exception {
-        ModifyEntryMockLDAPConnection c =
-            new ModifyEntryMockLDAPConnection("cn=test parent 1,cn=test parents,cn=config");
-        c.importLDIF(TEST_LDIF);
-        c.addExpectedModification("ds-cfg-enabled", "false");
-        c.addExpectedModification("ds-cfg-base-dn", "dc=mod1,dc=com", "dc=mod2,dc=com");
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        final AtomicBoolean isModified = new AtomicBoolean();
+        Connection c = new AbstractConnectionWrapper<Connection>(newInternalConnection(backend)) {
+            @Override
+            public Result modify(ModifyRequest request) throws ErrorResultException {
+                isModified.set(true);
+                return super.modify(request);
+            }
+        };
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
         parent.setMandatoryBooleanProperty(false);
-        parent.setOptionalMultiValuedDNProperty(Arrays.asList(DN.valueOf("dc=mod1,dc=com"),
-            DN.valueOf("dc=mod2,dc=com")));
+        parent.setOptionalMultiValuedDNProperty(Arrays.asList(DN.valueOf("dc=mod1,dc=com"), DN
+                .valueOf("dc=mod2,dc=com")));
         parent.commit();
-        Assert.assertTrue(c.isEntryModified());
+
+        String dn = "cn=test parent 1,cn=test parents,cn=config";
+        assertThat(backend.get(dn))
+                .isEqualTo(
+                        new LinkedHashMapEntry(
+                                "dn: " + dn,
+                                "objectclass: top",
+                                "objectclass: ds-cfg-test-parent-dummy",
+                                "cn: test parent 1",
+                                "ds-cfg-enabled: false",
+                                "ds-cfg-base-dn: dc=mod1,dc=com",
+                                "ds-cfg-base-dn: dc=mod2,dc=com",
+                                "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+                                "ds-cfg-attribute-type: description"));
+        assertThat(isModified.get()).isTrue();
     }
 
     /**
@@ -657,15 +717,14 @@
      */
     @Test
     public void testRemoveChildManagedObject() throws Exception {
-        DeleteSubtreeMockLDAPConnection c =
-            new DeleteSubtreeMockLDAPConnection(
-                "cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config");
-        c.importLDIF(TEST_LDIF);
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
         parent.removeTestChild("test child 1");
-        c.assertSubtreeIsDeleted();
+        String dn = "cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config";
+        assertThat(backend.get(dn)).isNull();
     }
 
     /**
@@ -676,13 +735,13 @@
      */
     @Test
     public void testRemoveTopLevelManagedObject() throws Exception {
-        DeleteSubtreeMockLDAPConnection c =
-            new DeleteSubtreeMockLDAPConnection("cn=test parent 1,cn=test parents,cn=config");
-        c.importLDIF(TEST_LDIF);
+        MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+        Connection c = newInternalConnection(backend);
         ManagementContext ctx =
-            LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
         removeTestParent(ctx, "test parent 1");
-        c.assertSubtreeIsDeleted();
+        String dn = "cn=test parent 1,cn=test parents,cn=config";
+        assertThat(backend.get(dn)).isNull();
     }
 
     /**
@@ -696,30 +755,29 @@
     public void testAddConstraintSuccess() throws Exception {
         Constraint constraint = new MockConstraint(true, false, false);
         TestCfg.addConstraint(constraint);
-
         try {
-            CreateEntryMockLDAPConnection c =
-                new CreateEntryMockLDAPConnection(
-                    "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config");
-            c.importLDIF(TEST_LDIF);
-            c.addExpectedAttribute("cn", "test child new");
-            c.addExpectedAttribute("objectClass", "top", "ds-cfg-test-child-dummy");
-            c.addExpectedAttribute("ds-cfg-enabled", "true");
-            c.addExpectedAttribute("ds-cfg-java-class",
-                "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
-            c.addExpectedAttribute("ds-cfg-attribute-type", "description");
-
+            MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+            Connection c = newInternalConnection(backend);
             ManagementContext ctx =
-                LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                    LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
             TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
-            TestChildCfgClient child = parent.createTestChild(TestChildCfgDefn.getInstance(), "test child new", null);
+            TestChildCfgClient child =
+                    parent.createTestChild(TestChildCfgDefn.getInstance(), "test child new", null);
             child.setMandatoryBooleanProperty(true);
             child.setMandatoryReadOnlyAttributeTypeProperty(getAttributeType("description"));
             child.commit();
 
-            c.assertEntryIsCreated();
+            String dn =
+                    "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config";
+            assertThat(backend.get(dn)).isEqualTo(new LinkedHashMapEntry(
+                    "dn: " + dn,
+                    "objectclass: top",
+                    "objectclass: ds-cfg-test-child-dummy",
+                    "cn: test child new",
+                    "ds-cfg-enabled: true",
+                    "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+                    "ds-cfg-attribute-type: description"));
         } finally {
-            // Clean up.
             TestCfg.removeConstraint(constraint);
         }
     }
@@ -735,29 +793,19 @@
     public void testAddConstraintFail() throws Exception {
         Constraint constraint = new MockConstraint(false, true, true);
         TestCfg.addConstraint(constraint);
-
         try {
-            CreateEntryMockLDAPConnection conn =
-                new CreateEntryMockLDAPConnection(
-                    "cn=test child new,cn=test children,cn=test parent 1,cn=test parents,cn=config");
-            conn.importLDIF(TEST_LDIF);
-            conn.addExpectedAttribute("cn", "test child new");
-            conn.addExpectedAttribute("objectClass", "top", "ds-cfg-test-child-dummy");
-            conn.addExpectedAttribute("ds-cfg-enabled", "true");
-            conn.addExpectedAttribute("ds-cfg-java-class",
-                "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
-            conn.addExpectedAttribute("ds-cfg-attribute-type", "description");
-
+            MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+            Connection c = newInternalConnection(backend);
             ManagementContext ctx =
-                LDAPManagementContext.createFromContext(conn, LDAPProfile.getInstance());
+                    LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
             TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
-            TestChildCfgClient child = parent.createTestChild(TestChildCfgDefn.getInstance(), "test child new", null);
+            TestChildCfgClient child =
+                    parent.createTestChild(TestChildCfgDefn.getInstance(), "test child new", null);
             child.setMandatoryBooleanProperty(true);
             child.setMandatoryReadOnlyAttributeTypeProperty(getAttributeType("description"));
             child.commit();
             Assert.fail("The add constraint failed to prevent creation of the managed object");
         } finally {
-            // Clean up.
             TestCfg.removeConstraint(constraint);
         }
     }
@@ -773,19 +821,17 @@
     public void testRemoveConstraintSuccess() throws Exception {
         Constraint constraint = new MockConstraint(false, false, true);
         TestCfg.addConstraint(constraint);
-
         try {
-            DeleteSubtreeMockLDAPConnection c =
-                new DeleteSubtreeMockLDAPConnection(
-                    "cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config");
-            c.importLDIF(TEST_LDIF);
+            MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+            Connection c = newInternalConnection(backend);
             ManagementContext ctx =
-                LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                    LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
             TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
             parent.removeTestChild("test child 1");
-            c.assertSubtreeIsDeleted();
+            String dn =
+                    "cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config";
+            assertThat(backend.get(dn)).isNull();
         } finally {
-            // Clean up.
             TestCfg.removeConstraint(constraint);
         }
     }
@@ -801,19 +847,15 @@
     public void testRemoveConstraintFail() throws Exception {
         Constraint constraint = new MockConstraint(true, true, false);
         TestCfg.addConstraint(constraint);
-
         try {
-            DeleteSubtreeMockLDAPConnection c =
-                new DeleteSubtreeMockLDAPConnection(
-                    "cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config");
-            c.importLDIF(TEST_LDIF);
+            MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+            Connection c = newInternalConnection(backend);
             ManagementContext ctx =
-                LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                    LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
             TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
             parent.removeTestChild("test child 1");
             Assert.fail("The remove constraint failed to prevent removal of the managed object");
         } finally {
-            // Clean up.
             TestCfg.removeConstraint(constraint);
         }
     }
@@ -829,22 +871,27 @@
     public void testModifyConstraintSuccess() throws Exception {
         Constraint constraint = new MockConstraint(false, true, false);
         TestCfg.addConstraint(constraint);
-
         try {
-            ModifyEntryMockLDAPConnection c =
-                new ModifyEntryMockLDAPConnection(
-                    "cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config");
-            c.importLDIF(TEST_LDIF);
-            c.addExpectedModification("ds-cfg-base-dn");
+            MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+            Connection c = newInternalConnection(backend);
             ManagementContext ctx =
-                LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                    LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
             TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
             TestChildCfgClient child = parent.getTestChild("test child 2");
             child.setOptionalMultiValuedDNProperty1(Collections.<DN> emptySet());
             child.commit();
-            Assert.assertTrue(c.isEntryModified());
+
+            String dn =
+                    "cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config";
+            assertThat(backend.get(dn)).isEqualTo(new LinkedHashMapEntry(
+                    "dn: " + dn,
+                    "cn: test child 2",
+                    "objectClass: top",
+                    "objectClass: ds-cfg-test-child-dummy",
+                    "ds-cfg-enabled: true",
+                    "ds-cfg-java-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+                    "ds-cfg-attribute-type: description"));
         } finally {
-            // Clean up.
             TestCfg.removeConstraint(constraint);
         }
     }
@@ -860,22 +907,17 @@
     public void testModifyConstraintFail() throws Exception {
         Constraint constraint = new MockConstraint(true, false, true);
         TestCfg.addConstraint(constraint);
-
         try {
-            ModifyEntryMockLDAPConnection c =
-                new ModifyEntryMockLDAPConnection(
-                    "cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config");
-            c.importLDIF(TEST_LDIF);
-            c.addExpectedModification("ds-cfg-base-dn");
+            MemoryBackend backend = new MemoryBackend(new LDIFEntryReader(TEST_LDIF));
+            Connection c = newInternalConnection(backend);
             ManagementContext ctx =
-                LDAPManagementContext.createFromContext(c, LDAPProfile.getInstance());
+                    LDAPManagementContext.newManagementContext(c, LDAPProfile.getInstance());
             TestParentCfgClient parent = getTestParent(ctx, "test parent 1");
             TestChildCfgClient child = parent.getTestChild("test child 2");
             child.setOptionalMultiValuedDNProperty1(Collections.<DN> emptySet());
             child.commit();
             Assert.fail("The modify constraint failed to prevent modification of the managed object");
         } finally {
-            // Clean up.
             TestCfg.removeConstraint(constraint);
         }
     }
@@ -892,16 +934,19 @@
     }
 
     // Create the named test parent managed object.
-    private TestParentCfgClient createTestParent(ManagementContext context, String name) throws Exception {
+    private TestParentCfgClient createTestParent(ManagementContext context, String name)
+            throws Exception {
         ManagedObject<RootCfgClient> root = context.getRootConfigurationManagedObject();
-        return root.createChild(TestCfg.getTestOneToManyParentRelationDefinition(), TestParentCfgDefn.getInstance(),
-            name, null).getConfiguration();
+        return root.createChild(TestCfg.getTestOneToManyParentRelationDefinition(),
+                TestParentCfgDefn.getInstance(), name, null).getConfiguration();
     }
 
     // Retrieve the named test parent managed object.
-    private TestParentCfgClient getTestParent(ManagementContext context, String name) throws Exception {
+    private TestParentCfgClient getTestParent(ManagementContext context, String name)
+            throws Exception {
         ManagedObject<RootCfgClient> root = context.getRootConfigurationManagedObject();
-        return root.getChild(TestCfg.getTestOneToManyParentRelationDefinition(), name).getConfiguration();
+        return root.getChild(TestCfg.getTestOneToManyParentRelationDefinition(), name)
+                .getConfiguration();
     }
 
     // List test parent managed objects.
diff --git a/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/MockLDAPConnection.java b/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/MockLDAPConnection.java
deleted file mode 100644
index ab089e2..0000000
--- a/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/MockLDAPConnection.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at legal-notices/CDDLv1_0.txt.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2007-2008 Sun Microsystems, Inc.
- */
-package org.forgerock.opendj.config.client.ldap;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.forgerock.opendj.ldif.LDIF.makeEntries;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.forgerock.opendj.ldap.Attribute;
-import org.forgerock.opendj.ldap.AttributeDescription;
-import org.forgerock.opendj.ldap.AttributeParser;
-import org.forgerock.opendj.ldap.ByteString;
-import org.forgerock.opendj.ldap.DN;
-import org.forgerock.opendj.ldap.DecodeException;
-import org.forgerock.opendj.ldap.DecodeOptions;
-import org.forgerock.opendj.ldap.Entry;
-import org.forgerock.opendj.ldap.ErrorResultException;
-import org.forgerock.opendj.ldap.LinkedHashMapEntry;
-import org.forgerock.opendj.ldap.RDN;
-import org.forgerock.opendj.ldap.ResultCode;
-import org.forgerock.opendj.ldap.controls.Control;
-import org.forgerock.opendj.ldap.controls.ControlDecoder;
-import org.forgerock.opendj.ldap.requests.ModifyRequest;
-import org.forgerock.opendj.ldap.responses.SearchResultEntry;
-
-/**
- * A mock LDAP connection which fakes up search results based on some LDIF
- * content. Implementations should override the modify operations in order to
- * get provide the correct fake behavior.
- */
-public class MockLDAPConnection extends LDAPConnection {
-
-    /**
-     * A mock entry.
-     */
-    private static final class MockEntry {
-
-        private final Entry entry;
-
-        private final List<MockEntry> children;
-
-        private final DN dn;
-
-        public MockEntry(DN dn, Entry entry) {
-            this.dn = dn;
-            this.entry = entry;
-            this.children = new LinkedList<MockEntry>();
-        }
-
-        public Entry getEntry() {
-            return entry;
-        }
-
-        public List<MockEntry> getChildren() {
-            return children;
-        }
-
-        public DN getDN() {
-            return dn;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            builder.append("dn:");
-            builder.append(dn);
-            builder.append(", attributes:");
-            builder.append(entry.getAllAttributes());
-            return builder.toString();
-        }
-    }
-
-    /** All the entries. */
-    private final Map<DN, MockEntry> entries;
-
-    /** The single root entry. */
-    private final MockEntry rootEntry;
-
-    /**
-     * Create a mock connection.
-     */
-    public MockLDAPConnection() {
-        this.rootEntry = new MockEntry(DN.rootDN(), new LinkedHashMapEntry(DN.rootDN()));
-        this.entries = new HashMap<DN, MockEntry>();
-        this.entries.put(DN.rootDN(), this.rootEntry);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void createEntry(Entry entry) throws ErrorResultException {
-        throw new UnsupportedOperationException("createEntry");
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void deleteSubtree(DN dn) throws ErrorResultException {
-        throw new UnsupportedOperationException("deleteSubtree");
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean entryExists(DN dn) throws ErrorResultException {
-        return getEntry(dn) != null;
-    }
-
-    /**
-     * Imports the provided LDIF into this mock connection.
-     *
-     * @param lines
-     *            The LDIF.
-     */
-    public final void importLDIF(String... lines) {
-        try {
-            for (Entry entry : makeEntries(lines)) {
-                addEntry(entry);
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Collection<DN> listEntries(DN dn, String filter) throws ErrorResultException {
-        MockEntry entry = getEntry(dn);
-
-        if (entry == null) {
-            throw ErrorResultException.newErrorResult(ResultCode.NO_SUCH_OBJECT, "Could not find entry: " + dn);
-        } else {
-            List<DN> names = new LinkedList<DN>();
-            for (MockEntry child : entry.children) {
-                names.add(DN.valueOf(child.getDN().toString()));
-            }
-            return names;
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void modifyEntry(ModifyRequest request) throws ErrorResultException {
-        throw new UnsupportedOperationException("modifyEntry");
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public SearchResultEntry readEntry(DN dn, Collection<String> attrIds) throws ErrorResultException {
-        final MockEntry entry = getEntry(dn);
-        return new SearchResultEntry() {
-
-            public AttributeParser parseAttribute(String attributeDescription) {
-                throw new RuntimeException("not implemented");
-            }
-
-            public AttributeParser parseAttribute(AttributeDescription attributeDescription) {
-                throw new RuntimeException("not implemented");
-            }
-
-            public boolean containsControl(String oid) {
-                return false;
-            }
-
-            public SearchResultEntry setName(String dn) {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public SearchResultEntry setName(DN dn) {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public SearchResultEntry replaceAttribute(String attributeDescription, Object... values) {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public boolean replaceAttribute(Attribute attribute) {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public SearchResultEntry removeAttribute(String attributeDescription, Object... values) {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public boolean removeAttribute(AttributeDescription attributeDescription) {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public boolean removeAttribute(Attribute attribute, Collection<? super ByteString> missingValues) {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public DN getName() {
-                return entry.getDN();
-            }
-
-            @Override
-            public List<Control> getControls() {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public <C extends Control> C getControl(ControlDecoder<C> decoder, DecodeOptions options)
-                    throws DecodeException {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public int getAttributeCount() {
-                return entry.getEntry().getAttributeCount();
-            }
-
-            @Override
-            public Attribute getAttribute(String attributeDescription) {
-                return entry.getEntry().getAttribute(attributeDescription);
-            }
-
-            @Override
-            public Attribute getAttribute(AttributeDescription attributeDescription) {
-                return entry.getEntry().getAttribute(attributeDescription);
-            }
-
-            @Override
-            public Iterable<Attribute> getAllAttributes(String attributeDescription) {
-                return entry.getEntry().getAllAttributes(attributeDescription);
-            }
-
-            @Override
-            public Iterable<Attribute> getAllAttributes(AttributeDescription attributeDescription) {
-                return entry.getEntry().getAllAttributes(attributeDescription);
-            }
-
-            @Override
-            public Iterable<Attribute> getAllAttributes() {
-                return entry.getEntry().getAllAttributes();
-            }
-
-            @Override
-            public boolean containsAttribute(String attributeDescription, Object... values) {
-                return entry.getEntry().containsAttribute(attributeDescription, values);
-            }
-
-            @Override
-            public boolean containsAttribute(Attribute attribute, Collection<? super ByteString> missingValues) {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public SearchResultEntry clearAttributes() {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public SearchResultEntry addControl(Control control) {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public SearchResultEntry addAttribute(String attributeDescription, Object... values) {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public boolean addAttribute(Attribute attribute, Collection<? super ByteString> duplicateValues) {
-                throw new RuntimeException("not implemented");
-            }
-
-            @Override
-            public boolean addAttribute(Attribute attribute) {
-                throw new RuntimeException("not implemented");
-            }
-        };
-    }
-
-    /**
-     * Asserts whether the provided attribute contains exactly the set of values
-     * contained in the provided collection.
-     *
-     * @param attr
-     *            The attribute.
-     * @param values
-     *            The expected values.
-     * @throws ErrorResultException
-     *             If an unexpected problem occurred.
-     */
-    protected final void assertAttributeEquals(Attribute attr, Collection<String> values) throws ErrorResultException {
-        List<String> actualValues = new LinkedList<String>();
-        for (ByteString actualValue : attr) {
-            actualValues.add(actualValue.toString());
-        }
-
-        assertThat(actualValues).hasSize(values.size());
-        assertThat(actualValues).containsOnly(values.toArray());
-    }
-
-    /**
-     * Create a new mock entry.
-     *
-     * @param entry
-     *            The entry to be added.
-     */
-    private void addEntry(Entry entry) {
-        MockEntry parent = rootEntry;
-        DN entryDN = entry.getName();
-
-        // Create required glue entries.
-        for (int i = 0; i < entryDN.size() - 1; i++) {
-            RDN rdn = entryDN.parent(entryDN.size() - i - 1).rdn();
-            DN dn = parent.getDN().child(rdn);
-
-            if (!entries.containsKey(dn)) {
-                MockEntry glue = new MockEntry(dn, new LinkedHashMapEntry(dn));
-                parent.getChildren().add(glue);
-                entries.put(dn, glue);
-            }
-
-            parent = entries.get(dn);
-        }
-
-        // We now have the parent entry - so construct the new entry.
-        MockEntry child = new MockEntry(entryDN, LinkedHashMapEntry.deepCopyOfEntry(entry));
-        parent.getChildren().add(child);
-        entries.put(entryDN, child);
-    }
-
-    /**
-     * Gets the named entry.
-     *
-     * @param dn
-     *            The name of the entry.
-     * @return Returns the mock entry or <code>null</code> if it does not exist.
-     */
-    private MockEntry getEntry(DN dn) {
-        DN name = DN.valueOf(dn.toString());
-        return entries.get(name);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void unbind() {
-        // nothing to do
-    }
-
-}
diff --git a/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/ModifyEntryMockLDAPConnection.java b/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/ModifyEntryMockLDAPConnection.java
deleted file mode 100644
index e7c0f56..0000000
--- a/opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/ModifyEntryMockLDAPConnection.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at legal-notices/CDDLv1_0.txt.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2008 Sun Microsystems, Inc.
- */
-package org.forgerock.opendj.config.client.ldap;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.forgerock.opendj.ldap.Attribute;
-import org.forgerock.opendj.ldap.DN;
-import org.forgerock.opendj.ldap.ErrorResultException;
-import org.forgerock.opendj.ldap.Modification;
-import org.forgerock.opendj.ldap.requests.ModifyRequest;
-import org.forgerock.util.Reject;
-import org.testng.Assert;
-
-/**
- * A mock LDAP connection which is used to verify that a modify operation was
- * requested and that it has the correct parameters.
- */
-public final class ModifyEntryMockLDAPConnection extends MockLDAPConnection {
-
-    // Detect multiple calls.
-    private boolean alreadyModified = false;
-
-    private final DN expectedDN;
-
-    // The expected set of modifications (attribute name -> list of
-    // values).
-    private final Map<String, List<String>> modifications = new HashMap<String, List<String>>();
-
-    /**
-     * Create a new mock ldap connection for detecting modify operations.
-     *
-     * @param dn
-     *            The expected DN of the entry to be added.
-     */
-    public ModifyEntryMockLDAPConnection(String dn) {
-        this.expectedDN = DN.valueOf(dn);
-    }
-
-    /**
-     * Add a modification which should be part of the modify operation.
-     *
-     * @param expectedName
-     *            The name of the expected attribute.
-     * @param expectedValues
-     *            The attribute's expected new values (possibly empty if
-     *            deleted).
-     */
-    public void addExpectedModification(String expectedName, String... expectedValues) {
-        Reject.ifNull(expectedName);
-        Reject.ifNull(expectedValues);
-        modifications.put(expectedName, Arrays.asList(expectedValues));
-    }
-
-    /**
-     * Determines whether or not the entry was modified.
-     *
-     * @return Returns <code>true</code> if it was modified.
-     */
-    public boolean isEntryModified() {
-        return alreadyModified;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void modifyEntry(ModifyRequest request) throws ErrorResultException {
-        Assert.assertFalse(alreadyModified);
-        Assert.assertEquals(request.getName(), expectedDN);
-
-        Map<String, List<String>> expected = new HashMap<String, List<String>>(modifications);
-        for (Modification modification : request.getModifications()) {
-            Attribute attribute = modification.getAttribute();
-            String attrName = attribute.getAttributeDescription().getAttributeType().getNameOrOID();
-            List<String> values = expected.remove(attrName);
-            if (values == null) {
-                Assert.fail("Unexpected modification to attribute " + attrName);
-            }
-            assertAttributeEquals(attribute, values);
-        }
-        if (!expected.isEmpty()) {
-            Assert.fail("Missing modifications to: " + expected.keySet());
-        }
-
-        alreadyModified = true;
-    }
-}

--
Gitblit v1.10.0